MATLAB app designer 菜鸟进阶学习(四) - 挽年_Sonny

时间:2024-03-10 18:17:40

MATLAB app designer 菜鸟进阶学习(四)

4.在 App 设计工具中创建多窗口 App

  多窗口 App 由两个或多个共享数据的 App 构成。App 之间共享数据的方式取决于设计。

  一种常见的设计包含两个 App:一个主 App 和一个对话框。通常,主 App 中有一个按钮用于打开该对话框。当用户关闭对话框时,对话框将用户的选择发送给主窗口,主窗口执行计算并更新 UI。

  这两个 App 在不同的时间通过不同的方式共享信息:

  • 当对话框打开时,主 App 将使用输入参数调用对话框 App,将信息传递给对话框。

  • 当用户点击对话框中的确定按钮时,对话框将使用输入参数调用主 App 中的公共函数,将信息返回给主 App。

4.1 设计概述

  要创建多窗口的 App,必须创建两个单独的 App(主 App 和对话框 App)。然后执行以下高级任务,每个任务都包含多个步骤。

  • 将信息发送给对话框 - 在接受输入参数的对话框 App 中编写一个 StartupFcn 回调。必须有一个输入参数是主 App 对象。然后在主 App 中使用输入参数调用对话框 App。

  • 将信息返回给主 App - 在主 App 中编写一个公共函数,以根据用户在对话框中的选择来更新 UI。由于它是公共函数,因此对话框可以调用它并将值传递给它。

  • 关闭窗口时的管理任务 - 在两个 App 中各编写一个 CloseRequest 回调,在窗口关闭时执行维护任务。

 4.2 实例先行

  此 App 由一个主绘图 App 构成,主绘图 App 中有一个按钮,用于在对话框中选择选项。选项按钮使用输入参数调用对话框 App。在对话框中,确定按钮的回调通过调用主 App 中的公共函数,将用户的选择发送回主 App。

将信息发送给对话框

  执行以下步骤,将值从主 App 传递给对话框 App。

 

 设计内容:

  新建一个主app,按照下图安放控件

   代码:

