Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MatlabGUI:在一个函数中定义按钮,在另一个函数中定义回调函数,通信_Matlab_User Interface_Matlab Figure - Fatal编程技术网

MatlabGUI:在一个函数中定义按钮,在另一个函数中定义回调函数,通信

MatlabGUI:在一个函数中定义按钮,在另一个函数中定义回调函数,通信,matlab,user-interface,matlab-figure,Matlab,User Interface,Matlab Figure,我正在尝试构建一个GUImain例程,它调用外部函数来执行更新,例如create\u ui\u buttons.m(创建我的用户界面按钮)和create\u callback\u fns.m(创建我的回调函数)。也就是说,在main之外,我想在单独的文件中定义回调函数和按钮(因为主文件越来越长),但是让main调用它们 例如,我想定义我的go按钮: handles.go_button = uicontrol('style','pushbutton', 'Units', 'normalized',

我正在尝试构建一个GUI
main
例程,它调用外部函数来执行更新,例如
create\u ui\u buttons.m
(创建我的用户界面按钮)和
create\u callback\u fns.m
(创建我的回调函数)。也就是说,在
main
之外,我想在单独的文件中定义回调函数和按钮(因为主文件越来越长),但是让
main
调用它们

例如,我想定义我的
go
按钮:

handles.go_button = uicontrol('style','pushbutton', 'Units', 'normalized', ...
'Position',[.1, .1, .1, .1], 'BackgroundColor', [0,1,0], ...
'FontWeight','bold', 'String', 'Go!', 'callback',@go_button_callback);
在名为
create\u ui\u buttons.m
的文件中,让它知道在另一个文件
create\u callback\u fns.m
中查找
@go\u button\u callback
参考。现在,它看不到这一点


作为一个更清楚的例子,从Matlab中考虑<代码> UCONTROLL >:

function myui
    % Create a figure and axes
    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    % Create pop-up menu
    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @setmap);    

   % Create push button
    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

   % Create slider
    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', @surfzlim); 

    % Add a text uicontrol to label the slider.
    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

    % Make figure visble after adding all components
    f.Visible = 'on';
    % This code uses dot notation to set properties. 
    % Dot notation runs in R2014b and later.
    % For R2014a and earlier: set(f,'Visible','on');

    function setmap(source,event)
        val = source.Value;
        maps = source.String;
        % For R2014a and earlier: 
        % val = get(source,'Value');
        % maps = get(source,'String'); 

        newmap = maps{val};
        colormap(newmap);
    end

    function surfzlim(source,event)
        val = 51 - source.Value;
        % For R2014a and earlier:
        % val = 51 - get(source,'Value');

        zlim(ax,[-val val]);
    end
end

我如何在另一个名为
create\u callback\u fns.m
的函数中定义函数
setmap
surfzlim
,以及如何在另一个名为
create\u ui\u buttons.m
的函数中定义
popup
sld
并让它们在
main
之外进行通信?

以下内容适用于所有文件都包含在同一文件夹中时的matlab测试用例


surfzlim.m:

function surfzlim(source,event,ax)
    val = 51 - source.Value;
    % For R2014a and earlier:
    % val = 51 - get(source,'Value');

    zlim(ax,[-val val]);
end
function setmap(source,event)
    val = source.Value;
    maps = source.String;
    % For R2014a and earlier: 
    % val = get(source,'Value');
    % maps = get(source,'String'); 

    newmap = maps{val};
    colormap(newmap);
end
setmap.m:

function surfzlim(source,event,ax)
    val = 51 - source.Value;
    % For R2014a and earlier:
    % val = 51 - get(source,'Value');

    zlim(ax,[-val val]);
end
function setmap(source,event)
    val = source.Value;
    maps = source.String;
    % For R2014a and earlier: 
    % val = get(source,'Value');
    % maps = get(source,'String'); 

    newmap = maps{val};
    colormap(newmap);
end
main.m

function myui
    % Create a figure and axes
    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    % Create pop-up menu
    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @setmap);    

   % Create push button
    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

   % Create slider
    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', {@surfzlim,ax}); 

    % Add a text uicontrol to label the slider.
    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

    % Make figure visble after adding all components
    f.Visible = 'on';
    % This code uses dot notation to set properties. 
    % Dot notation runs in R2014b and later.
    % For R2014a and earlier: set(f,'Visible','on');

