我已经想通了,之所以需要按下停止按钮后绘制一个矩形外,我已经找到了几个可能的解决方案来解决这个问题。
简而言之,问题是...... MatLab比你快。
在更多的话,这是发生什么事,一步一步:
让我们假设你想画只有一个矩形,然后按下“停止”按钮来停止绘制。
while
循环开头的if
语句中的条件未验证(尚未按下按钮),因此循环继续。
if get(ButtonHandle,'userdata')
break ;
end
的imrect
语句然后执行
h = imrect;
它开始矩形绘制过程:可以绘制矩形,移动它,调整它的大小ANS等。
一旦你开始画下一个语句执行
pos = uint32(wait(h));
的wait
功能块MATLAB命令行,直到矩形您double-click
从绘图模式
如果您已经退出绘制一个有效的矩形,下一个语句绘制实际的矩形,将矩形的位置存储在“数组”中,并删除handle
至imrect
对象
if ~isempty(pos)
rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k');
for i=1:4
counter=counter+1;
array (counter) = pos(i);
end
delete(h);
end
此时您决定“停止”添加矩形并按下“停止”按钮。
以下是MatLab比您快的点。
当您移动muose的光标到达按钮时,脚本的执行会继续,并且while
循环的新迭代开始。
又是第一个语句执行
if get(ButtonHandle,'userdata')
,如果你没有这么快(你不能),以达到“停止”按钮,并在新的迭代开始前推,在if
条件未验证,因此 的imrect
顺序执行
h = imrect;
pos = uint32(wait(h));
为你的意图是提请另一个矩形。
这是“seeem”在按下“Stop”按钮后需要实际停止脚本的“附加”矩形。
虽然MATLAB命令行由wait
功能受阻,callback
听者不是,所以可以推pusshbutton和userdata
的值被设置为1
尽管如此,拉拔处理已被激活。
因此,您需要绘制“附加”矩形,双击退出wait
,以便可以开始“while循环的迭代器”。
此时,最终将验证if
条件,并且break
语句会停止执行while
循环。
这是发生了什么事。
我发现了两种可能的解决方案:第一种可以让您的脚本“几乎”保持原样,第二种意味着歪曲GUI
概念。
第一种解决方案可以让您...... MatLab更快。
如果你调用wait
(例如pause(3)
)后插入pause
声明,你将有3秒内达到一个新的迭代开始前,按下“停止”。
这使得车callback
设置userdata
设置为1,使if
条件在while
循环的开始被验证停止脚本的executin无需作出任何附加矩形。
第二种解决方案在于改变GUI
的行为:
您可以删除while
循环和改变pushbutton callback
因此,它需要调用imrect
的关心和绘制矩形(在实际应用中,你必须移动 代码在pushbutton cllback
的while
循环内
这样的GUI的行为将是:要添加一个矩形内的任何时候,你推pushbutton
在此之后,您可以找到两种解决方案的脚本。
通知,我做了一些额外的修改你的额外的代码,以使其运行:
我已经删除了uint32 cast
:具有中轴线不是一个图片,默认axes
限值[ 0 1], 如果转换pos
到unsigned 32-bit integer
,POS将成为[0 1 0 0]
而且我已经删除了for
循环存储pos
在array
:它实际上没有必要。
溶液#1
% Commented since in the code excerpt is not used
% im_des=rgb2gray('pdb_img_1.jpg');
ButtonHandle = uicontrol('style','push','String', 'STOP',...
'callback','set(gcbo,''userdata'',1,''string'',''DONE!'')', ...
'userdata',0) ;
% Added initialization of "array" and array_32" arrays
% array_32: stores the rectangle pos as uint32
% array: stores the rectangle pos as double (added to make the script
% running without an image on the axes)
array=[];
array_32=[];
%
while(1)
if get(ButtonHandle,'userdata')
break ;
end
% Commented type cast (default axix limit are [0 1] therefore
% pos=[ 0 1 0 0]
h = imrect;
% pos = uint32(wait(h));
pos = wait(h);
% added message display and "pause" statement to allow pressing "Stop"
% button before drawing next rectangle
disp('Press STOP within 3 sec. to stop')
pause(3)
if ~isempty(pos)
rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k')
% if needed the edge color of each rectangle can be different
% rectangle('Position', pos, 'LineWidth',1,'EdgeColor',[rand(3,1)])
%
% Commented "for loop" to store rectangle pos since it is not needed
% for i=1:4
% counter=counter+1
% "array" is built as (N x 4) matrix, each row contains the "pos" of
% a rectangle (remove ";" to store it as a (1 x N) array
array = [array ; pos]
array_32 = [array_32 ; uint32(pos)]
% end
delete(h)
end
end
溶液#2 主脚本
array=[];
axes
ButtonHandle = uicontrol('style','push','String', 'Add rect',...
'callback','tmp=add_rect;array=[array;tmp]');
按钮回调
function pos=add_rect()
h = imrect;
pos = wait(h);
rectangle('Position', pos, 'LineWidth',1, 'EdgeColor','k')
delete(h)
希望这会有所帮助。
谢谢。我今天刚看到你的解决方案。我也实现了暂停功能。非常感谢您发布您的答案和所有的努力 –
不客气!这是一个非常有趣的问题,让我学习新东西。 –