如何在MATLAB中的函数内创建一个GUI? [英] How to create a GUI inside a function in MATLAB?

查看:134
本文介绍了如何在MATLAB中的函数内创建一个GUI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从函数内部编写一个GUI?



问题是所有GUI函数的回调都在全局工作空间中进行了评估。但函数有自己的工作空间,不能访问全局工作空间中的变量。是否有可能使GUI功能使用该功能的工作区?例如:

 函数myvar = myfunc()
myvar = true;
h_fig = figure;

%创建一个无用的按钮
uicontrol(h_fig,'style','pushbutton',...
'string','clickme',...
'callback','myvar = false');

%等待按钮被按下
,而myvar
暂停(0.2);
结束

关闭(h_fig);

disp('永远不会显示');
end

此事件循环将无限期运行,因为回调不会修改 myvar 在函数中。相反,它会在全局工作区中创建一个新的 myvar

解决方案

有许多方法可以构建GUI ,例如使用App Designer,GUIDE或以编程方式创建它(我将在下面说明此选项)。了解也很重要为GUI组件定义回调函数的不同方法可用于在组件之间共享数据的选项



我偏爱的方法是使用嵌套函数作为回调函数。下面是一个简单的GUI例子:

$ p $ 函数make_useless_button()

%初始化变量和图形:
iCounter = 0;
hFigure = figure;
hButton = uicontrol('Style','pushbutton','Parent',hFigure,...
'String','Blah','Callback',@increment);

%嵌套回调函数:
函数增量(〜,〜)
iCounter = iCounter + 1;
disp(iCounter);
end

end

运行此代码时,因为嵌套函数 increment 可以访问 make_useless_button ,因此可以修改 iCounter 。请注意,按钮回调被设置为函数句柄 increment ,并且该函数默认接受两个参数:触发回调的UI组件的图形句柄和相关事件数据的结构。我们忽略它们与 ,因为我们没有使用它们。



将上述方法扩展到您的特定问题,您可以添加循环和更改回调函数,使其将标志变量设置为false:

$ p $函数make_stop_button()

初始化变量和图形:
keepLo​​oping = true;
hFigure = figure;
hButton = uicontrol('Style','pushbutton','Parent',hFigure,...
'String','Stop','Callback',@stop_fcn);

%保持循环,直到按下按钮:
while keepLo​​oping,
drawnow;
结束

%删除图:
delete(hFigure);

%嵌套回调函数:
函数stop_fcn(〜,〜)
keepLo​​oping = false;
结束

结束

drawnow 在这里需要赋予按钮回调有机会中断循环内的程序流,并修改 keepLo​​oping 的值。


Is it possible to write a GUI from inside a function?

The problem is that the callback of all GUI-functions are evaluated in the global workspace. But functions have their own workspace and can not access variables in the global workspace. Is it possible to make the GUI-functions use the workspace of the function? For example:

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

This event-loop will run indefinitely, since the callback will not modify myvar in the function. Instead it will create a new myvar in the global workspace.

解决方案

There are a number of ways to build a GUI, such as using the App Designer, GUIDE, or creating it programmatically (I'll illustrate this option below). It's also important to be aware of the different ways to define callback functions for your GUI components and the options available for sharing data between components.

The approach I'm partial to is using nested functions as callbacks. Here's a simple GUI as an example:

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

When you run this code, the counter displayed should increment by one every time you press the button, because the nested function increment has access to the workspace of make_useless_button and thus can modify iCounter. Note that the button callback is set to a function handle to increment, and that this function must accept two arguments by default: a graphics handle for the UI component that triggered the callback, and a structure of associated event data. We ignore them with the ~ in this case since we aren't using them.

Extending the above approach to your particular problem, you could add your loop and change the callback so it sets your flag variable to 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

The drawnow is needed here to give the button callback a chance to interrupt the program flow within the loop and modify the value of keepLooping.

这篇关于如何在MATLAB中的函数内创建一个GUI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