end
function main()

    vm = MyFullViewModel();
    %Do whatever you want here
    CreateGUI(vm);
    %Do whatever you want here

end
function CreateGUI(vm)

    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @(src, evt)vm.setmap(src, evt));    

    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', @(src, evt)vm.surfzlim(src, evt, ax)); 

    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

end
function vm = MyFullViewModel()

    vm.setmap = @setmap;
    vm.surfzlim = @surfzlim;

end

function setmap(src, evt)
    val = src.Value;
    maps = src.String;
    newmap = maps{val};
    colormap(newmap);
end

function surfzlim(src, evt, ax)
    val = 51 - src.Value;
    zlim(ax,[-val val]);
end

您可以执行以下操作:

文件main.m

function myui
    % Create a figure and axes
    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    % Create pop-up menu
    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @setmap);    

   % Create push button
    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

   % Create slider
    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', {@surfzlim,ax}); 

    % Add a text uicontrol to label the slider.
    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

    % Make figure visble after adding all components
    f.Visible = 'on';
    % This code uses dot notation to set properties. 
    % Dot notation runs in R2014b and later.
    % For R2014a and earlier: set(f,'Visible','on');

end
function main()

    vm = MyFullViewModel();
    %Do whatever you want here
    CreateGUI(vm);
    %Do whatever you want here

end
function CreateGUI(vm)

    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @(src, evt)vm.setmap(src, evt));    

    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', @(src, evt)vm.surfzlim(src, evt, ax)); 

    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

end
function vm = MyFullViewModel()

    vm.setmap = @setmap;
    vm.surfzlim = @surfzlim;

end

function setmap(src, evt)
    val = src.Value;
    maps = src.String;
    newmap = maps{val};
    colormap(newmap);
end

function surfzlim(src, evt, ax)
    val = 51 - src.Value;
    zlim(ax,[-val val]);
end
文件CreateGUI.m

function myui
    % Create a figure and axes
    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    % Create pop-up menu
    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @setmap);    

   % Create push button
    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

   % Create slider
    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', {@surfzlim,ax}); 

    % Add a text uicontrol to label the slider.
    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

    % Make figure visble after adding all components
    f.Visible = 'on';
    % This code uses dot notation to set properties. 
    % Dot notation runs in R2014b and later.
    % For R2014a and earlier: set(f,'Visible','on');

end
function main()

    vm = MyFullViewModel();
    %Do whatever you want here
    CreateGUI(vm);
    %Do whatever you want here

end
function CreateGUI(vm)

    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @(src, evt)vm.setmap(src, evt));    

    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', @(src, evt)vm.surfzlim(src, evt, ax)); 

    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

end
function vm = MyFullViewModel()

    vm.setmap = @setmap;
    vm.surfzlim = @surfzlim;

end

function setmap(src, evt)
    val = src.Value;
    maps = src.String;
    newmap = maps{val};
    colormap(newmap);
end

function surfzlim(src, evt, ax)
    val = 51 - src.Value;
    zlim(ax,[-val val]);
end
文件MyFullViewModel.m

function myui
    % Create a figure and axes
    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    % Create pop-up menu
    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @setmap);    

   % Create push button
    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

   % Create slider
    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', {@surfzlim,ax}); 

    % Add a text uicontrol to label the slider.
    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

    % Make figure visble after adding all components
    f.Visible = 'on';
    % This code uses dot notation to set properties. 
    % Dot notation runs in R2014b and later.
    % For R2014a and earlier: set(f,'Visible','on');

end
function main()

    vm = MyFullViewModel();
    %Do whatever you want here
    CreateGUI(vm);
    %Do whatever you want here

end
function CreateGUI(vm)

    f = figure('Visible','off');
    ax = axes('Units','pixels');
    surf(peaks)

    popup = uicontrol('Style', 'popup',...
           'String', {'parula','jet','hsv','hot','cool','gray'},...
           'Position', [20 340 100 50],...
           'Callback', @(src, evt)vm.setmap(src, evt));    

    btn = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
        'Position', [20 20 50 20],...
        'Callback', 'cla');       

    sld = uicontrol('Style', 'slider',...
        'Min',1,'Max',50,'Value',41,...
        'Position', [400 20 120 20],...
        'Callback', @(src, evt)vm.surfzlim(src, evt, ax)); 

    txt = uicontrol('Style','text',...
        'Position',[400 45 120 20],...
        'String','Vertical Exaggeration');

