MATLAB 之 APP DESIGNER 学习(三)

学习(一)学习(二)

三、示例学习

3.响应用户选择

 

  有了学习(一)和学习(二)的基础,我直接开门见山,分析其中的核心部分。

(1)界面

  相比之前两个的界面,这个界面要高级很多了。首先是整个界面分为两个面板,左面板和右面板。

左面板部分从上到下依次是控件:

  标签Data Selection

  三个小面板,第一个面板上的title 为location,放着下拉框; 

  第二个面板的title是Gender,放着两个复选框Male 和 female;

  第三个面板的title是smoker,放着两个复选框yes和no

右面板部分上方有图窗工具菜单栏,在第一个子项plot中,从上到下依次是

  仪器工具中的开关

  绘图区

  button组

  滑块

菜单第二个子项data中,放的是

  表

  如下图。

    对控件进行相应的命名、属性的修改。

(2)代码

  先把源代码贴过来,代码分析见后。

classdef PatientsDisplay < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        PatientsDisplayUIFigure    matlab.ui.Figure
        GridLayout                 matlab.ui.container.GridLayout
        LeftPanel                  matlab.ui.container.Panel
        Panel2                     matlab.ui.container.Panel
        FemaleCheckBox             matlab.ui.control.CheckBox
        MaleCheckBox               matlab.ui.control.CheckBox
        Panel2_2                   matlab.ui.container.Panel
        NoCheckBox                 matlab.ui.control.CheckBox
        YesCheckBox                matlab.ui.control.CheckBox
        Panel2_4                   matlab.ui.container.Panel
        HospitalNameDropDownLabel  matlab.ui.control.Label
        HospitalNameDropDown       matlab.ui.control.DropDown
        DataSelectionLabel         matlab.ui.control.Label
        RightPanel                 matlab.ui.container.Panel
        TabGroup                   matlab.ui.container.TabGroup
        PlotTab                    matlab.ui.container.Tab
        UIAxes                     matlab.ui.control.UIAxes
        BinWidthSliderLabel        matlab.ui.control.Label
        BinWidthSlider             matlab.ui.control.Slider
        ButtonGroup                matlab.ui.container.ButtonGroup
        ScatterButton              matlab.ui.control.RadioButton
        HistogramButton            matlab.ui.control.RadioButton
        BloodPressureSwitchLabel   matlab.ui.control.Label
        BloodPressureSwitch        matlab.ui.control.Switch
        DataTab                    matlab.ui.container.Tab
        UITable                    matlab.ui.control.Table
    end

    % Properties that correspond to apps with auto-reflow
    properties (Access = private)
        onePanelWidth = 576;
    end

    % The app displays the data by using the scatter plot, histogram, and table.
    % It makes use of tabs to separate the ploting options output from the table display of the data.
    % There are several graphical elements used such as checkboxes, slider, switch, dropdown, and radiobutton group.
    % The data used in the app is shiped with the product.
    
    properties (Access = private)
        % Declare properties of the PatientsDisplay class.
        Data
        SelectedGenders
        SelectedColors
        BinWidth
        Histogram = gobjects(0)
        displayedIndices
    end
    
    methods (Access = private)
        
        function NBins = numhistbins(app,data)
            % Utility function to compute the number of histogram bins
            binwidth = app.BinWidth;
            range2plot =  floor(min(data)):binwidth:ceil(max(data));
            NBins = size(range2plot,2);
        end
        
        function annotateScatterPlot(app)
            % Update X and Y Labels
            app.UIAxes.XLabel.String = 'Weight';
            app.UIAxes.YLabel.String = app.BloodPressureSwitch.Value;
            % Dont show the histogram slider
            app.BinWidthSliderLabel.Visible = 'off';
            app.BinWidthSlider.Visible = 'off';
        end
        
        function annotateHistogram(app)
           
            % Update X and Y Labels
            app.UIAxes.XLabel.String = app.BloodPressureSwitch.Value;
            app.UIAxes.YLabel.String = '# of Patients';
            
            % Show histogram slider
            app.BinWidthSliderLabel.Visible = 'on';
            app.BinWidthSlider.Visible = 'on';
        end
        
        function filterData(app)
            % Utility function to filter the data according to the controls
            
            % Initially assume that all data will be displayed and then, subsequently, filter the data
            % based on the controls
            tempIndices = ones([size(app.Data,1),1]);
            
            % Append a column to tempIndices to indicate data that satisfies the smoker control
            if app.NoCheckBox.Value && ~app.YesCheckBox.Value
                tempIndices = [tempIndices, app.Data.Smoker == 0];
            elseif app.YesCheckBox.Value && ~app.NoCheckBox.Value
                tempIndices = [tempIndices, app.Data.Smoker == 1];
            elseif  ~app.YesCheckBox.Value && ~app.NoCheckBox.Value
                tempIndices = [tempIndices, zeros([size(app.Data,1),1])];
            end
            
            % Append a column to tempIndices to indicate data that satisfies the gender control
            if app.MaleCheckBox.Value && ~app.FemaleCheckBox.Value
                tempIndices = [tempIndices, app.Data.Gender == "Male"];
            elseif app.FemaleCheckBox.Value && ~app.MaleCheckBox.Value
                tempIndices = [tempIndices, app.Data.Gender == "Female"];
            elseif  ~app.FemaleCheckBox.Value && ~app.MaleCheckBox.Value
                tempIndices = [tempIndices, zeros([size(app.Data,1),1])];
            end
            
            % Append a column to tempIndices to indicate data that satisfies the location control
            if app.HospitalNameDropDown.Value ~= "All"
                tempIndices = [tempIndices, app.Data.Location == string(app.HospitalNameDropDown.Value)];
            end
            
            % Determine which data points satisfy all requirements
            app.displayedIndices = (sum(tempIndices,2)/size(tempIndices,2) == 1);
        end
    end

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

        % Code that executes after component creation
        function startupFcn(app)
            % Load the data.
            load('patients.mat','LastName','Gender','Smoker','Age','Height','Weight','Diastolic','Systolic','Location');
            
            % Store the data in a table and display it in one of the App's tabs.
            app.Data = table(LastName,Gender,Smoker,Age,Height,Weight,Diastolic,Systolic,Location);
            app.UITable.Data = app.Data;
            app.BinWidth = app.BinWidthSlider.Value;
            
            % Update the axes with the corresponding data.
            updateSelectedGenders(app)
            refreshplot(app)
        end

        % Changes arrangement of the app based on UIFigure width
        function updateAppLayout(app, event)
            currentFigureWidth = app.PatientsDisplayUIFigure.Position(3);
            if(currentFigureWidth <= app.onePanelWidth)
                % Change to a 2x1 grid
                app.GridLayout.RowHeight = {400, 400};
                app.GridLayout.ColumnWidth = {'1x'};
                app.RightPanel.Layout.Row = 2;
                app.RightPanel.Layout.Column = 1;
            else
                % Change to a 1x2 grid
                app.GridLayout.RowHeight = {'1x'};
                app.GridLayout.ColumnWidth = {282, '1x'};
                app.RightPanel.Layout.Row = 1;
                app.RightPanel.Layout.Column = 2;
            end
        end

        % Value changing function: BinWidthSlider
        function SliderValueChanging(app, event)
            % Update the histogram as the slider value for bindwidth changes.
            app.BinWidth = event.Value;
            for ii=1:length(app.Histogram)
                app.Histogram(ii).NumBins = numhistbins(app,app.Histogram(ii).Data);
            end
        end

        % Callback function: BinWidthSlider, BloodPressureSwitch, 
        % ButtonGroup, UITable
        function refreshplot(app, event)
            Genders = app.SelectedGenders;
            Colors = app.SelectedColors;
            
            % Start with a fresh plot
            cla(app.UIAxes)
            hold(app.UIAxes,'on')
            app.Histogram = gobjects(0);
            
            % Select relevant segment of data
            xdata = app.Data.Weight;
            ydata = app.Data.(app.BloodPressureSwitch.Value);
            
            % Filter the data according to the controls
            filterData(app);
            
            % Create either a scatter plot or histogram, based on selection
            switch app.ButtonGroup.SelectedObject.Text
                
                case 'Scatter'
                    % Build a scatter plot for each selected gender
                    for ii = 1:length(Genders)
                        selectedpatients = ((app.Data.Gender == Genders(ii)) & (app.displayedIndices));
                        scatter(app.UIAxes,xdata((selectedpatients)),ydata(selectedpatients),Colors{ii});
                    end
                    annotateScatterPlot(app)
                    
                case 'Histogram'
                    % Build a histogram for each selected gender
                    for ii = 1:length(Genders)
                        selectedpatients = ((app.Data.Gender == Genders(ii)) & (app.displayedIndices));
                        NBins = numhistbins(app,ydata(selectedpatients));
                        h = histogram(app.UIAxes,ydata(selectedpatients),NBins,'BinLimits',[floor(min(ydata)) ceil(max(ydata))]);
                        h.EdgeColor = Colors{ii};
                        h.FaceColor = Colors{ii};
                        app.Histogram = [app.Histogram h];
                    end
                    annotateHistogram(app)
                    
            end
            
            % Update the table to show only the data that satisfies the controls
            app.UITable.Data = app.Data(app.displayedIndices,:);
            drawnow;
        end

        % Value changed function: FemaleCheckBox, 
        % HospitalNameDropDown, MaleCheckBox, NoCheckBox, 
        % YesCheckBox
        function updateSelectedGenders(app, event)
            % List which genders and colors to use
            Genders = [];
            Colors = [];
            Smoker = [];
            
            if app.MaleCheckBox.Value
                Genders = "Male";
                Colors = "blue";
            end
            if app.FemaleCheckBox.Value
                Genders = [Genders "Female"];
                Colors = [Colors "red"];
            end
            if app.YesCheckBox.Value
                Smoker = "Yes";
            end
            if app.NoCheckBox.Value
                Smoker = [Smoker "No"];
            end
            
            if isempty(Genders) || isempty(Smoker)
                % Disable the switches and buttons if they were on
                app.BloodPressureSwitch.Enable = 'off';
                app.ScatterButton.Enable = 'off';
                app.HistogramButton.Enable = 'off';
                app.BinWidthSliderLabel.Enable = 'off';
                app.BinWidthSlider.Enable = 'off';
            else
                % Enable the switches and buttons if they were off
                app.BloodPressureSwitch.Enable = 'on';
                app.ScatterButton.Enable = 'on';
                app.HistogramButton.Enable = 'on';
                app.BinWidthSliderLabel.Enable = 'on';
                app.BinWidthSlider.Enable = 'on';
            end
            app.SelectedGenders = Genders;
            app.SelectedColors = Colors;
            
            refreshplot(app)
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create PatientsDisplayUIFigure and hide until all components are created
            app.PatientsDisplayUIFigure = uifigure('Visible', 'off');
            app.PatientsDisplayUIFigure.AutoResizeChildren = 'off';
            app.PatientsDisplayUIFigure.Position = [100 100 703 400];
            app.PatientsDisplayUIFigure.Name = 'Patients Display';
            app.PatientsDisplayUIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);

            % Create GridLayout
            app.GridLayout = uigridlayout(app.PatientsDisplayUIFigure);
            app.GridLayout.ColumnWidth = {282, '1x'};
            app.GridLayout.RowHeight = {'1x'};
            app.GridLayout.ColumnSpacing = 0;
            app.GridLayout.RowSpacing = 0;
            app.GridLayout.Padding = [0 0 0 0];
            app.GridLayout.Scrollable = 'on';

            % Create LeftPanel
            app.LeftPanel = uipanel(app.GridLayout);
            app.LeftPanel.Layout.Row = 1;
            app.LeftPanel.Layout.Column = 1;
            app.LeftPanel.Scrollable = 'on';

            % Create Panel2
            app.Panel2 = uipanel(app.LeftPanel);
            app.Panel2.AutoResizeChildren = 'off';
            app.Panel2.Title = 'Gender';
            app.Panel2.Position = [9 123 269 97];

            % Create FemaleCheckBox
            app.FemaleCheckBox = uicheckbox(app.Panel2);
            app.FemaleCheckBox.ValueChangedFcn = createCallbackFcn(app, @updateSelectedGenders, true);
            app.FemaleCheckBox.Text = 'Female';
            app.FemaleCheckBox.Position = [12 14 60 16];

            % Create MaleCheckBox
            app.MaleCheckBox = uicheckbox(app.Panel2);
            app.MaleCheckBox.ValueChangedFcn = createCallbackFcn(app, @updateSelectedGenders, true);
            app.MaleCheckBox.Text = 'Male';
            app.MaleCheckBox.Position = [12 44 46 16];
            app.MaleCheckBox.Value = true;

            % Create Panel2_2
            app.Panel2_2 = uipanel(app.LeftPanel);
            app.Panel2_2.AutoResizeChildren = 'off';
            app.Panel2_2.Title = 'Smoker';
            app.Panel2_2.Position = [9 7 268 97];

            % Create NoCheckBox
            app.NoCheckBox = uicheckbox(app.Panel2_2);
            app.NoCheckBox.ValueChangedFcn = createCallbackFcn(app, @updateSelectedGenders, true);
            app.NoCheckBox.Text = 'No';
            app.NoCheckBox.Position = [12 12 60 22];
            app.NoCheckBox.Value = true;

            % Create YesCheckBox
            app.YesCheckBox = uicheckbox(app.Panel2_2);
            app.YesCheckBox.ValueChangedFcn = createCallbackFcn(app, @updateSelectedGenders, true);
            app.YesCheckBox.Text = 'Yes';
            app.YesCheckBox.Position = [12 42 46 22];
            app.YesCheckBox.Value = true;

            % Create Panel2_4
            app.Panel2_4 = uipanel(app.LeftPanel);
            app.Panel2_4.AutoResizeChildren = 'off';
            app.Panel2_4.Title = 'Location';
            app.Panel2_4.Position = [9 242 269 97];

            % Create HospitalNameDropDownLabel
            app.HospitalNameDropDownLabel = uilabel(app.Panel2_4);
            app.HospitalNameDropDownLabel.HorizontalAlignment = 'right';
            app.HospitalNameDropDownLabel.Position = [8 27 84 22];
            app.HospitalNameDropDownLabel.Text = 'Hospital Name';

            % Create HospitalNameDropDown
            app.HospitalNameDropDown = uidropdown(app.Panel2_4);
            app.HospitalNameDropDown.Items = {'County General Hospital', 'St. Mary''s Medical Center', 'VA Hospital', 'All'};
            app.HospitalNameDropDown.ValueChangedFcn = createCallbackFcn(app, @updateSelectedGenders, true);
            app.HospitalNameDropDown.Position = [107 27 153 22];
            app.HospitalNameDropDown.Value = 'All';

            % Create DataSelectionLabel
            app.DataSelectionLabel = uilabel(app.LeftPanel);
            app.DataSelectionLabel.HorizontalAlignment = 'center';
            app.DataSelectionLabel.FontSize = 15;
            app.DataSelectionLabel.FontWeight = 'bold';
            app.DataSelectionLabel.Position = [9 356 267 22];
            app.DataSelectionLabel.Text = 'Data Selection';

            % Create RightPanel
            app.RightPanel = uipanel(app.GridLayout);
            app.RightPanel.Layout.Row = 1;
            app.RightPanel.Layout.Column = 2;
            app.RightPanel.Scrollable = 'on';

            % Create TabGroup
            app.TabGroup = uitabgroup(app.RightPanel);
            app.TabGroup.Position = [7 6 408 387];

            % Create PlotTab
            app.PlotTab = uitab(app.TabGroup);
            app.PlotTab.Title = 'Plot';

            % Create UIAxes
            app.UIAxes = uiaxes(app.PlotTab);
            xlabel(app.UIAxes, 'Weight')
            ylabel(app.UIAxes, 'Diastolic')
            app.UIAxes.GridAlpha = 0.15;
            app.UIAxes.MinorGridAlpha = 0.25;
            app.UIAxes.Box = 'on';
            app.UIAxes.Position = [19 89 376 215];

            % Create BinWidthSliderLabel
            app.BinWidthSliderLabel = uilabel(app.PlotTab);
            app.BinWidthSliderLabel.HorizontalAlignment = 'center';
            app.BinWidthSliderLabel.VerticalAlignment = 'top';
            app.BinWidthSliderLabel.Position = [241 63 76 15];
            app.BinWidthSliderLabel.Text = 'Bin Width';

            % Create BinWidthSlider
            app.BinWidthSlider = uislider(app.PlotTab);
            app.BinWidthSlider.Limits = [1 11];
            app.BinWidthSlider.MajorTicks = [1 2 3 4 5 6 7 8 9 10 11];
            app.BinWidthSlider.ValueChangedFcn = createCallbackFcn(app, @refreshplot, true);
            app.BinWidthSlider.ValueChangingFcn = createCallbackFcn(app, @SliderValueChanging, true);
            app.BinWidthSlider.MinorTicks = [];
            app.BinWidthSlider.Position = [183 46 192 3];
            app.BinWidthSlider.Value = 5;

            % Create ButtonGroup
            app.ButtonGroup = uibuttongroup(app.PlotTab);
            app.ButtonGroup.AutoResizeChildren = 'off';
            app.ButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @refreshplot, true);
            app.ButtonGroup.Title = 'Plotting Options';
            app.ButtonGroup.Position = [18 4 148 79];

            % Create ScatterButton
            app.ScatterButton = uiradiobutton(app.ButtonGroup);
            app.ScatterButton.Text = 'Scatter';
            app.ScatterButton.Position = [11 34 103 15];
            app.ScatterButton.Value = true;

            % Create HistogramButton
            app.HistogramButton = uiradiobutton(app.ButtonGroup);
            app.HistogramButton.Text = 'Histogram';
            app.HistogramButton.Position = [11 12 103 15];

            % Create BloodPressureSwitchLabel
            app.BloodPressureSwitchLabel = uilabel(app.PlotTab);
            app.BloodPressureSwitchLabel.HorizontalAlignment = 'center';
            app.BloodPressureSwitchLabel.VerticalAlignment = 'top';
            app.BloodPressureSwitchLabel.Position = [132 340 151 15];
            app.BloodPressureSwitchLabel.Text = 'Blood Pressure';

            % Create BloodPressureSwitch
            app.BloodPressureSwitch = uiswitch(app.PlotTab, 'slider');
            app.BloodPressureSwitch.Items = {'Systolic', 'Diastolic'};
            app.BloodPressureSwitch.ValueChangedFcn = createCallbackFcn(app, @refreshplot, true);
            app.BloodPressureSwitch.Position = [190 309 34 15];
            app.BloodPressureSwitch.Value = 'Systolic';

            % Create DataTab
            app.DataTab = uitab(app.TabGroup);
            app.DataTab.Title = 'Data';

            % Create UITable
            app.UITable = uitable(app.DataTab);
            app.UITable.ColumnName = {'Last Name'; 'Gender'; 'Smoker'; 'Age'; 'Height'; 'Weight'; 'Diastolic'; 'Systolic'; 'Location'};
            app.UITable.RowName = {};
            app.UITable.ColumnSortable = true;
            app.UITable.RowStriping = 'off';
            app.UITable.CellSelectionCallback = createCallbackFcn(app, @refreshplot, true);
            app.UITable.Position = [1 1 407 358];

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

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = PatientsDisplay

            % Create UIFigure and components
            createComponents(app)

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

            % 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.PatientsDisplayUIFigure)
        end
    end
