三 示例學習
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
至此,我們了解了界面大小調整的程序含義,同時學習了如何 利用識別文本框的輸入值、並且如何輸出結果值在文本框中;另外還學習了如何在指定的繪圖區中繪圖。
下面我們學習第三個教程,我另起第三個文檔,跟緊哦!