在MATLAB GUI中如何跳出for循环

6

我在MATLAB的开放功能中有一个for循环,我正在尝试使用回调按钮来中断循环。我是MATLAB的新手。这是我的代码:

%In the opening function of the GUI
handles.stop_now = 0;
for i=1:inf
   if handles.stop_now==1
      break;
   end
end


% Executes on button press 
function pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to end_segmenting_button (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
handles.stop_now=1;
guidata(hObject, handles);

由于某种原因,尽管使用句柄定义变量,但循环在按下按钮时并未中断。 有人知道发生了什么吗? 谢谢。

2个回答

8
你遇到的问题是,传递给 打开函数handles值结构在调用打开函数时被固定。你从未检索由pushbutton_Callback更新的新结构。您可以通过在循环中调用GUIDATA来检索新结构。以下是我建议您尝试编写循环的方式:
handles.stop_now = 0;  %# Create stop_now in the handles structure
guidata(hObject,handles);  %# Update the GUI data
while ~(handles.stop_now)
  drawnow;  %# Give the button callback a chance to interrupt the opening function
  handles = guidata(hObject);  %# Get the newest GUI data
end

更大的GUI设计问题...

根据您在评论中提供的附加描述,我认为有一种更好的设计方法。不要让用户重复输入ROIs并按下停止按钮的连续循环,而是可以取消循环和停止按钮,并在GUI中添加一个“添加ROI”按钮。这样,用户只需在想要添加另一个ROI时按下按钮即可。您可以首先使用以下初始化替换开放函数中的for循环:

handles.nROIs = 0;  %# Current number of ROIs
handles.H = {};  %# ROI handles
handles.P = {};  %# ROI masks
guidata(hObject,handles);  %# Update the GUI data

接下来,您可以使用以下内容替换按钮的回调函数:

function pushbutton_Callback(hObject,eventdata,handles)
%# Callback for "Add new ROI" button
  nROIs = handles.nROIs+1;  %# Increment the number of ROIs
  hROI = imfreehand;  %# Add a new free-hand ROI
  position = wait(hROI);  %# Wait until the user is done with the ROI
  handles.nROIs = nROIs;  %# Update the number of ROIs
  handles.H{nROIs} = hROI;  %# Save the ROI handle
  handles.P{nROIs} = hROI.createMask;  %# Save the ROI mask
  guidata(hObject,handles);  %# Update the GUI data
end

我明白了,所以关键是在循环内调用 GUIDATA。现在我遇到另一个问题。我正在使用for循环和imagefreehand从图像中捕获ROI。for i=1:inf drawnow
handles = guidata(hObject);if handles.stop_now==1 break; end handles.H{i} = imfreehand; handles.P{i}= handles.H{i}.createMask;end问题是,一旦我调用pushbutton,我只能在选择一个额外的自由手区域后退出循环。我该如何解决这个问题?
- Nick
1
在你的实现中,break 会退出循环并将控制流传递到 imfreehand()。因此,你应该使用 return 而不是 break - Mikhail Poda
感谢所有的帮助。问题是,我正在使用该程序来分割生物图像。在一张图片中,我可能需要分割多达20个不同的对象,所以我不想让用户每次需要添加额外的ROI时都要按一个按钮。我只是想知道是否有任何方法可以解决我目前设置中遇到的问题。 - Nick

4
我看到这里有两个潜在的问题。
第一:变量handles不是一个引用,设置handles.stop_now=1;会在控制流程退出pushbutton_Callback后丢失。使用guidata其他方法来存储和检索数据。 第二个问题:使用函数drawnow()。请参见Yair Altman的这篇文章以获得良好的解释。
总结:MATLAB图形界面是Java Swing,并且IO操作(如按按钮)发生在一个特殊的线程 - 事件调度线程(EDT)上。调用drawnow();刷新事件队列并更新图形窗口。

我正在使用guidata,并且已经检查过handles.stop_now是否在pushbutton_Callback之外更新(即,我知道它没有丢失),但是由于某种原因,在for循环中它无法被识别... - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接