Realizzare un'app simile a quella in figura composta dai seguenti oggetti grafici:

  1. Un "Axes" che contiene il grafico della retta
  2. Una "Label" che contiene  la scrittura y=mx+q
  3. Un "Knob" per i valori di m
  4. Un "Knob" per i valori di q
  5. Uno "Slider" per il valore Xmin
  6. Uno slider per il valore Xmax

Suggerimenti per la creazione della GUI:

STEP 1: La GUI è divisa in 2 parti, questo è fatto scegliendo quando si apre l'App designer "2-Panel App with Auto-Reflow"

STEP 2: Inserire ora sulla sinistra della finestra un "Axes". Cliccare 2 volte su su "Title" e sostituire il testo con "Grafico di una retta".

Andare ora nel Component Browser, cercare la voce "RULERS" e cambiare "XAxisLocation" in "origin". Fare la stessa cosa per "YAxisLocation"

STEP 3: Aggiungere una "Label" sotto l'Axes, cliccare 2 volter e sostituire il testo "Label" con "y=mx+q". Nel Component Browser cercare poi "FontSize" e cambiare il valore in 24.

STEP 4: Prendere un oggetto "Knob" e posizionarlo nella parte destra della finestra. Cliccare 2 volte sulla label "Knob" in basso e sostituire il testo con "m". Questa operazione cambierà immediatamente anche il nome con cui questo oggetto è chiamato, in particolare passerà da app.Knob a  app.mKnob.

Successivamente nel Component Browser eseguire le seguenti modifiche:

  • alla voce "KNOB" sostituire "Limits" tra -10 e 10 scrivendo nella casella "-10,10"
  • cambiare il FontSize a 24

STEP 5: Eseguire la stessa operazione per il secondo Knob rinominandolo però in "q".

N.B.: per fare velocemente questa operazione, selezionare il knob appena ultimato, fare copia e incolla e cambiare la label da "m" a "q".

STEP 6: Inserire ora il primo "Slider". Cliccare 2 volte sulla label "Slider" e cambiare il nome in "Xmin".

Nel Component Browser, prestando attenzione a selezionare  solo in testo, in "FONT AND COLOR" cambiare il font in 24. Questa operazione cambierà solo le dimensioni del testo lasciando invariate le dimensione degli indicatori sotto lo slider. Se invece si selezionasse tutto l'oggetto knob e nel Component Browser in "FONT" si cambiassero le dimensioni a 24, il risultato sarebbe diverso (provare per credere).

Selezionare ora tutto l'oggetto knob e nel Component Browser alla voce "SLIDER" inserire:

  • In "Value" il valore "-5"
  • In "Limits" l'intervallo "-50,0"

STEP 7: Ripetere la stessa operazione con il secondo slider "Xmax" inserendo come "Value" il valore 10 e come "Limits" l'intervallo "0,50".

A questo punto l'interfaccia è completa, si tratta ora di andare in "Code View" e realizzare le funzioni di callback.

STEP 8: Nel Component Browser selezionare in alto app1, premere il tato destro del mouse e nel menù che compare selezionare Callbacks -> Add StartupFcn callback in modo da creare una funzione che viene eseguita all'avvio dell'app.

Questa funzione comparirà anche all'interno del codice. In particolare si osserverà una riga bianca nella quale sarà possibile aggiungere del codice (si osservi invece che Matlab non lascia inserire nulla nelle zone di codice con sfondo grigio)

Nello spazio bianco che si è generato inserire la seguente porzione di codice:

xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

Il codice non fa attro che disegnare nell'Axes una retta con i parametri m e q inseriti tramite mKnob e qKnob e il valore  minimo e massimo di x tramite XminSlider e XmaxSlider.

STEP 9: Ripetere la stessa operazione per app.XmaxSlider, cliccando con il tasto destro del mouse e aggiungendo una funzione di callback che viene richiamata quando viene cambiato il valore dello slider

e inserendo lo stesso codice precedente nella funzione. Questo è corretto perché una volta cambiato il valore Xmax che vogliamo visualizzare è necessario ridisegnare tutta la retta.

STEP 10: Eseguire le stesse operazione dello STEP 9 con app.XminSlider.

STEP 11: Eseguire le stesse operazioni dello STEP 9 con app.qKnob.

STEP 12: Eseguire le stesse operazioni dello STEP 9 con app.mKnob.

STEP 13: Lanciare l'app.

Se si sono eseguire correttamente tutte le operazioni il codice ceh si dovrebbe ottenere è qui sotto riportato (in grassetto è evidenziato il codice aggiunto manualmente negli step da 8 a 12):

classdef app1 < matlab.apps.AppBase

% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
GridLayout matlab.ui.container.GridLayout
LeftPanel matlab.ui.container.Panel
ymxqLabel matlab.ui.control.Label
UIAxes matlab.ui.control.UIAxes
RightPanel matlab.ui.container.Panel
XmaxSlider matlab.ui.control.Slider
XmaxSliderLabel matlab.ui.control.Label
XminSlider matlab.ui.control.Slider
XminSliderLabel matlab.ui.control.Label
qKnob matlab.ui.control.Knob
qKnobLabel matlab.ui.control.Label
mKnob matlab.ui.control.Knob
mKnobLabel matlab.ui.control.Label
end

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

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