end
function vm = MyFullViewModel()

    vm.setmap = @setmap;
    vm.surfzlim = @surfzlim;

end

function setmap(src, evt)
    val = src.Value;
    maps = src.String;
    newmap = maps{val};
    colormap(newmap);
end

function surfzlim(src, evt, ax)
    val = 51 - src.Value;
    zlim(ax,[-val val]);
end

您可以通过这种方式轻松地将所有回调放在同一个文件中
MyFullViewModel.m

您真的应该去上课了。正如Excaza告诉你的。但是,在使用matlab中的类时,您应该尊重以下几点:

  • 首先,只创建句柄类型类。这意味着您的类都应该从handle:MyInterface
  • 这样做将迫使您将类本身声明为类方法的第一个参数。setmap(scr,evt)将变成setmap(self,scr,evt),其中self是“我自己”
  • 然后,要在回调中定义的方法所使用的句柄将是@self.setmap
我研究了一个面向对象的掩码框架,不久我将开始研究一个接口框架。你想使用类。它不仅是通用的、抽象的和可重用的,而且Matlab还充满了可能令人痛苦的特殊行为。使用类可以帮助你一劳永逸地控制这些行为

10年前,我和你一样,使用句柄结构进行接口,以便在项目创建后与项目交互。维护起来很麻烦。类要简单得多,项目总是使用简单的getter

以下是转换为matlab类的示例代码:

classdef myuiClass < handle

    %% Private constants
    properties (Access = private)
        mFigure;
        mAxes;

        mPopup;
        mButton;
        mSlider;
        mText;
    end

    %% Public methods
    methods (Access = public)

        %% Constructor
        function self = myuiClass()
            self.mFigure = figure('Visible', 'off');
            self.mAxes   = axes('Units', 'pixels');
            surf(peaks);

            self.createInterface();

            self.mFigure.Visible = 'on';
        end
    end

    %% Protected methods
    methods (Access = protected)

        %% setmap
        function setmap(~, source, ~)
            val = source.Value;
            maps = source.String;

            newmap = maps{val};
            colormap(newmap);
        end

        %% surfzlim
        function surfzlim(self, source, ~)
            val = 51 - source.Value;

            zlim(self.mAxes, [-val val]);
        end

    end

    %% Private methods
    methods (Access = private)

        %% createInterface
        function createInterface( self )

            self.mPopup = uicontrol('Style', 'popup',...
                'String', {'parula','jet','hsv','hot','cool','gray'},...
                'Position', [20 340 100 50],...
                'Callback', @self.setmap);

            self.mButton = uicontrol('Style', 'pushbutton', 'String', 'Clear',...
                'Position', [20 20 50 20],...
                'Callback', 'cla');

            self.mSlider = uicontrol('Style', 'slider',...
                'Min',1,'Max',50,'Value',41,...
                'Position', [400 20 120 20],...
                'Callback', @self.surfzlim);

            self.mText = uicontrol('Style','text',...
                'Position',[400 45 120 20],...
                'String','Vertical Exaggeration');            
        end
    end
end
classdef myuiClass
您不能从外部引用本地或嵌套函数,因此要走这条路,您需要为每个函数提供一个
*.m
文件,或者研究在GUI中使用面向对象的方法。对于回调,使用继承或直接调用的with将是一种简单的方法。@excaza:谢谢!您怎么办是指每个函数都有一个
*.m
文件吗?我已经创建了
setmap.m
surfzlim.m
,但是我如何调用它们/引用那些带有函数句柄/回调的函数呢?我一直在使用
@setmap
…如果你有
setmap.m
,那么你的回调被定义为
@setmap
。好吧,也许我对abo感到困惑但是我如何告诉
setmap
的回调需要
source
event
输入?这些输入是什么?我如何将它们从主GUI传递到回调?请参阅:谢谢!假设
surfzlim
是一个大函数,我可以将其提取到另一个文件并在方法定义中引用该文件吗?是的,但我可以如果SurfZLIM是一个大的函数,考虑在小函数中解耦它。如果SurfZLIM有几个职责,则创建一个类或一个层次结构。