5 Tvorba grafického rozhranní v MATLABu Studijní cíl Tento blok je věnován základům tvorby grafického rozhranní jako sou‐ část aplikací vytvořených v programovém prostředí MATLAB. Program s gra‐ fickým rozhranním velmi zjednodušuje používání hotové aplikace uživatelům, kteří nemají zkušenosti s používáním MATLABu. Uživatelské grafické rozhraní (Graphical User Interface GUI) je velmi užitečné v případě tvorby samostatně spustitelných aplikací (standalone applications), které je možné dále distribu‐ ovat za stejných podmínek, jaké jsou stanoveny pro licenci na MATLAB Compi‐ ler, pomocí kterého byla vytvořena.
Doba nutná k nastudování
2 ‐ 3 hodiny
Průvodce studiem Při studiu tohoto bloku se předpokládá, že čtenář je obeznámen se složitějšími datovými typy MATLABu (struktura, pole buněk, objekt), se základy objektové‐ ho programování a s používáním standardních grafických prvků (Push Button, Check Box, Slider, Edit, Static Text, Axes atd.). Jsou ukázány (kapitola 5.1) prin‐ cipy tvorby grafického uživatelského rozhranní a na jednoduchém příkladě dva způsoby jeho vytvoření – pomocí nástroje GUIDE (kapitola 5.2.1) a pouze pro‐ gramově (kapitola 5.2.2). Na závěr (kapitola 5.3) je uveden příklad vytvoření GUI pomocí nástroje pro složitější úlohu. V textu jsou použity následující typografické konvence: Calibri 11, Bold, Italic Courier Courier Courier Courier Courier Courier Courier Courier Courier
New New New New New New New New New
10, Bold 10, Bold 10 10 10, Italic
9 9 9 9
nové pojmy k zapamatování názvy nástrojů MATLABu upřesnění nápovědy (help téma) názvy příkazů, funkcí a objektů označení části příkazu, která se může vynechat názvy proměnných použitých v programu výpis programu – standardní text výpis programu – klíčová slova výpis programu – řetězec výpis programu – komentář
5.1 Tvorba grafického rozhranní v MATLABu Programové prostředí MATLAB dovoluje vytvořit (bez potřeby dodatečných toolboxů) grafické rozhranní k uživatelskému programu. Je možné vytvořit samostatné okno se standardními prvky, jejichž vlastnosti je možné programo‐ vě měnit a události (pohyb myši a použití jejich tlačítek, stisk klávesy) těchto objektů spojit s vlastní programovou obsluhou. Obsluha události (funkce) se v terminologii MATLABu nazývá callback function. Výsledný program
KŘP/IMSW Modelování ve výpočtových software
5‐1 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
s grafickým rozhranním je tvořen jedním či dvěma soubory stejného jména 1 . Základní soubor s příponou .m (existuje vždy) obsahuje vlastní program (sadu funkcí obsluhujících jednotlivé události). V inicializační (základní) funkci tohoto souboru může být vytvořeno celé grafické rozhranní programově. Druhý sou‐ bor s příponou .fig bude přítomen pouze v případě, že jsme grafické rozhranní vytvořili samostatně pomocí nástroje GUIDE. Tento soubor obsahuje popis grafického rozhranní (vlastnosti okna, použité grafické objekty jejich rozmístění a výchozí vlastnosti). Při použití nástroje GUIDE se kromě souboru s příponou .fig vygeneruje automaticky i základní soubor s inicializační funkcí a hlavičky callback funkcí použitých ovládacích prvků.
Základní soubor s příponou .m má předepsanou strukturu. Formálně je to sou‐ bor obsahující několik funkcí. První (povinná) funkce 2 je inicializační (základní) funkce. Obsahuje buď programové vytvoření okna (funkce figure) a definice grafických prvků (funkce uicontrol) nebo přípravu parametrů a volání funkce gui_mainfcn (v případě vytvoření pomocí GUIDE). Funkce gui_mainfcn zajistí vytvoření okna (s využitím definic připravených v souboru .fig) a zajistí volání uživatelem definovaných obsluh událostí při jejich výskytu. Funkce ob‐ sluhy událostí a případné další funkce jsou v obou případech uvedeny dále v základním souboru za inicializační funkcí (subfunction).
5.2 Princip tvorby programu s GUI Na následujících dvou jednoduchých příkladech programů MATLABu s grafickým rozhranním budou demonstrovány základní principy tvorby pro‐ gramů oběma způsoby. Činnost obou programů je stejná. Po spuštění se vytvo‐ ří okno s tlačítkem Konec, jehož stisknutí ukončí program. První příklad (soubo‐ ry Prikl01a.fig a Prikl01a.m) je vytvořen pomocí nástroje GUIDE, v druhém pří‐ kladě (Prikl01b.m) je grafické rozhranní vytvořeno programově.
5.2.1 Tvorba GUI pomocí GUIDE Pomocí příkazu guide zapsaného do příkazového řádku MATLABu se spustí interaktivní nástroj umožňující návrh grafické části programu (viz Obrázek 5‐1). Vzhled okna nástroje GUIDE s vytvořeným návrhem je zobrazen na Obrázku 5‐2. Programový kód (viz Výpis programu 5‐1) je vygenerován automaticky včetně anglických komentářů (pro zkrácení výpisu jsou v tomto textu komentáře vět‐ šinou odstraněny). Inicializační funkce Prikl01a je jednou volána bez vstup‐ ního parametru při spuštění (uživatelem) a opakovaně s jedním vstupním pa‐ rametrem při vzniku každé událostí okna (automaticky). V inicializační funkci je vytvořena / aktualizována datová struktura (gui_State) s šesti položkami. Tato struktura a hodnota vstupního parametru inicializační funkce (může být prázdný) jsou předány funkci MATLABu gui_mainfcn. Forma volání se liší
1
Podle potřeby mohou být součástí aplikace i další funkce v samostatných souborech
2
Pouze tuto funkci je možné volat standardním způsobem. Její název by měl být shodný se jmé‐ nem souboru.
KŘP/IMSW Modelování ve výpočtových software
5‐2 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
podle toho, zda byla inicializační funkce volána s výstupními parametry (řádek 13) či nikoliv (řádek 15).
Obrázek 5‐1 Návrhové prostředí GUIDE
Položky datové struktury gui_State jsou naplněny názvem funkce (řádek 03 – použita předdefinovaná konstanta mfilename obsahující řetězec s názvem vykonávané funkce), příznakem používat pouze jedno okno (singleton) i při opa‐ kovaném volání funkce (řádek 04) a re‐ ferencemi (function handle) na funkce, které jsou volané při události spuštění / ukončení (řádek 05 / 06) programu. Po‐ ložka struktury .gui_Callback se ak‐ tualizuje podle hodnoty vstupního pa‐ rametru předávaného při voláních funk‐ Obrázek 5‐2 Vzhled programu Prikl01a ce po vzniku událostí. Vstupní parametr varargin inicializační funkce je dato‐ vého typu pole buněk (cell array) kde první prvek obsahuje název události (da‐ tový typ řetězec), který se převede (str2func) na referenci / ukazatel (functi‐ on handle) na funkci obsluhující tuto událost (řádky 09‐11). V programu je do‐ plněna obsluha pouze jedné události – stisknutí tlačítka (funkce pushbutton1_Callback). Funkce obsluhy událostí mají standardně tři parametry. První parametr hObject je reference (handle) na objekt, v rámci kterého událost vznikla. Druhý parametr eventData je rezervován pro budoucí použití. Třetí parametr handles je struktura obsahující reference (handle) grafických objektů okna a případně uživatelská data. Pomocí tohoto parametru se v obsluze stisku tlačít‐ ka zjistí handle okna programu. Handle okna se použije jako argument funkce close, která uzavře dané okno a tím ukončí program.
KŘP/IMSW Modelování ve výpočtových software
5‐3 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
Výpis programu 5‐1 Tvorba GUI pomocí GUIDE Prikl01a.m ====================================================== 01 function varargout = Prikl01a(varargin) % PRIKL01A M-file for Prikl01a.fig % Begin initialization code - DO NOT EDIT 02 gui_Singleton = 1; 03 gui_State = struct('gui_Name', mfilename, ... 04 'gui_Singleton', gui_Singleton, 05 'gui_OpeningFcn', @Prikl01a_OpeningFcn, 06 'gui_OutputFcn', @Prikl01a_OutputFcn, 07 'gui_LayoutFcn', [] , ... 08 'gui_Callback', []); 09 if nargin && ischar(varargin{1}) 10 gui_State.gui_Callback = str2func(varargin{1}); 11 end 12 if nargout 13 [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 14 else 15 gui_mainfcn(gui_State, varargin{:}); 16 end % End initialization code - DO NOT EDIT % --- Executes just before Prikl01a is made visible. 17 function Prikl01a_OpeningFcn(hObject, eventdata, handles, varargin) % Choose default command line output for Prikl01a 18 handles.output = hObject; % Update handles structure 19 guidata(hObject, handles); % --- Outputs from this function are returned to the % command line. 20 function varargout = Prikl01a_OutputFcn(hObject, eventdata, handles) % Get default command line output from handles % structure 21 varargout{1} = handles.output; % --- Executes on button press in pushbutton1. 22 function pushbutton1_Callback(hObject, eventdata, handles) 23 close(handles.figure1); ====================================================== Prikl01a.m
5.2.2 Programová tvorba GUI Druhá varianta programu – pouze s programovým vytvořením grafického roz‐ hranní – je uvedena na konci kapitoly (viz Výpis programu 5‐2). V tomto případě je nutné v inicializační funkci vytvořit všechny grafické objekty včetně vlastního okna. Okno je vytvořeno příkazem figure a jeho poloha příkazem movegui. Takto vytvořené okno však není ekvivalentní oknu z předchozího příkladu, ob‐ sahuje navíc řádek se standardním menu všech oken MATLABu (viz Obrázek 5‐3). Dalším principiálním rozdílem je, kromě již zmiňované nutnosti explicitní tvor‐ by grafických objektů (příkaz uicontrol), způsob předávání dat mezi jednotli‐ vými funkcemi a způsob spojení funkcí obsluh událostí s příslušnými událostmi (vlastnost Callback příslušného objektu).
KŘP/IMSW Modelování ve výpočtových software
5‐4 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
V případě použití GUIDE je vše určeno konvencemi vyplýva‐ jícími z použití funkce gui_mainfcn. Data i iden‐ tifikace aktuální události se předávají pomocí parametrů funkcí. Data pomocí parametrů funkce obsluhy události, iden‐ tifikace aktuální události pomo‐ cí parametru inicializační funk‐ ce.
V případě programovém řešení jsou handle funkcí obsluhujících jednotlivé události zapsány přímo do vlastností odpovídajícího objektu a call‐ back funkce mají jen dva parametry (hObject, eventdata). Způsob předá‐ vání dat není stanoven. Je věcí programátora, jak předání dat vyřeší. V příkladě Prikl01b je použito jednoduché řešení – hnízdění funkcí 3 (nested function). V obsluze události (callback) stisku tlačítka (funkce konecbutton_Callback) je potřeba handle okna (proměnná f), který je však vytvořen v inicializační funkci. Protože je však tato callback funkce zahnízděná do základní funkce, je proměnná f globální (tj. viditelná) i v této funkci. Další možností by bylo využít první parametr hObject callback funkce, který obsahuje handle objektu, v rámci kterého událost vznikla. Vlastnost objektů Parent obsahuje handle rodičovského (Parent) objektu – v našem případě okna programu (objekt figure). Příslušný příkaz pro získání handle rodičovského objektu by mohl být např. Obrázek 5‐3 Vzhled programu Prikl01b
f = get(hObject,'Parent');
Druhý parametr eventdata je buď prázdný, nebo obsahuje strukturu s dalšími daty, pokud objekt, v rámci kterého událost vznikla, tato data generuje. Výpis programu 5‐2 Programová tvorba GUI Prikl01b.m ===================================================== 01 function Prikl01b % Příklad programového vytvoření GUI % Vytvoř okno na zadané pozici, které není viditelné 02 f = figure('Visible','off','Position', [360,500,450,285]); % Vytvoř tlačítko, s textem, na pozici, handle % funkce při stisku, v b je handle funkce 03 b = uicontrol('Style','pushbutton','String',... 04 'Konec','Position', [200,150,70,25],... 05 'Callback',@konecbutton_Callback); % Inicializace GUI. % nastav text do záhlaví okna
3
Hnízdění funkcí – definuje se funkce uvnitř jiné funkce. Všechny proměnné vnější funkce jsou globální vzhledem k zahnízděné funkci. Zahnízděnou funkci lze standardně volat pouze z vnější funkce. V uvedeném příkladu je volána prostřednictvím handle (callback funkce) v kontextu vnější funkce.
KŘP/IMSW Modelování ve výpočtových software
5‐5 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
06 set(f,'Name','Prikl01b'); % nastav okno doprostřed obrazovky 07 movegui(f,'center'); % učiň okno viditelným 08 set(f,'Visible','on'); % Obsluha událostí (callback). Tato funkce má přístup k % proměnným v hlavní funkce - jde o hnízděnou (nested) funkci 09 function konecbutton_Callback(hObject, eventdata) 10 close(f); % zavři okno programu 11 end 12 end % konec základní funkce ===================================================== Prikl01b.m
5.3 Složitější příklad Tento příklad popisuje vytvoření grafického rozhranní k aplikaci počítající pa‐ rametry polynomiální aproximace maximálně 5. stupně funkce jedné proměn‐ né y=f(x), která je určena dvojicemi hodnot xi,yi uložených v textovém souboru. Stupeň aproximačního polynomu a název souboru s daty jsou volitelné. Kromě výpočtu parametrů polynomu je požadováno vykreslení původních dat ve for‐ mě izolovaných bodů a výsledné aproximace ve formě spojité křivky v zadaném počtu bodů. Měřítko kreslicí oblasti se má přizpůsobit načteným hodnotám.
5.3.1 Návrh vzhledu okna Po zadání příkazu quide se spustí průvodce GUIDE, který podle volby uživatele vytvoří oba soubory (Prikl02.m a Prikl02.fig) a přejde do návrhového režimu (viz Obrázek 5‐1). V návrhovém režimu se přetažením ovládacích a zobrazovacích prvků do pracovní oblasti vytvoří vizuální vzhled okna (grafického rozhranní) výsledné aplikace. Ukázka vzhledu vytvořeného grafického rozhranní aplikace v návrhovém prostředí je na Obrázku 5‐4.
Obrázek 5‐4 Návrhové okno s rozmístěním grafických objektů
KŘP/IMSW Modelování ve výpočtových software
5‐6 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
Pro usnadnění orientace a identifikace jednotlivých prvků jsou v obrázku dopl‐ něna čísla označující umístění (pozici) jednotlivých prvků. Tabulka 1 uvádí se‐ znam všech 35 použitých grafických objektů s uvedením umístění objektu v okně (číslo v kolečku na Obrázku 5‐4), typu objektu (vlastnost Style), jedno‐ značného identifikátoru objektu (vlastnost Tag) a významu objektu v programu.
Tabulka 1 Seznam použitých objektů
Pozice Objekt (Style)
Identifikátor Význam (Tag)
1 16 4
uipanel1 uipanel2
20 3 30 31 35 10 11 12 13 14 15 24 25 26 32 33 34 2 5 6 7 8 9 17 18 19 21 22 23 32 33 34
Panel Push Button
Edit Axes
Static Text
Static Text
objekt sdružující další objekty související s daty objekt sdružující další objekty související s výpočtem pushbutton1 tlačítko pro načtení a zpracování dat funkce pushbutton1_Callback pushbutton2 tlačítko pro výpočet aproximačního polynomu funkce pushbutton2_Callback edit1 editační pole pro zadání názvu souboru s daty edit2 editační pole pro zadání stupně aproximačního polynomu edit3 editační pole pro zadání počtu bodů vykreslení aproximace axes1 oblast grafu pro vykreslení průběhů text2 „Soubor nenačten“ info o výsledku načtení dat text8 „123.456“ aktualizovaný počet dat v souboru text9 „123.456“ aktualizovaná minimální hodnota X text10 „123.456“ aktualizovaná maximální hodnota X text11 „123.456“ aktualizovaná minimální hodnota Y text12 „123.456“ aktualizovaná maximální hodnota Y text20 „123.456“ vypočtená hodnota parametru a0 apr. pol. text21 „123.456“ vypočtená hodnota parametru a1 apr. pol. text22 „123.456“ vypočtená hodnota parametru a2 apr. pol. text26 „123.456“ vypočtená hodnota parametru a3 apr. pol. text27 „123.456“ vypočtená hodnota parametru a4 apr. pol. text28 „123.456“ vypočtená hodnota parametru a5 apr. pol. text1 „Název souboru s daty“ význam vedlejšího pole text3 „Počet dat“ význam vedlejšího pole text4 „Min. hodnota X“ význam vedlejšího pole text5 „Max. hodnota X“ význam vedlejšího pole text6 „Min. hodnota Y“ význam vedlejšího pole text7 „Max. hodnota Y“ význam vedlejšího pole text14 „Stupeň aproximačního polynomu (<=5)“ význam vedlejší‐ ho pole text15 „Počet bodů vykreslení aproximace“ význam vedlejšího pole text16 „y(x)=a0+a1*x+a2*x^2+a3*x^3+a4*x^4+a5*x^5“ význam parametrů apr. pol. text17 „a0“ význam vedlejšího pole text18 „a1“ význam vedlejšího pole text19 „a2“ význam vedlejšího pole text23 „a3“ význam vedlejšího pole text24 „a4“ význam vedlejšího pole text25 „a5“ význam vedlejšího pole
Vlastnosti jednotlivých prvků či společné vlastnosti vybrané skupiny prvků se upravují pomocí nástroje Property Inspector. Jeho použití je ukázáno na Obrázku 5‐6, kde je vidět seznam názvů a aktuálních hodnot vlastností objektu KŘP/IMSW Modelování ve výpočtových software
5‐7 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
PushButton. Seznam všech v návrhu použitých objektů je k dispozici v nástroji Object Browser (Obrázek 5‐7).
Obrázek 5‐5 Property Inspector
Obrázek 5‐6 Object Browser
5.3.2 Vytvoření programu aplikace Při použití nástroje GUIDE se vytvoří kostra programu v souboru .m včetně hlaviček všech callback funkcí obsluhujících události spojené s oknem a použi‐ tými objekty. Události můžeme rozdělit do tří skupin. První skupina jsou udá‐ losti spojené s existencí okna tj. callback funkce obsluhující tyto události se vytváří automaticky s kostrou programu. Příkladem budiž události otevření a ukončení okna aplikace, při jejichž výskytu jsou volané callback funkce _OpenningFcn() a _OutputFcn (viz řádky 12 a 27 ve výpisu Prikl02.m). Funkce _OpenningFcn() (událost otevření okna) je vyvolána až po vyvolání všech funkcí _CreateFcn() (událostí vytvoření objektu). KŘP/IMSW Modelování ve výpočtových software
5‐8 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
Druhá skupina jsou událostí spojené s existencí objektu v návrhu tj. jejich ob‐ sluha (callback funkce) se vytvoří při vložení objektu do návrhového okna. Pří‐ kladem budiž objekt EditBox. Po jeho vložení se vytvoří dvě callback funkce (viz např. řádky 54 a 63 ve výpisu Prikl02.m). První – _CreateFcn() – je vola‐ ná při vytvoření prvku a druhá – _Callback – je volána při změně textu (vlastnost String). První funkce umožňuje např. v případě, že jde o zadávané číslo zajistit, jaká je při návrhu zadaná počáteční textová hodnota a provést konverzi na odpovídající číselnou hodnotu v příslušné proměnné. Druhá funkce umožňuje aktualizovat číselnou hodnotu odpovídající proměnné v okamžiku dokončení editace textového řetězce.
Třetí skupina jsou události, které se obsluhují až na vyžádání uživatele. Typic‐ kým příkladem je objekt PushButton, kde je možné zvolit callback pro několik událostí. Na řádku 29 je obsluha nejběžnější události – _CallBack(), která nastane při uvolnění stisknutého tlačítka. Další callback funkcí, která se vytváří až na požádání, je obsluha události vytvoření objektu – _CreateFcn(). Udá‐ lost vytvoření (a zrušení objektu s odpovídající callback funkcí _DeleteFcn()) je generována pro každý objekt okna ale pouze pro objekt EditBox je auto‐ maticky vytvářena callback funkce _CreateFcn(). Následuje výpis programové části aplikace, ze které byly odstraněny automa‐ ticky vkládané komentáře pro zkrácení výpisu. Tento kód je z větší části vytvo‐ řen automaticky. Doplněny jsou příkazy callback funkcí. Informace mezi jednot‐ livými funkcemi jsou předávány pomocí položek parametru (struktury) handles. Jsou využívány jednak automaticky přidávané položky (handle jednot‐ livých objektů) a jednak uživatelská položka (struktura) User obsahující všechna uživatelská data. Pokud se uvnitř funkce změní data v parametru (struktuře) handles, je potřeba zajistit aktualizaci voláním systémové funkce guidata(). Více viz help guidata. Výpis programu 5‐3 Tvorba GUI pomocí GUIDE složitější příklad Prikl02.m ======================================================= 001 function varargout = Prikl02(varargin) % PRIKL02 M-file for Prikl02.fig % Begin initialization code - DO NOT EDIT 002 gui_Singleton = 1; 003 gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @Prikl02_OpeningFcn, ... 'gui_OutputFcn', @Prikl02_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); 004 if nargin && ischar(varargin{1}) 005 gui_State.gui_Callback = str2func(varargin{1}); 006 end 007 if nargout 008 [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); 009 else 010 gui_mainfcn(gui_State, varargin{:}); 011 end % End initialization code - DO NOT EDIT
KŘP/IMSW Modelování ve výpočtových software
5‐9 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
% --- Executes just before Prikl02 is made visible. 012 function Prikl02_OpeningFcn(hObject, eventdata, handles, varargin) % Choose default command line output for Prikl02 013 handles.output = hObject; % Vytvoření uživatelské struktury s potřebnými položkami a daty 014 n=str2double(get(handles.edit2,'String')); % stupeň polynomu 015 x.PN=n; % stupeň polynomu (aktualizuje edit2) 016 x.Pk=zeros(1,n+1); % vektor koef. Pol. (pushbutton2_Callback) 017 n=str2double(get(handles.edit3,'String')); 018 x.Px=n; % počet bodů aproximačního průběhu (akt. edit3) 019 x.Dn=2; % počet hodnot v souboru (pushbutton1_Callback) 020 x.DX=[0;10]; % vektor hodnot X (pushbutton1_Callback) 021 x.DY=[-1;1]; % vektor hodnot Y (akt. pushbutton1_Callback) 022 x.Dr=[0,10,-1,1]; % vek Xmin,Xmax,Ymin,Ymax 023 handles.User=x; % přidej položku User % Aktualizace hodnot v okně podle nastavených hodnot parametrů 024 AktVypPar(handles); % aktualizace výpisu parametrů aproximace 025 AktVypDat(handles); % akt. výpisu parametrů načtených dat 026 guidata(hObject, handles); % Update handles structure
% --- Outputs are returned to the command line. 027 function varargout = Prikl02_OutputFcn(hObject, eventdata, handles) % Get default command line output from handles structure 028 varargout{1} = handles.output; % --- Executes on button press in pushbutton1. 029 function pushbutton1_Callback(hObject, eventdata, handles) % načtení dat ze souboru s kontrolou 030 nazev=get(handles.edit1,'String'); % název souboru 031 try % kontrola načtení dat 032 data=load(nazev); % zkus načíst soubor 033 catch ME % je-li chyba 034 set(handles.text2,'String','Chyba viz okno MATLABu'); 035 disp(ME.message); % výpis do rádku okna MATLABu 036 return % konec obsluhy při chybě 037 end 038 [r,s]=size(data); % rozměry načtené matice 039 if s~=2, % nejsou-li dva sloupce 040 set(handles.text2,'String','Soubor nenačten viz MATLAB'); 041 disp('Musí být dva sloupce dat'); 042 return % konec obsluhy při chybě 043 else 044 x=handles.User; % uživatelská data 045 x.Dn=r; % počet dat 046 x.DX=data(:,1); x.DY=data(:,2); % vektor X a Y 047 x.Dr(1)=min(x.DX); x.Dr(2)=max(x.DX); % min,max pro X 048 x.Dr(3)=min(x.DY); x.Dr(4)=max(x.DY); % min,max pro Y 049 handles.User=x; % aktualizace uživ. dat 050 AktVypDat(handles); % aktualizace vypisu na obrazovce 051 guidata(hObject, handles); % Update handles structure 052 set(handles.text2,'String','Soubor načten'); 053 end 054 function edit2_Callback(hObject, eventdata, handles) % kontrola na platnost hodnoty stupeň polynomu 055 n=str2double(get(hObject,'String')); % aktuální hodnota 056 if isempty(n), n=1; % není-li číslo 057 elseif n>5, n=5; % je-li větší než 5 058 elseif n<0, n=0; % je-li menší než 0 059 end
KŘP/IMSW Modelování ve výpočtových software
5‐10 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
060 set(hObject,'String',num2str(n,1)); % zpětný zápis 061 handles.User.PN=n; % ulož hodnotu 062 guidata(hObject, handles); % Update handles structure
063 function edit2_CreateFcn(hObject, eventdata, handles) 064 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 065 set(hObject,'BackgroundColor','white'); 066 end % kontrola na platnost hodnoty stupeň polynomu 067 n=str2double(get(hObject,'String')); % aktuální hodnota 068 if isempty(n), n=1; % není-li číslo 069 elseif n>5, n=5; % je-li větší než 5 070 elseif n<0, n=0; % je-li menší než 0 071 end 072 set(hObject,'String',num2str(n,1)); % zpětný zápis 073 075 076 077 078 079 080 081
function edit3_Callback(hObject, eventdata, handles) n=str2double(get(hObject,'String')); % aktuální hodnota if isempty(n), n=10; elseif n<2, n=2; end set(hObject,'String',num2str(n,4)); % zpětný zápis handles.User.Px=n; % ulož hodnotu guidata(hObject, handles); % Update handles structure
082 function edit3_CreateFcn(hObject, eventdata, handles) 083 if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) 084 set(hObject,'BackgroundColor','white'); 085 end % kontrola na platnost hodnoty počet bodů vykreslení aproximace 086 n=str2double(get(hObject,'String')); % aktuální hodnota 087 if isempty(n), n=100; 088 elseif n<0, n=3; 089 end 090 set(hObject,'String',num2str(n,5)) 091 function pushbutton2_Callback(hObject, eventdata, handles) 092 x=handles.User; % uživatelská data 093 k=polyfit(x.DX,x.DY,x.PN); % koeficienty apex. polynomu 094 handles.User.Pk=k; % ulož hodnotu 095 AktVypPar(handles); % aktualizace vypisu na obrazovce % vykreslení průběhu aproximace v zadaném počtu bodů 096 XX=linspace(x.Dr(1),x.Dr(2),x.Px); 097 YY=polyval(k,XX); % hodnoty aproximace 098 plot(handles.axes1,XX,YY,'r','LineWidth',2); % nakresli 099 guidata(hObject, handles); % Update handles structure % Dvě pomocné uživatelské funkce, předává se struktura handles 100 function AktVypPar(h) % Aktualizace výpisu hodnot koeficientů aproximačního polynomu 101 x=h.User; % uživatelská data 102 if x.PN>4, set(h.text28,'String',num2str(x.Pk(6),'%8.5f')); 103 else set(h.text28,'String','--------'); end 104 if x.PN>3, set(h.text27,'String',num2str(x.Pk(5),'%8.5f')); 105 else set(h.text27,'String','--------'); end 106 if x.PN>2, set(h.text26,'String',num2str(x.Pk(4),'%8.5f')); 107 else set(h.text26,'String','--------'); end 108 if x.PN>1, set(h.text22,'String',num2str(x.Pk(3),'%8.5f')); 109 else set(h.text22,'String','--------'); end 110 if x.PN>0, set(h.text21,'String',num2str(x.Pk(2),'%8.5f')); 111 else set(h.text21,'String','--------'); end
KŘP/IMSW Modelování ve výpočtových software
5‐11 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
112 set(h.text20,'String',num2str(x.Pk(1),'%8.5f')); 113 return 114 function AktVypDat(h) % Aktualizace výpisu vlastností načtených dat a jejich vykreslení 115 x=h.User; % uživatelská data 116 set(h.text8 ,'String',num2str(x.Dn,'%5d')); % počet dat 117 set(h.text9,'String',num2str(x.Dr(1),'%8.3f')); % min. X 118 set(h.text10,'String',num2str(x.Dr(2),'%8.3f')); % max. X 119 set(h.text11,'String',num2str(x.Dr(3),'%8.3f')); % min. Y 120 set(h.text12,'String',num2str(x.Dr(4),'%8.3f')); % max. Y 121 set(h.axes1,'XLim',x.Dr(1:2)); % měřítko osy X 122 set(h.axes1,'YLim',x.Dr(3:4)); % měřítko osy X 123 cla(h.axes1); % vymaž oblast 124 plot(h.axes1,x.DX,x.DY,'*b','LineWidth',2); % nakresli 125 return ===================================================== Prikl02.m
Na posledním Obrázku 5‐7 je ukázka okna (grafického rozhranní aplikace) spuštěné aplikace po načtení souboru s daty (podle zvoleného názvu s kontro‐ lou, ř.32 load), jejich vyhodnocení (určení počtu a rozsahu načtených hodnot – ř. 38 size, výpočet hodnot koeficientů polynomu zvoleného stupně – ř.93 polyfit) a vykreslení původních dat a dat vypočtených podle určeného poly‐ nomu ve zvoleném počtu bodů (ř.98 a ř.124 plot, ř.97 polyval). Určený roz‐ sah hodnot je použit pro nastavení měřítka kreslicí oblasti.
Obrázek 5‐7 Ukázka vzhledu okna spuštěného programu
KŘP/IMSW Modelování ve výpočtových software
5‐12 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice
Pojmy k zapamatování Okruhy problémů: tvorba GUI pomocí GUIDE, programová tvorba GUI, funkce obsluhy událostí, předávání dat mezi funkcemi, zachycení chyb, práce s grafickými objekty, použití handle funkcí Použité nástroje:
GUIDE, Object Browser, Inspektor
Příkazy a funkce: cla, close, get, guidata, guide, gui_mainfcn, figure, ischar, isempty, isequal, ispc, load, movegui, num2str, polyfit, polyval, set, str2double, str2func, try … catch … end, uicontrol
Otázky na procvičení 1. 2. 3. 4. 5.
Co znamená zkratka GUI a jaký typ uživatelského rozhranní se standardně v aplikacích MATLABu používá? V čem vidíte největší výhodu návrhu GUI pomocí nástroje GUIDE? Co označuje pojem „callback function“? Jak je řešeno spojení obsluhy událostí s událostí příslušného objektu v případě použití nástroje GUIDE a jak v případě programového řešení? Jaké jsou možnosti předávání parametrů do obsluhy událostí?
Odkazy a další studijní prameny • •
on‐line dokumentace k programu nebo www.mathworks.com/help/ – část „Creating Graphical User Interfaces“ elektronická učebnice Learning MATLAB 7– www.mathworks.com/academia/student_version/learnmatlab_sp3.pdf (část „Creating Graphical User Interfaces“)
KŘP/IMSW Modelování ve výpočtových software
5‐13 (13) 5.7.11
František Dušek KŘP FEI Univerzita Pardubice