当前位置: 动力学知识库 > 问答 > 编程问答 >

user interface - Matlab gui: callback containing imrect gets stuck if clicking multiple times

问题描述:

I am writing a GUI in Matlab where a user can process images. Once an image is opened, the user can specify a ROI by a "Crop" button (callback code below). After cropping, further analysis can be done.

Everything works fine except when the user accidentally clicks on the "crop button" without selecting a rectangle. Then, clicking again on the button, I can draw the rectangle but not confirm my selection anymore. I think the "previous" callback is still stuck at the wait(h) function which should enable the user to redefine the rectangle (according to http://www.mathworks.ch/ch/help/images/ref/imrect.html)

I also tried to include a restart button and to reopen the GUI, but then it is still not possible to select a ROI in the image.

% --- Executes on button press in cropButton.

function cropButton_Callback(hObject, eventdata, handles)

% Read image

I = handles.I;

hold(handles.axes1,'on');

% Let user choose rectangle to crop

h = imrect(handles.axes1);

position = round(wait(h));

% Crop image

I = imcrop(I,position);

hold(handles.axes1,'off');

% Show cropped image

imshow(I, 'Parent', handles.axes1);

handles.I = I;

guidata(hObject, handles);

% --- Executes on button press in resetButton.

function resetButton_Callback(hObject, eventdata, handles)

clear all;

close all;

clc;

MyGUI; % restart GUI

How can I solve this problem? Any ideas would be appreciated.

网友答案:

You can disable the button on click and re-enable it at the end of the callback:

% --- Executes on button press in cropButton.
function cropButton_Callback(hObject, eventdata, handles)
set(handles.cropButton,'enable','off');

% Read image
I = handles.I;
hold(handles.axes1,'on');

% Let user choose rectangle to crop
h = imrect(handles.axes1);
position = round(wait(h));
% Crop image
I = imcrop(I,position);

hold(handles.axes1,'off');

% Show cropped image
imshow(I, 'Parent', handles.axes1);

handles.I = I;
guidata(hObject, handles);
set(handles.cropButton,'enable','on');

Much less complicated.

网友答案:

Instead of a "reset" button, you could use findobj to look for a rectangle (i.e. a hggroup object). If no rectangle is found (i.e. you have pressed the crop button without selecting a rectangle), call 'return' and do it again.

Eg:

hFindROi = findobj(gca,'Type','hggroup');

if isempty(hFindRoi) % i.e. no rectangle found

msgbox('Please select a rectangle before pressing the Crop button');
return
end

Another option would be to use some kind of flags to know whether some callback has been executed. You can store those flags in the handles structure of the GUI so that they are accessible from any callback.

For example, let's say you declare

handles.SelectRectangleFlag = true;
guidata(hObject,handles);

after selecting a rectangle. Then when you press the crop button, you can check the value of the flag, and if it's false (don't forget to initialize it at the beginning), then return and don't do anything.

Eg. in cropButton_Callback

if handles.SelectRectangleFlag == false
msgbox('Please select a rectangle before pressing the Crop button');
    return
end

Hope that helps! I hope it was clear enough. If not please ask :)

分享给朋友:
您可能感兴趣的文章:
随机阅读: