是否可以从函数内部编写GUI?
问题是所有GUI函数的回调都在全局工作空间中进行评估.但是函数具有自己的工作空间,无法访问全局工作空间中的变量.是否可以使GUI函数使用函数的工作空间?例如:
function myvar = myfunc() myvar = true; h_fig = figure; % create a useless button uicontrol( h_fig, 'style', 'pushbutton', ... 'string', 'clickme', ... 'callback', 'myvar = false' ); % wait for the button to be pressed while myvar pause( 0.2 ); end close( h_fig ); disp( 'this will never be displayed' ); end
此事件循环将无限期运行,因为回调不会myvar
在函数中修改.相反,它将myvar
在全局工作区中创建一个新的.
有许多方法可以构建GUI,例如使用App Designer,GUIDE或以编程方式创建GUI(我将在下面说明此选项).了解为GUI组件定义回调函数的不同方法以及可用于在组件之间共享数据的选项也很重要.
我偏爱的方法是使用嵌套函数作为回调.这是一个简单的GUI作为示例:
function make_useless_button() % Initialize variables and graphics: iCounter = 0; hFigure = figure; hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 'String', 'Blah', 'Callback', @increment); % Nested callback function: function increment(~, ~) iCounter = iCounter+1; disp(iCounter); end end
当您运行此代码时,每次按下按钮时显示的计数器应递增1,因为嵌套函数increment
可以访问工作区,make_useless_button
因此可以修改iCounter
.请注意,按钮回调被设置为一个函数句柄来increment
,那这个函数必须接受两个参数默认为:图形处理其触发回调,以及相关的事件数据结构中的UI组件.我们在这种情况下忽略它们,~
因为我们没有使用它们.
将上述方法扩展到您的特定问题,您可以添加循环并更改回调,以便将flag变量设置为false:
function make_stop_button() % Initialize variables and graphics: keepLooping = true; hFigure = figure; hButton = uicontrol('Style', 'pushbutton', 'Parent', hFigure, ... 'String', 'Stop', 'Callback', @stop_fcn); % Keep looping until the button is pressed: while keepLooping, drawnow; end % Delete the figure: delete(hFigure); % Nested callback function: function stop_fcn(~, ~) keepLooping = false; end end
在drawnow
这里需要给按键回调几率打断循环内的程序流和修改的值keepLooping
.