You are on page 1of 10

Step-by-step procedure for transforming an existing MATLAB script

into a GUI tool using GUIDE

Step 0: Write and debug the program that realizes the computational
model as a MATLAB script file.

Step 1: Plan the GUI. Design the layout and determine which variables
are set through the GUI and how they are presented to the user. Design
the output display.

Step 2: Create the GUI with GUIDE. This will result in the GUIDE-
generated *.fig and the GUI tool *.m files.

Step 3: Transform the program into an appropriate function, called


the “primary model function,” which will be invoked from within the
GUI tool code.

Step 4: Connect the function to the GUI. Add calls from the GUI tool
code to the primary model function and synchronize the GUI objects.

 Multiple graphics windows


In XpultTool the user can see, in both the animation and the completed
plots, the way the energy shifts between potential and kinetic energy as
the ball is in flight.
plot(handles.firstAxes, ...) This also works for plot3, xlabel, ylabel, grid,
title, axis, box, polar, hold, rotate3d, loglog, semilogx, semilogy, legend,
area, bar, pie, hist, surf, and rotate3d.

More GUI Techniques


GUI pop-ups. MATLAB comes with a variety of small predefined GUI
tools in the form of ready-to-go dialog boxes and pop-up tools. These
can be added to your own GUI tools to enhance their functionality.

Waitbars Waitbar pop-ups show the user how much progress has been
made toward the completion of a computational task. The key MATLAB
command is waitbar. (Section 12.1).
The waitbar command creates a thermometer-type display in
a pop-up figure window that represents the progress of the calculation graphically.
<handle>=waitbar(0, '<message string>', 'Name', '<title>');

In each iteration of the loop, the waitbar command is invoked again to update the displayed
state
waitbar(progress, <handle>);

Here, progress should evaluate to a real number between 0 and 1, and < handle> is the
handle to the waitbar that has already been created.

Finally, the waitbar should be deleted by the command close(handle). The following
example illustrates the common pattern of waitbar use.
N=500;
hwb=waitbar(0, 'Calculating ...', 'Name', 'Time marching');
for k=1:N

% <long calculation goes here>


waitbar(k/N, hwb);
end
close(hwb)
File dialogs To save information to a MATLAB-formatted *.mat file,
one can conveniently use a combination of the save command and the
uiputfile command, which pops up a familiar file navigation tool. To
read information from a file, one can use load and uigetfile (Section
12.2) Writing and reading from formatted text files is a little more
complicated and can be accomplished using the commands fopen,
fprintf, and textscan (Section 12.3).
Saving and loading data in .mat files
The save command saves the values and names of MATLAB variables. For example, to
save variables x, y, and t, which could be arrays or scalars, to a file named “myData,” the
syntax is as follows:
save myData x y t

or save('myData', 'x', 'y', 't');

The latter, functional, form of the command is necessary if the file name is stored in a string
variable.
fname='myData';
save(fname, 'y', 'yinit', 'yfinal');

The file thus produced is named myData.mat and is a MATLAB-specific binary file; it is
not a text file and in general cannot be read except by MATLAB. Note that the file contains
not only the data, but also the name and class of each of the variables. If you do not specify
a list of variables, all the variables in the current workspace are stored.

The information stored in a .mat file can be read back into MATLAB using the load
command.
load myData % loads all variables from myData.mat
load myData x y name % loads variables x, y, name from myData.mat

Or

theFile='myData';
load(theFile);
load(theFile, 'x', 'y', 'name')

A GUI interface to file names using uiputfile and uigetfile


uiputfile command, for saving files, and uigetfile, for loading files.

The syntax for uiputfile is:


[FileName, PathName, FilterIndex] = uiputfile(FilterSpec,...
DialogTitle, DefaultName);
Ex: [fname, pname]=uiputfile('*.mat', 'Save in .mat file', 'myData');

The function returns the variable fname containing the name of the file the user chose. The
returned variable pname has the full path name to the chosen folder—and it’s often long.
For example:

C: \Documents and Settings \Alfonso \My Documents \MATLAB \

To carry through on saving the file requires a subsequent save command.


save([pname, fname], 'x', 'y', 'snoutCount');

the first argument is the fully qualified name of the file, including its full path name, and is
formed by concatenating the strings representing the path name and the file name. Notice
that in the string concatenation operation (using square brackets) the path name and file
name need to be in the reverse order from that returned by uiputfile.

To load information into the workspace, the command uigetfile provides comparable
functionality.
[FileName, PathName, FilterIndex] = ...
uigetfile(FilterSpec, DialogTitle, DefaultName)

Ex: [fname, pname]=uigetfile('*.mat', 'Load *.mat file', 'myData');


As with uiputfile, uigetfile only gets a file name and path name; it does not actually
retrieve information from the file. So the common pattern is to follow it immediately by a
load command using the string variables obtained.