end

(3)知识点分析

  略去之前已经分析过的部分,在Properties部分,我们看到,除了前面提及的控件属性、窗口宽度外,增加了很大一部分内容,这部分是关于数据载入、直方图/散点图/表格等内容的辅助程序。

 properties (Access = private)
        % Declare properties of the PatientsDisplay class.
        Data
        SelectedGenders
        SelectedColors
        BinWidth
        Histogram = gobjects(0)
        displayedIndices
    end

  这个app类叫做PatientsDisplay,这部分声明这个类里私有成分,包括Data、SelectedGenders、SelectedColors、BinWidth、Histogram = gobjects(0)、displayedIndices。

 function NBins = numhistbins(app,data)
            % Utility function to compute the number of histogram bins
            binwidth = app.BinWidth;
            range2plot =  floor(min(data)):binwidth:ceil(max(data));
            NBins = size(range2plot,2);
        end

  这个函数是用于计算 直方图 每一条柱的数据: 将滑块读取的BinWidth的值赋值给binwidth,range2plot是最小值到最大值的范围的向量,NBins是直方图每一个条形的宽度。

  floor()这个函数是向下取整。

function annotateScatterPlot(app)
            % Update X and Y Labels
            app.UIAxes.XLabel.String = 'Weight';
            app.UIAxes.YLabel.String = app.BloodPressureSwitch.Value;
            % Dont show the histogram slider
            app.BinWidthSliderLabel.Visible = 'off';
            app.BinWidthSlider.Visible = 'off';
        end

  绘制散点图时,坐标区的x的名称为Weight,Y坐标的名称根据控件开关的状态更新;滑块及其标签隐藏。

