matlab gui:在一个函数中定义按钮,在另一个函数中定义回调函数,进行通信

时间:2017-10-30 15:18:31

标签: matlab user-interface matlab-figure

我正在尝试构建一个GUI main例程,该例程调用外部函数来执行更新,例如create_ui_buttons.m(创建我的用户界面按钮)和create_callback_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_ui_buttons.m的文件中,让其知道在另一个文件create_callback_fns.m中查找@go_button_callback引用。现在,它没有看到那个参考。

或许是一个更明确的例子,请考虑来自matlab的uicontrol documentation

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

如何在另一个名为setmap的函数中定义函数surfzlimcreate_callback_fns.m,如何在另一个名为{popup的函数中定义sldcreate_ui_buttons.mmain之外的{1}}并让他们都进行沟通?

3 个答案:

答案 0 :(得分:1)

你真的应该去上课。正如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

答案 1 :(得分:0)

当所有文件都包含在同一文件夹中时,以下适用于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

setmap.m:

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

答案 2 :(得分:0)

您可以执行以下操作:

档案main.m

function main()

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

end

文件CreateGUI.m

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

文件MyFullViewModel.m

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