load([pname, fname]);

Example:
% save a,b,c to *.mat file chosen by user
a=1.1;
b=2.2;
c=3.3;
[fname, pname]=uiputfile('*.mat', 'Save in .mat file');

% set new values for a,b,c


a=10.1;
b=20.2;
c=30.3;
disp(['a=', num2str(a), 'b=', num2str(b), 'c=', num2str(c)]);
% load values from file, overwriting the current values
[fname, pname]=uigetfile('*.mat', 'Load .mat file');
load([pname, fname], 'a', 'b', 'c');
disp(['a=', num2str(a), 'b=', num2str(b), 'c=', num2str(c)]);
Reading and writing formatted text files
An alternative is to write the information to, and subsequently read it
from, a plain text file. The main advantage of storing information in a
plain text file is that the data can be easily read by humans, and by
many other programs. One disadvantage is that the information about the
class and name of the MATLAB variables that held the information is
not stored. Depending on how the text is written, there may also be a
loss of precision.
Writing data to a text file can be accomplished in three steps:

1. Open the file with the fopen command; this associates an integer called the “file
identifier number” with the file. The file can be opened in several different access
modes (also called permissions).
2. Write data from currently defined MATLAB variables to the file using the fprintf
command. The data will be written as formatted text strings.
3. Close the file using the fclose command.

fid=open('DataFileName.txt', '<accessString>');

Ex:

a=randi([1, 10]);
b=7.2*sqrt(2);
c=3*pi;
name='Alfonzo';

fid1=fopen('Somedata.txt','a');
fprintf(fid1,'%d %f %5.3f %s \n', a, b, c, name);
fclose(fid1);

result: 9 10.182338 9.425 Alfonso

>> fprintf(' Height= %g meters \n', x)

Height= 1.2 meters

>> A=rand(3)
A=
0.8173 0.3998 0.4314
0.8687 0.2599 0.9106
0.0844 0.8001 0.1818
>> fprintf('%g \n', A)
0.817303
0.868695
0.0844358
0.399783
0.25987
0.800068
0.431414
0.910648
0.181847

>> fprintf('%12.8f %12.8f %12.8f \n', A)


0.81730322 0.86869471 0.08443585
0.39978265 0.25987040 0.80006848
0.43141383 0.91064759 0.18184703

Reading data from a text file


8 6.908345 9.425 Alfonso
7 0.257124 9.425 Richard
9 6.724751 9.425 Mingus
7 5.455729 7.345 Theodosius
8 2.824035 7.345 Thurston
7 1.232544 7.345 Aloysius
8 0.229196 3.787 Bob
3 0.332434 9.425 Colfax

To read data from a file, the file can be opened with a “read” access mode and read using
textscan.

fid1=fopen('MyRelevantData.dat', 'r');
theData=textscan(fid1, '%d %f %f %s');
fclose(fid1);

The command textscan uses the same format string conventions as fprintf and returns
a cell array with the data read by column. The first column of data is stored as a vector in
theData{1}, the second in theData{2}, and so forth.

avec=theData{1};
bvec=theData{2};
cvec=theData{3};
Names=theData{4};
disp('Display last row of data')
disp(['a=', num2str(avec(end))]);
disp(['b=', num2str(bvec(end))]);
disp(['c=', num2str(cvec(end))]);
disp(['Name=', Names{end}]);

result: Display last row of data


a=3
b=0.33243
c=9.425
Name=Colfax

Input dialogs The pop-up produced by the inputdlg command allows


the user to enter specific information to the GUI tool without
permanently taking up space on the tool panel (Section 12.4).
prompt={'Enter x_0 (m):',...
'Enter v_0 (m/s):'};
name='Initial values';
numlines=1;
defaultanswer={'0.0', '1.0'};
options.Resize='on';
options.Interpreter='tex';
caStr=inputdlg(prompt,name,numlines,defaultanswer,options);

prompt = {'Enter matrix size:','Enter colormap name:'};