function annotateHistogram(app)
           
            % Update X and Y Labels
            app.UIAxes.XLabel.String = app.BloodPressureSwitch.Value;
            app.UIAxes.YLabel.String = '# of Patients';
            
            % Show histogram slider
            app.BinWidthSliderLabel.Visible = 'on';
            app.BinWidthSlider.Visible = 'on';
        end

  绘制直方图时,坐标区的x的名称根据控件状态变化,Y坐标的名称为# of Patients;滑块及其标签显示。

  重点: 控制某个控件是否可见,采用:app.XXX.Visible='on'或者 'off';坐标区的X、Y坐标名称也可以根据控件的状态进行更改,方式为app.XXX.XLabel.String = 'Weight'

  读取开关控件的值采用的程序语句为:XXX= app.xxx.Value。

function filterData(app)
            % Utility function to filter the data according to the controls
            
            % Initially assume that all data will be displayed and then, subsequently, filter the data
            % based on the controls
            tempIndices = ones([size(app.Data,1),1]);
            
            % Append a column to tempIndices to indicate data that satisfies the smoker control
            if app.NoCheckBox.Value && ~app.YesCheckBox.Value
                tempIndices = [tempIndices, app.Data.Smoker == 0];
            elseif app.YesCheckBox.Value && ~app.NoCheckBox.Value
                tempIndices = [tempIndices, app.Data.Smoker == 1];
            elseif  ~app.YesCheckBox.Value && ~app.NoCheckBox.Value
                tempIndices = [tempIndices, zeros([size(app.Data,1),1])];
            end
            
            % Append a column to tempIndices to indicate data that satisfies the gender control
            if app.MaleCheckBox.Value && ~app.FemaleCheckBox.Value
                tempIndices = [tempIndices, app.Data.Gender == "Male"];
            elseif app.FemaleCheckBox.Value && ~app.MaleCheckBox.Value
                tempIndices = [tempIndices, app.Data.Gender == "Female"];
            elseif  ~app.FemaleCheckBox.Value && ~app.MaleCheckBox.Value
                tempIndices = [tempIndices, zeros([size(app.Data,1),1])];
            end
            
            % Append a column to tempIndices to indicate data that satisfies the location control
            if app.HospitalNameDropDown.Value ~= "All"
                tempIndices = [tempIndices, app.Data.Location == string(app.HospitalNameDropDown.Value)];
            end
            
            % Determine which data points satisfy all requirements
            app.displayedIndices = (sum(tempIndices,2)/size(tempIndices,2) == 1);
        end
    end

  这部分程序的功能是数据选用。ones(x,y)定义x行y列的单元向量。

  接下来的if语句是判别复选框状态的语句。其中,~ app.YesCheckBox.Value中前面的~是非的意思。

  其余部分自行理解,这里需要重点说明:

  复选框的程序调用方法:

 if app.A.Value && ~app.B.Value
                xxxx;