% Code that executes after component creation
function startupFcn(app)
xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

end

% Value changed function: mKnob
function mKnobValueChanged(app, event)
xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

end

% Value changed function: qKnob
function qKnobValueChanged(app, event)
xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

end

% Value changed function: XminSlider
function XminSliderValueChanged(app, event)
xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

end

% Value changed function: XmaxSlider
function XmaxSliderValueChanged(app, event)
xval = linspace(app.XminSlider.Value,app.XmaxSlider.Value,50);
yval = app.mKnob.Value*xval+app.qKnob.Value;
plot(app.UIAxes,xval,yval);
if ( min(xval) < max(xval) )
app.UIAxes.XLim = [min(xval) max(xval)];
end
if ( min(yval) < max(yval) )
app.UIAxes.YLim = [min(yval) max(yval)];
end

end

% Changes arrangement of the app based on UIFigure width
function updateAppLayout(app, event)
currentFigureWidth = app.UIFigure.Position(3);
if(currentFigureWidth <= app.onePanelWidth)
% Change to a 2x1 grid
app.GridLayout.RowHeight = {480, 480};
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 = {310, '1x'};
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
end
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.AutoResizeChildren = 'off';
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'MATLAB App';
app.UIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);

% Create GridLayout
app.GridLayout = uigridlayout(app.UIFigure);
app.GridLayout.ColumnWidth = {310, '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;

% Create UIAxes
app.UIAxes = uiaxes(app.LeftPanel);
title(app.UIAxes, 'Grafico di una retta')
xlabel(app.UIAxes, 'x')
ylabel(app.UIAxes, 'y')
zlabel(app.UIAxes, 'Z')
app.UIAxes.XAxisLocation = 'origin';
app.UIAxes.YAxisLocation = 'origin';
app.UIAxes.Position = [5 157 300 267];

% Create ymxqLabel
app.ymxqLabel = uilabel(app.LeftPanel);
app.ymxqLabel.FontSize = 24;
app.ymxqLabel.Position = [92 90 118 30];
app.ymxqLabel.Text = 'y = mx + q';

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

% Create mKnobLabel
app.mKnobLabel = uilabel(app.RightPanel);
app.mKnobLabel.HorizontalAlignment = 'center';
app.mKnobLabel.FontSize = 24;
app.mKnobLabel.Position = [88 232 25 30];
app.mKnobLabel.Text = 'm';

% Create mKnob
app.mKnob = uiknob(app.RightPanel, 'continuous');
app.mKnob.Limits = [-10 10];
app.mKnob.ValueChangedFcn = createCallbackFcn(app, @mKnobValueChanged, true);
app.mKnob.FontSize = 24;
app.mKnob.Position = [69 296 60 60];

% Create qKnobLabel
app.qKnobLabel = uilabel(app.RightPanel);
app.qKnobLabel.HorizontalAlignment = 'center';
app.qKnobLabel.FontSize = 24;
app.qKnobLabel.Position = [236 231 25 30];
app.qKnobLabel.Text = 'q';

% Create qKnob
app.qKnob = uiknob(app.RightPanel, 'continuous');
app.qKnob.Limits = [-10 10];
app.qKnob.ValueChangedFcn = createCallbackFcn(app, @qKnobValueChanged, true);
app.qKnob.FontSize = 24;
app.qKnob.Position = [218 295 60 60];

% Create XminSliderLabel
app.XminSliderLabel = uilabel(app.RightPanel);
app.XminSliderLabel.HorizontalAlignment = 'right';
app.XminSliderLabel.FontSize = 24;
app.XminSliderLabel.Position = [20 150 60 30];
app.XminSliderLabel.Text = 'Xmin';

% Create XminSlider
app.XminSlider = uislider(app.RightPanel);
app.XminSlider.Limits = [-50 0];
app.XminSlider.ValueChangedFcn = createCallbackFcn(app, @XminSliderValueChanged, true);
app.XminSlider.Position = [101 167 150 3];
app.XminSlider.Value = -5;

% Create XmaxSliderLabel
app.XmaxSliderLabel = uilabel(app.RightPanel);
app.XmaxSliderLabel.HorizontalAlignment = 'right';
app.XmaxSliderLabel.FontSize = 24;
app.XmaxSliderLabel.Position = [13 77 67 30];
app.XmaxSliderLabel.Text = 'Xmax';

% Create XmaxSlider
app.XmaxSlider = uislider(app.RightPanel);
app.XmaxSlider.Limits = [0 50];
app.XmaxSlider.ValueChangedFcn = createCallbackFcn(app, @XmaxSliderValueChanged, true);
app.XmaxSlider.Position = [101 94 150 3];
app.XmaxSlider.Value = 10;

% 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 = disegna_retta

% 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
Ultime modifiche: mercoledì, 3 gennaio 2024, 18:52