title = 'Input';
dims = [1 35];
definput = {'20','hsv'};
answer = inputdlg(prompt,title,dims,definput

Text Edit Fields of Different Widths

x = inputdlg({'Name','Telephone','Account'},...
'Customer', [1 50; 1 12; 1 7]);

Convert Input to Numeric Values


answer = inputdlg('Enter space-separated numbers:',...
'Sample', [1 50])
user_val = str2num(answer{1})

The first input to the command prompt is a cell array of strings that contains the prompts
for each value to be input. The name of the dialog box is displayed in the top border. If
numlines is 1, then each input is taken to be a scalar value (see the documentation for
inputting vector values). The defaultanswer is another cell array of strings, one for each
of the values being sought. The options structure includes fields for making the panel
resizable, and using the TEX interpreter so that here the prompt 'x_0' is rendered as x0 on
the dialog box.
The returned cell array of strings, caStr, must be processed to set the values of the desired
variables appropriately. If the user presses ‘Cancel’, inputdlg returns a null string (i.e., a
string with length zero).
if length(caStr)>0
x0=num2str(caStr{1});
v0=num2str(caStr{2});
disp(['x0= ', num2str(x0), ' v0=', num2str(v0)]);
end
Question dialogs The pop-up produced by the questdlg command
similarly allows the user to enter the answer to a simple yes/no question
(Section 12.5).
choice=questdlg('Do you want to sing the blues?','Important question');
wantsToSingTheBlues=false;
switch choice
case 'Yes'
disp('Then you gotta pay your dues.');
wantsToSingTheBlues=true;
case 'No'
disp('Okay, then.');
case 'Cancel'
disp('Cancelled.')
end

Sharing information between functions. One often wants to


communicate information between Callback functions. Information
displayed in GUI objects is available to all Callbacks through the
handles structure. It’s often desirable to keep other information available
as well. This can be accomplished through use of the setappdata and
getappdata commands (Section 12.6).

Responding to keyboard and mouse events. Sections 12.7 and 12.8


describe how to make your program responsive to user keyboard clicks,
mouse clicks, and mouse motion. This involves setting Callback
functions associated with those actions by changing the
value of the properties KeyPressFcn, ButtonDownFcn,
WindowButtonMotionFcn, and WindowButtonUpFcn. Each of these
properties takes the value of a handle to a function that is invoked when
the action happens (e.g., the user moves the mouse when the mouse
button is down).

Creating menus in GUIDE. A top bar of pull-down menus can be


added to your GUI tool
using the Menu Editor in GUIDE, as described in Section 12.9.
Pass input data from GUIs

1. Put uiwait in the OpeningFcn of the main AC_GUI


2. Put varargout{1}=handles.wingdata in the OutputFcn of the sub-GUI
3. Put uiresume in the CallBack of the "Confirm" button of the sub-GUI

Moving between different GUI's (bypassing any


intermediate GUI)
Hello everyone,

I am trying to send data (i.e. user input inside text field) between two different GUI's, bypassing
any intermediate GUI. I created a simple GUI to accomplish this after reading multiple forums
and reading the Matlab documentation, but I am still having problems. The GUI I created using
GUIDE, has a static text box in the "main" GUI. Then you press a push button to move to an
"intermediate" GUI that opens a "third" GUI. Finally, the last GUI has a input text box that
would change the value of the static text in the "main" GUI.

From everything I read, I believe the best way to accomplish this is by using setappdata and
getappdata.

First answer:
I believe I found a way to accomplish what I was trying to do... After calling the third GUI, I
added an If statement to check if data was added to the root. If something was added to the root
(data was recorded to be used in the main GUI), then immediately resume back to the main GUI.
It looks something like:

Call third GUI:

testGUI3('testGUI3', handles.figure1);
if isappdata(0,'ReturnTestText')
check = getfield(getappdata(0,'ReturnTestText'), 'testText')
uiresume(handles.figure1);
end
he third GUI has two options. Record data (from the input text box) once a button is pushed (i.e.
OK) or do nothing (i.e. CANCEL button).

%OK button

layers.testText = get(handles.test_edit1,'String');
setappdata(0,'ReturnTestText',layers);
uiresume(handles.figure1);
%CANCEL button
uiresume(handles.figure1);

Second Answer:
Others may be able to comment on the best way to do this using appdata. I have found, however,
that simply passing the handles structure from your main to secondary GUIs is a convenient way
of accomplishing this. This is how I do it:

In the callback in your main GUI that calls the secondary GUI:

function OpenSecondaryGui(hObject,eventdata,handles)
SG = SecondaryGui(handles);
set(SG,'WindowStyle','modal') %If you want to "freeze" main GUI until
secondary is closed.
uiwait(SG) %Wait for user to finish with secondary GUI.
handles = guidata(hObject); %If your secondary GUI updates some handles,
you'll need this line

Then, in the opening function of your secondary GUI, you'd do something like this:
function SecondaryGUI_OpeningFcn(hObject,eventdata,handles,varargin)
handles.mainHandles = varargin{1}; %Get passed-in handles structure and add
them to secondary GUI's handles structure
guidata(hObject, handles);
Finally, to pass data out of the GUI (such as through a user created "close" button, you save the portion
of you secondary handles that contains the primary structure back to your main figure (this assuming
that your opening function of the primary GUI saves the figure handle as "handles.main").
function CloseSecondary_Callback(hObject,eventdata,handles)
guidata(handles.mainHandles.main,handles.mainHandles)

You would just need to apply this another time to pass data through an intermediate to a third
GUI.

If this is going away from the way you prefer too much, no worries. I just figured I'd leave it as a
suggestion, as I've found it to be the cleanest way to share data between GUIs.

You might also like