elseif app.B.Value && ~app.A.Value YYYY; elseif ~app.A.Value && ~app.B.Value 0000; end

  下拉框的程序调用方法:

  XXX == string(app.DropDown.Value)

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

        % Code that executes after component creation
        function startupFcn(app)
            % Load the data.
            load('patients.mat','LastName','Gender','Smoker','Age','Height','Weight','Diastolic','Systolic','Location');
            
            % Store the data in a table and display it in one of the App's tabs.
            app.Data = table(LastName,Gender,Smoker,Age,Height,Weight,Diastolic,Systolic,Location);
            app.UITable.Data = app.Data;
            app.BinWidth = app.BinWidthSlider.Value;
            
            % Update the axes with the corresponding data.
            updateSelectedGenders(app)
            refreshplot(app)
        end

  加载数据:load(‘文件名’,‘XXX’);

  现将数据赋值给app.Data,再导入table中。

  更新数据:updateSelectedGenders(app)
  刷新绘图:refreshplot(app)
% Changes arrangement of the app based on UIFigure width
        function updateAppLayout(app, event)
            currentFigureWidth = app.PatientsDisplayUIFigure.Position(3);
            if(currentFigureWidth <= app.onePanelWidth)
                % Change to a 2x1 grid
                app.GridLayout.RowHeight = {400, 400};
                app.GridLayout.ColumnWidth = {'1x'};
                app.RightPanel.Layout.Row = 2;
                app.RightPanel.Layout.Column = 1;
            else
                % Change to a 1x2 grid
                app.GridLayout.RowHeight = {'1x'};
                app.GridLayout.ColumnWidth = {282, '1x'};
                app.RightPanel.Layout.Row = 1;
                app.RightPanel.Layout.Column = 2;
            end
        end

  根据界面调整布局,之前在学习(二)中已经详细讲解。

  % Value changing function: BinWidthSlider
        function SliderValueChanging(app, event)
            % Update the histogram as the slider value for bindwidth changes.
            app.BinWidth = event.Value;
            for ii=1:length(app.Histogram)
                app.Histogram(ii).NumBins = numhistbins(app,app.Histogram(ii).Data);
            end
        end

  根据滑块的值变动直方图的宽度。

