只需在执行 MATLAB GUI 期间进入调试器即可修复在正常执行期间持续存在的错误

Simply entering the debugger during execution of MATLAB GUI fixes error that persists during normal execution

我在 MATLAB 中使用编程 GUI,它使用多个图形 windows。当我按下图 A 中的按钮 'Redraw' 时,会出现一个新图形(图 B),其中绘制了一些数据。我希望焦点立即切换回图 A,因为我在 window 中使用了许多热键 (WindowKeyPressFcn) 来更新图 B 中的绘图。

这里有两个问题:

1) 按钮 'Redraw' 回调的最后一行确实将焦点切换回图 A,但前提是图 B 已经存在。也就是说,第一次创建图 B 时,它仍然处于焦点中。如果我随后使用图 A 更新图 B 中的绘图,焦点将正确切换回图 A。我想不出为什么它在第一次重绘和所有后续调用期间表现不同。

2) 更大的问题是,如果我在代码中的任意位置设置断点然后继续执行,焦点会根据需要切换回图A。那么,为什么进入调试器而不做任何其他事情就能解决问题呢?如果在调试器中一切正常,我如何找到问题?

提前致谢!

编辑: 令我惊讶的是,我能够通过编写我的第一个程序化 GUI 来重现此 "Heisenbug"。这应该是我的问题的最简单的例子。要查看它的实际效果,只需 运行 下面的代码并单击按钮。出于某种原因,当第一次创建 Window 2 时,焦点不会按预期切换回 Window 1。它适用于所有后续按钮按下。尝试关闭 Window 2 并再次按下按钮,错误将继续出现。

如原文post所述,在代码中设置断点即可解决问题。在第27行设置断点,然后继续执行,Window1就会成为焦点。

这里发生了什么?

 function heisenbug

%% Main problem:
% After clicking the push button, I want the focus to
% always switch back to Window 1 (the one containing the button).
% However, this does not work when Window 2 is first created.
%%

%% Create and then hide the GUI as it is being constructed
f = figure('Visible','off','name','Window 1','units','normalized','Position',[0.1 0.1 0.5 0.5]);

%% Initialize handles structure
handles = guihandles(f);
handles.window2 = [];
guidata(f,handles)

%% Make a button
hbutton = uicontrol('Style','pushbutton','String','Push me','units','normalized',...
    'Position',[0.1 0.1 0.8 0.8],...
    'Callback',@button_Callback);

%% Make the GUI visible
f.Visible = 'on';

%% Button callback
    function button_Callback(source,eventData)
        handles = guidata(gcbo);
        % If Window 2 already exists, plot a circle, then switch focus back to Window 1.
        if ~isempty(handles.window2) && ishandle(handles.window2)
            figure(handles.window2);
            plot(1,1,'bo')
            figure(f);
        % Otherwise, create Window 2 and do the same thing.
        else
            handles.window2 = figure('Name','Window 2','units','normalized','position',[0.4 0.1 0.5 0.5]);
            plot(1,1,'bo')
            figure(f)
        end
        guidata(source,handles)
    end

end

Adam 很快在 MathWorks 网站上回答了我的 post(谢谢!):http://se.mathworks.com/matlabcentral/answers/299607-simply-entering-the-debugger-during-execution-of-matlab-gui-fixes-error-that-persists-during-normal

我需要在创建 Window 2 之后插入一个 pause(0.05),然后再尝试使用 figure(f) 将焦点切换回来。否则,当它完成绘图时,焦点将被偷回 Window 2。