Matlab
GUI – Callback function
In this
article we’re going to build-up a simple
adder. Our adder (by means of a relevant callback function)
is going to have two ‘edit
text’ components, two ‘static
text’ components, and one ‘push button’ element.
|
I
strongly recommend you to review the first
article of this series, if you haven’t done so. I explain
there how to add elements to your interface, and how to use
the
built-in function ‘set’. You can see this video
on GUIs, too.
Let’s
start... Open your guide
(graphical interface environment) by typing on the command window:
|
>>
guide
Choose
the default option (blank
GUI).
Add (drag)
two ‘edit text’
boxes (which will be your inputs), two ‘static text’
boxes (one
will be just an equal sign and the other will be the output), and add a
‘push button’
(which will be the ‘+’ sign, as in a calculator).
Resize
your elements, figure and window as necessary (by dragging their
anchors on the
corners). You must end-up having something similar to this:
Now,
double-click
on each element, look and modify their properties as indicated
on this
table:
Component |
HorizontalAlignment |
String |
Tag |
Top Edit
Text |
right |
0 |
edit1 |
Bottom
Edit Text |
right |
0 |
edit2 |
Left
Static Text |
center |
= |
text1 |
Rigth
Static Text |
right |
0 |
result |
Push-button |
center |
+ |
pushbutton1 |
You
must now have something similar to this (save it with any name, for
example:
adder.fig):
Before
we develop the code for this interface, we must mention that there are
three
very important instructions when working with GUIs: ‘get’, ‘guidata’,
and ‘set’.
The
‘get’
instruction, gets the string
value from an input component. For
example,
if we want to get the number that the user inputs in ‘edit1’, we can do
it like
this (preceed the identifier tag with ‘handles.’):
get(handles.edit1,
'String')
However,
this instruction gets a string, not
a number; thus, if we need to
numerically
manipulate that value, we have to transform it into a number first. For
example, something typical is:
num =
str2double(get(handles.edit1,'String'));
Now, our
variable ‘num’
does contain a number (double), and we can manipulate it.
Finally,
we must update the value of the component and keep that variable in our
memory-workspace (using the ‘guidata’
instruction) to be used in other callback
functions. We can achieve it by doing this:
handles.edit1
= num;
guidata(hObject,handles)
Generally
speaking, we need to finish every callback function with
guidata(hObject,handles)
in
order to maintain in memory the values of the variables.
The
‘set’
instruction sets the properties of the element that you indicate.
The
property ‘Tag’
is the identifier to use for this purpose. Do you
remember that
you have one ‘static text’
with the tag (identifier) ‘result’?
We are
going to
modify it when the user pushes the button with the string ‘+’. This is
to be accomplished
with the instruction
set(handles.output_line,'String',value)
where
‘value’
contains the addition edit1 + edit2
We have
to take care about two more things:
- What if the user doesn’t
enter numbers in the edit boxes?
- Do we need an initialization
procedure to make sure everything is in order before the user uses our
GUI?
To
modify the Matlab code for the components displayed in your interface,
right-click on any of them and choose ‘View Callbacks’
->
‘Callback’.
You
will be taken to the corresponding m-file (there are many automatically
written
lines, just add the new ones).
We can
test for the input value from the user. Let’s check the code for the
callback function
related to ‘edit1’:
function
edit1_Callback(hObject, eventdata, handles)
%
hObject handle
to edit1 (see GCBO)
%
eventdata reserved
- to be defined in a
future version of MLB
%
handles structure
with handles and
user data (see GUIDATA)
%
Hints: get(hObject,'String') returns contents of edit1 as text
%
str2double(get(hObject,'String'))
returns contents of
% edit1 as a double
num
=
str2double(get(hObject,'String'));
if
isnan(num)
num = 0;
set(hObject,'String',num);
errordlg('Input
must be a number', 'Error')
end
handles.edit1
= num;
guidata(hObject,handles)
In this
callback function, we first read the input from the user and transform it to a
number
(since we are within the edit1_Callback, using
get(handles.edit1,’String’)
is
the same as using get(hObject,'String')).
Then, we use the ‘isnan’ (for
IS
Not
A
Number)
to launch an error message if the value is not a
number, and
set the value to 0, too. Finally, we keep the corresponding numerical
value in
the variable ‘edit1’
(officially recognized by Matlab as
‘handles.edit1’).
We can
do the same thing for the 'edit2'
callback function
(you only need to add the last 8 lines):
function
edit2_Callback(hObject, eventdata, handles)
%
hObject handle
to edit2 (see GCBO)
%
eventdata reserved
- to be defined in a
future version of MLB
%
handles structure
with handles and
user data (see GUIDATA)
%
Hints: get(hObject,'String') returns contents of edit2 as text
%
str2double(get(hObject,'String'))
returns contents of
% edit2 as a double
num =
str2double(get(hObject,'String'));
if
isnan(num)
num = 0;
set(hObject,'String',num);
errordlg('Input must be a number', 'Error')
end
handles.edit2
= num;
guidata(hObject,handles)
And,
since the values are kept in memory due to the 'guidata' instruction
used
in both
callback functions (in variables handles.edit1 and handles.edit2), we
can easily
code
the section for the push-button, like this (you have to add only the
last two
lines):
%
--- Executes on button press in pushbutton1.
function
pushbutton1_Callback(hObject, eventdata, handles)
%
hObject handle
to pushbutton1 (see
GCBO)
%
eventdata reserved
- to be defined in a
future version of MLB
%
handles structure with handles and
user data (see
GUIDATA)
addition
= handles.edit1 + handles.edit2;
set(handles.result,
'String', addition);
Bingo!
We’re almost done!
We need
to consider the initialization
part. What if the user press the ‘+’
button
without entering any data? Will everything work fine?
Unfortunately
not. ‘edit1’
and ‘edit2’
don’t have zero values, they display a ‘0’
string
(not
a number). So, if the user press the ‘+’ button without entering any
data, your
GUI will display a number, but nothing to do with the expected
numerical 0
value.
To
tackle this down, we just add some lines in the section code that runs
just
before ‘adder’
(your m-file, remember?) is made visible (most of the
lines are
written by Matlab automatically, you just add three lines), like this:
%
--- Executes just before adder is made visible.
function
adder_OpeningFcn(hObject, eventdata, handles, varargin)
%
This function has no output args, see OutputFcn.
%
hObject handle
to figure
%
eventdata reserved
- to be defined in a
future version of MLB
%
handles structure
with handles and
user data (see GUIDATA)
%
varargin command
line arguments to
adder (see VARARGIN)
%
Choose default command line output for adder
handles.output
= hObject;
num = 0;
handles.edit1
= num;
handles.edit2
= num;
%
Update handles structure
guidata(hObject,
handles);
%
UIWAIT makes adder wait for user response (see UIRESUME)
%
uiwait(handles.figure1);
Done!
Run your GUI by clicking on the ‘run’
icon
at the top of your editor
window...
From
'Callback Function' to home
From
'Callback
Function' to 'GUIs Menu'
|