• MATLAB 之 App designer 小白学习(二)


    (一)

    三 示例学习

    2.响应数值输入

    (1)主页——新建——APP——响应数值输入

     

    (2)知识点解读

      这里将学习 数值输入  响应 图像的相关内容。界面如下,包括左面板:四个数值文本编辑框、一个按钮button、右面板:一个坐标区,坐标区内有网格布局,并相应地对控件的名称、属性进行了修改,这些内容可以自行尝试设计。

       我们进入代码视图,学习如何编程实现 界面输入数值 进行 绘图。我按顺次一段一段进行分析。

    classdef Mortgage < matlab.apps.AppBase
    
        % Properties that correspond to app components
        properties (Access = public)
            MortgageCalculatorUIFigure     matlab.ui.Figure
            GridLayout                     matlab.ui.container.GridLayout
            LeftPanel                      matlab.ui.container.Panel
            LoanAmountEditFieldLabel       matlab.ui.control.Label
            LoanAmountEditField            matlab.ui.control.NumericEditField
            InterestRateEditFieldLabel     matlab.ui.control.Label
            InterestRateEditField          matlab.ui.control.NumericEditField
            LoanPeriodYearsEditFieldLabel  matlab.ui.control.Label
            LoanPeriodYearsEditField       matlab.ui.control.NumericEditField
            MonthlyPaymentButton           matlab.ui.control.Button
            MonthlyPaymentEditField        matlab.ui.control.NumericEditField
            RightPanel                     matlab.ui.container.Panel
            PrincipalInterestUIAxes        matlab.ui.control.UIAxes
        end
    

      这段代码的作用: 定义APP类,类名称为 Mortgage,控件属性有 :整个界面图布 MortgageCalculatorUIFigure、 网格布局GridLayout、LeftPanel 左面板、数值文本编辑框 及相应的文本框标签LoanAmountEditFieldLabel、LoanAmountEditField、 InterestRateEditFieldLabel、InterestRateEditField  , LoanPeriodYearsEditFieldLabel 、LoanPeriodYearsEditField 、 MonthlyPaymentEditField ;按钮 MonthlyPaymentButton 、右面板 RightPanel、坐标区PrincipalInterestUIAxes

      

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

      界面自动重排刷新时的属性定义

     onePanelWidth = 576;

      因为这个界面是分为左面板和右面板两个面板,所以这里只定义了一个面板宽度。意思就是,当你在运行程序的时候,程序界面可以最大化,也可以手动调整大小,为了自适应界面的大小变化,这里固定了一个面板的宽度,无论界面变大变小,这个面板的宽度始终为576.

      可以对比一下,小界面为下图

       我拉大界面后,可以发现左面板的宽度始终不变,右面板宽度在随界面大小变化。

       类比一下,如果是三栏式的,就需要对其中两个进行控制,这样的话界面不容易崩溃报错,如下面黄色部分。

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

      但是这两个代码实际意义只是定义面板宽度值,给定这两个面板的宽度是确定值,方便后面对界面调整大小的操作。

      我们继续分析接下来的代码

     % Callbacks that handle component events
        methods (Access = private)
    
            % Changes arrangement of the app based on UIFigure width
            function updateAppLayout(app, event)
                currentFigureWidth = app.MortgageCalculatorUIFigure.Position(3);
                if(currentFigureWidth <= app.onePanelWidth)
                    % Change to a 2x1 grid
                    app.GridLayout.RowHeight = {316, 316};
                    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 = {257, '1x'};
                    app.RightPanel.Layout.Row = 1;
                    app.RightPanel.Layout.Column = 2;
                end
            end
    
            % Button pushed function: MonthlyPaymentButton
            function MonthlyPaymentButtonPushed(app, event)
                           
                % Calculate the monthly payment
                amount = app.LoanAmountEditField.Value ;
                rate = app.InterestRateEditField.Value/12/100 ;
                nper = 12*app.LoanPeriodYearsEditField.Value ;
                payment = (amount*rate)/(1-(1+rate)^-nper);
                app.MonthlyPaymentEditField.Value = payment;
                
                % pre allocating and initializing variables 
                interest = zeros(1,nper);
                principal = zeros(1,nper);
                balance = zeros (1,nper);
                
                balance(1) = amount;
                
                % Calculate the principal and interest over time
                for i = 1:nper
                    interest(i)  = balance(i)*rate ;
                    principal(i) = payment - interest(i) ;
                    balance(i+1) = balance(i) - principal(i) ;
                end
                
                % Plot the principal and interest
                plot(app.PrincipalInterestUIAxes, (1:nper)', principal, ...
                    (1:nper)', interest) ;
                legend(app.PrincipalInterestUIAxes,{'Principal','Interest'},'Location','Best')
                xlim(app.PrincipalInterestUIAxes,[0 nper]) ; 
                
            end
        end
    

      这部分是回调函数,内容相对较多,我们分两部分来看,我用不同颜色标识。

      第一块的内容是调整界面大小:前文提到,定义了一个面板的宽度为固定值。当总界面的宽度比刚才一个面板的宽度还要小时,界面就变成了1×2 的布局,什么意思呢,看下图

      相应的,当界面宽度大于一个面板宽度时,就是2×1的布局,也就是下面这种布局。而其他时候,则左面板宽度不变,右面板大小随界面变化。

     

      第二大块是按钮的回调函数,也就是当运行时按下按钮希望执行的操作:

      代码  amount = app.LoanAmountEditField.Value ; 执行的是读取LoanAmountEditField文本编辑框里的内容,赋值给amount;

      代码:rate = app.InterestRateEditField.Value/12/100 ;执行的是读取InterestRateEditField并进行/12/100 的数值运算,最后赋值给rate;

      代码:nper = 12*app.LoanPeriodYearsEditField.Value可类比上面两行。

      由此看出,欲读取文本框(数值)内容,可采用 变量=app.XX.value的方式,同时,还可以进行数值运算,数值运算可以前置也可以后置,和一般的数值运算表达式一致。

      代码:payment = (amount*rate)/(1-(1+rate)^-nper); 对读取的数值进行计算。

      代码:app.MonthlyPaymentEditField.Value = payment;将上面计算的结果赋值给 MonthlyPaymentEditField 文本框。

      由此可以看出,文本编辑框既可以作为数值输入,也可以作为数值输出。

      接下来的代码是初始化变量,zeros(1,nper)是建立1行nper列的零矩阵。balance(1) = amount,即将amount赋值给balance的第一个数。

      再下面是计算过程。采用的for循环,i从1到nper,这里的nper也就是上文文本框输入值进行计算后赋值的一个数字。对三个变量分别迭代计算求解,并且用向量矩阵的方式,将每一次迭代的值保存在矩阵中。

      for循环计算结束后,是画图区,代码:

      plot(app.PrincipalInterestUIAxes, (1:nper)', principal, ...
      (1:nper)', interest) ; 这里的...是续行符,用于多行输入代码; plot 是绘图指令,括号第一个变量app.PrincipalInterestUIAxes是指绘图的结果在这个绘图区显示;后面的变量分别是横坐标、纵坐标、横坐标、纵坐标。
      legend(app.PrincipalInterestUIAxes,{'Principal','Interest'},'Location','Best') 这和MATLAB的基本代码含义一样,定义图例名称
      xlim(app.PrincipalInterestUIAxes,[0 nper]) ;定义横坐标范围

      由此可以看到,欲在绘图区xxx里绘图,需要调用函数 plot (app.xxx,  x,y,x2,y2.)

      

       剩下的代码是对组件初始化的属性定义和APP创建/删除两部分,在之前设计界面是通过拖拽控件、在检查器里修改相应的属性参数,这部分会自动生成,所以一般不需要再修改。之后的学习中,为了篇幅,也不再对这部分内容进行分析,直接跳过。

      % Component initialization
        methods (Access = private)
    
            % Create UIFigure and components
            function createComponents(app)
    
                % Create MortgageCalculatorUIFigure and hide until all components are created
                app.MortgageCalculatorUIFigure = uifigure('Visible', 'off');
                app.MortgageCalculatorUIFigure.AutoResizeChildren = 'off';
                app.MortgageCalculatorUIFigure.Position = [100 100 653 316];
                app.MortgageCalculatorUIFigure.Name = 'Mortgage Calculator';
                app.MortgageCalculatorUIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);
    
                % Create GridLayout
                app.GridLayout = uigridlayout(app.MortgageCalculatorUIFigure);
                app.GridLayout.ColumnWidth = {257, '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 LoanAmountEditFieldLabel
                app.LoanAmountEditFieldLabel = uilabel(app.LeftPanel);
                app.LoanAmountEditFieldLabel.HorizontalAlignment = 'right';
                app.LoanAmountEditFieldLabel.Position = [50 230 77 22];
                app.LoanAmountEditFieldLabel.Text = 'Loan Amount';
    
                % Create LoanAmountEditField
                app.LoanAmountEditField = uieditfield(app.LeftPanel, 'numeric');
                app.LoanAmountEditField.Limits = [0 10000000];
                app.LoanAmountEditField.ValueDisplayFormat = '%8.f';
                app.LoanAmountEditField.Position = [142 230 100 22];
                app.LoanAmountEditField.Value = 300000;
    
                % Create InterestRateEditFieldLabel
                app.InterestRateEditFieldLabel = uilabel(app.LeftPanel);
                app.InterestRateEditFieldLabel.HorizontalAlignment = 'right';
                app.InterestRateEditFieldLabel.Position = [39 177 88 22];
                app.InterestRateEditFieldLabel.Text = 'Interest Rate %';
    
                % Create InterestRateEditField
                app.InterestRateEditField = uieditfield(app.LeftPanel, 'numeric');
                app.InterestRateEditField.Limits = [0.001 100];
                app.InterestRateEditField.Position = [142 177 100 22];
                app.InterestRateEditField.Value = 4;
    
                % Create LoanPeriodYearsEditFieldLabel
                app.LoanPeriodYearsEditFieldLabel = uilabel(app.LeftPanel);
                app.LoanPeriodYearsEditFieldLabel.HorizontalAlignment = 'right';
                app.LoanPeriodYearsEditFieldLabel.Position = [15 124 112 22];
                app.LoanPeriodYearsEditFieldLabel.Text = 'Loan Period (Years)';
    
                % Create LoanPeriodYearsEditField
                app.LoanPeriodYearsEditField = uieditfield(app.LeftPanel, 'numeric');
                app.LoanPeriodYearsEditField.Limits = [10 40];
                app.LoanPeriodYearsEditField.ValueDisplayFormat = '%.0f';
                app.LoanPeriodYearsEditField.Position = [142 124 100 22];
                app.LoanPeriodYearsEditField.Value = 30;
    
                % Create MonthlyPaymentButton
                app.MonthlyPaymentButton = uibutton(app.LeftPanel, 'push');
                app.MonthlyPaymentButton.ButtonPushedFcn = createCallbackFcn(app, @MonthlyPaymentButtonPushed, true);
                app.MonthlyPaymentButton.Position = [19 71 108 22];
                app.MonthlyPaymentButton.Text = 'Monthly Payment';
    
                % Create MonthlyPaymentEditField
                app.MonthlyPaymentEditField = uieditfield(app.LeftPanel, 'numeric');
                app.MonthlyPaymentEditField.ValueDisplayFormat = '%7.2f';
                app.MonthlyPaymentEditField.Editable = 'off';
                app.MonthlyPaymentEditField.Position = [142 71 100 22];
    
                % Create RightPanel
                app.RightPanel = uipanel(app.GridLayout);
                app.RightPanel.Layout.Row = 1;
                app.RightPanel.Layout.Column = 2;
                app.RightPanel.Scrollable = 'on';
    
                % Create PrincipalInterestUIAxes
                app.PrincipalInterestUIAxes = uiaxes(app.RightPanel);
                title(app.PrincipalInterestUIAxes, 'Principal and Interest')
                xlabel(app.PrincipalInterestUIAxes, 'Time (Months)')
                ylabel(app.PrincipalInterestUIAxes, 'Amount')
                app.PrincipalInterestUIAxes.Position = [30 36 326 250];
    
                % Show the figure after all components are created
                app.MortgageCalculatorUIFigure.Visible = 'on';
            end
        end
    
        % App creation and deletion
        methods (Access = public)
    
            % Construct app
            function app = Mortgage
    
                % Create UIFigure and components
                createComponents(app)
    
                % Register the app with App Designer
                registerApp(app, app.MortgageCalculatorUIFigure)
    
                if nargout == 0
                    clear app
                end
            end
    
            % Code that executes before app deletion
            function delete(app)
    
                % Delete UIFigure when app is deleted
                delete(app.MortgageCalculatorUIFigure)
            end
        end
    end
    

      

      至此,我们了解了界面大小调整的程序含义,同时学习了如何 利用识别文本框的输入值、并且如何输出结果值在文本框中;另外还学习了如何在指定的绘图区中绘图。

      下面我们学习第三个教程,我另起第三个文档,跟紧哦!

  • 相关阅读:
    ionic3使用@angular/http 访问nodejs(koa2框架)服务不能返回数据
    FacebookFriendAdderPro
    SEO记录-1
    thanos 实现 prometheus 高可用 数据持久化2
    Prometheus + consul + grafana 监控体系搭建1
    解决问题方法
    原则设定
    docker-基本概念、架构和使用
    如何有效学习
    社会~
  • 原文地址:https://www.cnblogs.com/Sonny-xby/p/12569239.html
Copyright © 2020-2023  润新知