% Callback function: BinWidthSlider, BloodPressureSwitch, 
        % ButtonGroup, UITable
        function refreshplot(app, event)
            Genders = app.SelectedGenders;
            Colors = app.SelectedColors;
            
            % Start with a fresh plot
            cla(app.UIAxes)
            hold(app.UIAxes,'on')
            app.Histogram = gobjects(0);
            
            % Select relevant segment of data
            xdata = app.Data.Weight;
            ydata = app.Data.(app.BloodPressureSwitch.Value);
            
            % Filter the data according to the controls
            filterData(app);

  重点内容:

  清空坐标区内的绘图数据:cla(app.UIAxes)

% Create either a scatter plot or histogram, based on selection
            switch app.ButtonGroup.SelectedObject.Text
                
                case 'Scatter'
                    % Build a scatter plot for each selected gender
                    for ii = 1:length(Genders)
                        selectedpatients = ((app.Data.Gender == Genders(ii)) & (app.displayedIndices));
                        scatter(app.UIAxes,xdata((selectedpatients)),ydata(selectedpatients),Colors{ii});
                    end
                    annotateScatterPlot(app)
                    
                case 'Histogram'
                    % Build a histogram for each selected gender
                    for ii = 1:length(Genders)
                        selectedpatients = ((app.Data.Gender == Genders(ii)) & (app.displayedIndices));
                        NBins = numhistbins(app,ydata(selectedpatients));
                        h = histogram(app.UIAxes,ydata(selectedpatients),NBins,'BinLimits',[floor(min(ydata)) ceil(max(ydata))]);
                        h.EdgeColor = Colors{ii};
                        h.FaceColor = Colors{ii};
                        app.Histogram = [app.Histogram h];
                    end
                    annotateHistogram(app)
                    
            end

  重点:按钮组的程序调用方法:

  采用switch语句,对按钮组进行程序操作

 % Update the table to show only the data that satisfies the controls
            app.UITable.Data = app.Data(app.displayedIndices,:);
            drawnow;
        end

  drawnow; 更新图窗并处理回调

