我已經想通了,之所以需要按下停止按鈕後繪製一個矩形外,我已經找到了幾個可能的解決方案來解決這個問題。
簡而言之,問題是...... 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)
希望這會有所幫助。
謝謝。我今天剛看到你的解決方案。我也實現了暫停功能。非常感謝您發佈您的答案和所有的努力 –
不客氣!這是一個非常有趣的問題,讓我學習新東西。 –