classdef MainAppExample < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure       matlab.ui.Figure
        UIAxes         matlab.ui.control.UIAxes
        OptionsButton  matlab.ui.control.Button
    end


    properties (Access = private)
        DialogApp                   % Dialog box app
        CurrentSize = 35;           % Surface sample size
        CurrentColormap = \'Parula\'; % Colormap
    end

    methods (Access = public)
    
        function updateplot(app, sz, c)
            % Store inputs as properties
            app.CurrentSize = sz;
            app.CurrentColormap = c;
            
            % Update plot 
            Z = peaks(sz);
            surf(app.UIAxes,Z);
            colormap(app.UIAxes,c);
            
            % Re-enable the Plot Options button
            app.OptionsButton.Enable = \'on\';
        end
        
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            % Call updateplot to display an initial plot
            updateplot(app, app.CurrentSize, app.CurrentColormap)
        end

        % Button pushed function: OptionsButton
        function OptionsButtonPushed(app, event)
            % Disable Plot Options button while dialog is open
            app.OptionsButton.Enable = \'off\';
            
            % Open the options dialog and pass inputs
            app.DialogApp = DialogAppExample(app, app.CurrentSize, app.CurrentColormap);
        end

        % Close request function: UIFigure
        function MainAppCloseRequest(app, event)
            % Delete both apps
            delete(app.DialogApp)
            delete(app)
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure(\'Visible\', \'off\');
            app.UIFigure.Position = [100 100 449 370];
            app.UIFigure.Name = \'Display Plot\';
            app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @MainAppCloseRequest, true);

            % Create UIAxes
            app.UIAxes = uiaxes(app.UIFigure);
            app.UIAxes.Position = [68 68 341 267];

            % Create OptionsButton
            app.OptionsButton = uibutton(app.UIFigure, \'push\');
            app.OptionsButton.ButtonPushedFcn = createCallbackFcn(app, @OptionsButtonPushed, true);
            app.OptionsButton.Position = [189 23 100 22];
            app.OptionsButton.Text = \'Options\';

            % Show the figure after all components are created
            app.UIFigure.Visible = \'on\';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = MainAppExample

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end

  再建第二个对话框app,控件安放如下图

 

 

 代码:

classdef DialogAppExample < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                  matlab.ui.Figure
        SampleSizeEditFieldLabel  matlab.ui.control.Label
        EditField                 matlab.ui.control.NumericEditField
        ColormapDropDownLabel     matlab.ui.control.Label
        DropDown                  matlab.ui.control.DropDown
        Button                    matlab.ui.control.Button
    end


    properties (Access = private)
        CallingApp   % Main app object
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function StartupFcn(app, mainapp, sz, c)
            % Store main app in property for CloseRequestFcn to use
            app.CallingApp = mainapp;
            
            % Update UI with input values
            app.EditField.Value = sz;
            app.DropDown.Value = c;
        end

        % Button pushed function: Button
        function ButtonPushed(app, event)
            % Call main app\'s public function
            updateplot(app.CallingApp, app.EditField.Value, app.DropDown.Value);
            
            % Delete the dialog box
            delete(app)
        end

        % Close request function: UIFigure
        function DialogAppCloseRequest(app, event)
            % Enable the Plot Opions button in main app
            app.CallingApp.OptionsButton.Enable = \'on\';
            
            % Delete the dialog box 
            delete(app)
            
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure(\'Visible\', \'off\');
            app.UIFigure.Position = [600 100 392 248];
            app.UIFigure.Name = \'Options\';
            app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @DialogAppCloseRequest, true);

            % Create SampleSizeEditFieldLabel
            app.SampleSizeEditFieldLabel = uilabel(app.UIFigure);
            app.SampleSizeEditFieldLabel.HorizontalAlignment = \'right\';
            app.SampleSizeEditFieldLabel.VerticalAlignment = \'top\';
            app.SampleSizeEditFieldLabel.Position = [102 160 74 15];
            app.SampleSizeEditFieldLabel.Text = \'Sample Size\';

            % Create EditField
            app.EditField = uieditfield(app.UIFigure, \'numeric\');
            app.EditField.Limits = [2 1000];
            app.EditField.Position = [191 156 100 22];
            app.EditField.Value = 35;

            % Create ColormapDropDownLabel
            app.ColormapDropDownLabel = uilabel(app.UIFigure);
            app.ColormapDropDownLabel.HorizontalAlignment = \'right\';
            app.ColormapDropDownLabel.VerticalAlignment = \'top\';
            app.ColormapDropDownLabel.Position = [117 106 59 15];
            app.ColormapDropDownLabel.Text = \'Colormap\';

            % Create DropDown
            app.DropDown = uidropdown(app.UIFigure);
            app.DropDown.Items = {\'Parula\', \'Jet\', \'Winter\', \'Cool\'};
            app.DropDown.Position = [191 102 100 22];
            app.DropDown.Value = \'Parula\';

            % Create Button
            app.Button = uibutton(app.UIFigure, \'push\');
            app.Button.ButtonPushedFcn = createCallbackFcn(app, @ButtonPushed, true);
            app.Button.Position = [116 43 174 22];
            app.Button.Text = \'OK\';

            % Show the figure after all components are created
            app.UIFigure.Visible = \'on\';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = DialogAppExample(varargin)

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            % Execute the startup function
            runStartupFcn(app, @(app)StartupFcn(app, varargin{:}))

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end

4.3  重点内容

4.3.1 将信息发送给对话框

执行以下步骤,将值从主 App 传递给对话框 App

(1)在对话框 App 中,为 StartupFcn 回调定义输入参数,然后将代码添加到回调中。

  打开对话框 App 的代码视图。在编辑器选项卡上,点击 App 输入参数。在 App 输入参数对话框中,为您的输入参数输入以逗号分隔的变量名称列表。将其中一个输入指定为存储主 App 对象的变量。然后点击确定。

  将代码添加到 StartupFcn 回调中,以存储 mainapp 的值。

 

 

 

 

function StartupFcn(app,mainapp,sz,c)
    % Store main app object
    app.CallingApp = mainapp;

    % Process sz and c inputs
    ...
end

2.从主 App 的回调中调用对话框 App。打开主 App 的代码视图,然后为选项按钮添加一个回调函数。此回调禁用选项按钮,以防止用户打开多个对话框。接下来,它获取要传递给对话框的值,然后使用输入参数和输出参数调用对话框 App。输出参数是对话框 App 对象。

function OptionsButtonPushed(app,event) 
    % Disable Plot Options button while dialog is open
    app.OptionsButton.Enable = \'off\';

    % Get szvalue and cvalue
    % ....
    
    % Call dialog box with input values
    app.DialogApp = DialogAppExample(app,szvalue,cvalue);
end

3.在主 App 中定义一个属性,以存储对话框 App。在主 App 保持打开的情况下,创建一个名为 DialogApp 的私有属性。在编辑器选项卡上选择属性 > 私有属性。然后,将 properties 模块中的属性名称更改为 DialogApp

properties (Access = private)
       DialogApp % Dialog box app
end

4.3.2 将信息返回给主App

执行以下步骤,将用户的选择返回给主 App

1.在主 App 中创建一个公共函数,以更新 UI。打开主 App 的代码视图,然后在编辑器选项卡上选择函数 > 公共函数。

将默认函数名称更改为所需的名称,即你所希望从对话框传递给主 App 的每个选项添加输入参数。app 参数必须是第一个,因此请在此参数后指定其他参数。然后将代码添加到处理输入并更新主 App 的函数中。

function updateplot(app,sz,c) 
    % Process sz and c 
    ...
end

2.在对话框 App 中创建一个属性,以存储主 App。打开对话框 App 的代码视图,然后创建一个名为 CallingApp 的私有属性。在编辑器选项卡上选择属性> 私有属性。然后,将 properties 模块中的属性名称更改为 CallingApp

properties (Access = private)
        CallingApp % Main app object
end

3.从对话框 App 的回调中调用公共函数。在对话框 App 保持打开的情况下,为确定按钮添加一个回调函数。

在此回调中,将 CallingApp 属性和用户的选择传递给公共函数。然后调用 delete 函数以关闭对话框。

function ButtonPushed(app,event)
   % Call main app\'s public function
   updateplot(app.CallingApp,app.EditField.Value,app.DropDown.Value);

   % Delete the dialog box  
   delete(app)                  
end

4.3.3 关闭窗口时的管理任务

  两个 App 都必须在用户关闭它们时执行某些任务。在对话框关闭之前,它必须重新启用主 App 中的选项按钮。在主 App 关闭之前,它必须确保对话框 App 也关闭。

1.打开对话框 App 的代码视图,右键点击组件浏览器中的 app.UIFigure 对象,然后选择回调 > 添加 CloseRequestFcn 回调。然后添加重新启用主 App 中的按钮并关闭对话框 App 的代码

function DialogAppCloseRequest(app,event)
   % Enable the Plot Options button in main app
   app.CallingApp.OptionsButton.Enable = \'on\';
            
   % Delete the dialog box 
   delete(app)             
end

2.打开主 App 的代码视图,右键点击组件浏览器中的 app.UIFigure 对象,然后选择回调 > 添加 CloseRequestFcn 回调。然后添加删除这两个 App 的代码。

function MainAppCloseRequest(app,event)
   % Delete both apps
   delete(app.DialogApp)
   delete(app)              
end

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Dialog