% Value changed function: FemaleCheckBox, 
        % HospitalNameDropDown, MaleCheckBox, NoCheckBox, 
        % YesCheckBox
        function updateSelectedGenders(app, event)
            % List which genders and colors to use
            Genders = [];
            Colors = [];
            Smoker = [];
            
            if app.MaleCheckBox.Value
                Genders = "Male";
                Colors = "blue";
            end
            if app.FemaleCheckBox.Value
                Genders = [Genders "Female"];
                Colors = [Colors "red"];
            end
            if app.YesCheckBox.Value
                Smoker = "Yes";
            end
            if app.NoCheckBox.Value
                Smoker = [Smoker "No"];
            end
            
            if isempty(Genders) || isempty(Smoker)
                % Disable the switches and buttons if they were on
                app.BloodPressureSwitch.Enable = 'off';
                app.ScatterButton.Enable = 'off';
                app.HistogramButton.Enable = 'off';
                app.BinWidthSliderLabel.Enable = 'off';
                app.BinWidthSlider.Enable = 'off';
            else
                % Enable the switches and buttons if they were off
                app.BloodPressureSwitch.Enable = 'on';
                app.ScatterButton.Enable = 'on';
                app.HistogramButton.Enable = 'on';
                app.BinWidthSliderLabel.Enable = 'on';
                app.BinWidthSlider.Enable = 'on';
            end
            app.SelectedGenders = Genders;
            app.SelectedColors = Colors;
            
            refreshplot(app)
        end
    end

  isempty()函数是判断数组是否为空,如果为空,返回逻辑真,值为1,如果数组不为空,返回逻辑假,值为0,其他内容便比较容易理解了。

  这部分学习的内容包括 下拉框、复选框、按钮组、滑块值、开关、菜单栏、表格、散点图和直方图的绘制等功能。另外对辅助功能如清空绘图区、刷线图窗更新等命令也做了学习。

  但是这部分关于编程思想并没有学习透彻,我们之后会专门提到这个问题。因此,本节内容只要掌握这些控件的程序调用方式即可。

  下一节我们学习其他的控件,我另起文档介绍,继续跟紧我!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MatlabApp Designer是一种可视化开发工具,用于创建MATLAB应用程序的用户界面。它提供了一种简单的方式来设计和构建交互式应用程序,包括图形用户界面(GUI)和数据可视化工具。使用App Designer,用户可以轻松地创建自定义应用程序,而无需编写任何代码。它还提供了许多内置的组件和工具,如按钮、文本框、下拉菜单、绘图工具等,以帮助用户快速构建应用程序。 ### 回答2: MATLABApp Designer是一个基于MATLAB的应用程序开发环境。它提供了良好的可视化编程界面,使用户可以方便地创建和设计自己的应用程序。 使用App Designer,用户可以使用拖放和布局工具来创建用户界面。它提供了各种UI组件,如按钮、滑块和文本框,用户可以直接通过拖放方式将它们添加到界面上。用户还可以使用布局器件来调整和排列UI组件,以创建具有良好外观和易用性的应用程序界面。 在App Designer中,用户可以使用MATLAB的强大功能来编写应用程序的逻辑部分。用户可以编写MATLAB脚本和函数,并将它们与界面上的组件相连。用户可以利用MATLAB的数学、绘图和数据处理功能来实现应用程序的各种功能。 App Designer还提供了方便的调试和测试工具。用户可以使用内置的调试器来检查和修复应用程序中的错误。用户还可以使用模拟器来模拟用户与应用程序的交互,以测试应用程序的功能和性能。 另外,App Designer还提供了应用程序的部署选项。用户可以将应用程序导出为独立的可执行文件、Web应用程序或移动应用程序,以便在不同的平台上使用和分享。 总之,MATLABApp Designer是一个非常强大和便捷的应用程序开发工具。它提供了丰富的UI组件、方便的编程界面、强大的功能和灵活的部署选项,使用户能够轻松地创建出功能强大、外观精美的应用程序。无论是学术研究、工程设计还是数据分析,App Designer都是一个非常好用的工具。 ### 回答3: MATLABApp DesignerMATLAB软件中用于设计和构建交互式应用程序的工具。App Designer提供了一个可视化的界面,使用户能够以图形化方式创建自定义的MATLAB应用程序。 使用App Designer,用户可以轻松地创建具有用户界面的交互式应用程序,无需编写复杂的代码。App Designer提供了一系列用于创建界面的可视化组件,如按钮、文本框、下拉菜单等。用户可以通过拖放这些组件来构建应用程序的界面,并使用属性编辑器来调整它们的外观和行为。 除了界面设计,App Designer还提供了对MATLAB语言和函数库的完全访问。这意味着用户可以在应用程序中使用MATLAB的各种功能,包括数学计算、数据处理、图形绘制等。用户可以在App Designer中编写自定义的MATLAB代码,并将其与界面组件进行交互。 与传统的MATLAB脚本文件相比,使用App Designer设计的应用程序具有更高的可视化效果和交互性。用户可以通过添加回调函数来为界面组件定义其行为,使应用程序对用户的操作做出相应的反应。这使得用户能够更方便地与应用程序进行互动,增强了用户体验。 总之,MATLABApp Designer是一个功能强大且易于使用的工具,可帮助用户设计和构建各种交互式应用程序。无论是进行数据分析、数学建模、工程仿真还是其他科学计算任务,App Designer都可以提供一个便捷的方式来创建专业水平的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值