Cornell University
ECE 5030
Matlab Graphical User Interface Design
Introduction
Once you have written a program to perform some data-related function you may find that other people want to use it. It is useful to wrap a GUI around the function so that other people (and yourself) can remember how to use the program. MatLab supplies a set of tools for building GUI elements including:
The various GUI elements have a lot of automatic behavior programmed in. For
instance, the slider element has built-in behaviors for dragging the slider,
clicking in the body of the slider (to make a big change in value), and clicking
in the end-arrows of the slider (to make a small change). Your program must
specify what to do with the value returned by the slider element. The following
code fragment implements a slider in a figure window. The main uicontrol
function would be executed once to define the control. The Callback
parameter is a vector of strings which defines what happens each time the user
manipulates the slider. In this simple example, the slider value is assigned
to a variable and printed in the command window. The variable slider1
is refered to as the handle to the control. The callback string refers
to slider1
to retrieve the value from the control handle.
slider1=uicontrol(gcf,... 'Style','slider',... 'CallBack', ... ['s1value=get(slider1,''value'');',... 'disp (num2str(s1value));'... ]);The slider appearance and function can be controlled by changing its properties. The following code sets up the slider to a value-range of [-20 20], sets its position, initial value, color, and the step size for clicks in the slider body and in the slider ends.
slider1=uicontrol(gcf,... 'Style','slider',... 'Min' ,-20,'Max',20, ... 'Position',[10,220,150,20], ... 'Value', 10,... 'SliderStep',[0.01 0.1], ... 'BackgroundColor',[0.8,0.8,0.8],... 'CallBack', ... ['s1value=get(slider1,''value'');',... 'disp (num2str(s1value));'... ]);
As with any graphics object in Matlab, a list of the object's current properties
may be obtained by typing get(uihandle)
, or specifically for the
slider above get(slider1)
. A list of all possible property settings
may be obtained by typing set(uihandle)
, or specifically for the
slider set(slider1)
.
Usually when you write code in a procedural language like Matlab, you expect execution to proceed linearly through the program (except for loops and subroutine calls that you program). Writing a program with uicontrols is different in several ways:
clear all
when you have uicontrols
in a figure, that the control will still be visible, but you may no longer
get its value. The complicated data storage relationship between the figure
and the workspace leads to lots of frustration for new programmers. Approaches
to handling this complexity are explained in the examples below.Examples
clf clear all %plot a couple of sine curves to click on x = 0:.1:6.28; y = sin(x); hline1=plot(x,y); hold on hline2=plot(x,-y/2+.4); %the mouse-click sets a flag for point aquisition set(gcf,'windowbuttondownfcn','hit=1;'); %make a control to stop the loop uicontrol('style','pushbutton',... 'string','Quit', ... 'position',[0 0 50 20], ... 'callback','stopit=1;'); %start looping and waiting for a mouse click stopit=0; while (stopit==0) %check for valid object and chek for line 1 %and see if the mouse was clicked if ~isempty(gco) & gco == hline1 & hit==1 %get the mouse position in graph units mouse = get(gca,'currentpoint'); %calculate the point nearest to the %mouse click [val, pnt] = ... min( sqrt(... (get(hline1,'xdata')-mouse(1,1)).^2 ... +(get(hline1,'ydata')-mouse(1,2)).^2 ... )); %display the result disp(['line1 point=',num2str(pnt)]) %wait for the next click hit=0; end %check for valid object and chek for line 2 %and see if the mouse was clicked if ~isempty(gco) & gco == hline2 & hit==1 mouse = get(gca,'currentpoint'); [val, pnt] = ... min( sqrt(... (get(hline2,'xdata')-mouse(1,1)).^2 ... +(get(hline2,'ydata')-mouse(1,2)).^2 ... )); disp(['line2 point=',num2str(pnt)]) hit=0; end drawnow end
clf clear all set(gcf,'doublebuffer','on') tmax = 2 ; % seconds. NumControl = 20 ; %number of control points FPS = 30 ; %frames/sec ForceZeroSlope = 1 ; AngleRange = 90 ; t = linspace(0, tmax, NumControl) ; tt = linspace(0, tmax, tmax*FPS) ; %start with all zeros in control points y = zeros(1,length(t)); if ForceZeroSlope cs = spline(t,[0 y 0]); else cs = spline(t,y); end yy = ppval(cs,tt); hold on sp = plot(tt,yy); line1 = plot(t,y,'or'); set(gca, 'ylim', [-AngleRange AngleRange]) %set(gca, 'position', [0 0 1 1]) %the mouse-click sets a flag for point aquisition set(gcf,'windowbuttondownfcn','mousedown=1;'); set(gcf,'windowbuttonupfcn','mouseup=1;'); set(gcf,'windowbuttonmotionfcn','mousemotion=1;'); %make a control to stop the loop uicontrol('style','pushbutton',... 'string','Quit', ... 'position',[0 0 50 20], ... 'callback','stopit=1;'); %start looping and waiting for a mouse click stopit = 0; mousedown = 0; mouseup = 0; mousemotion = 0; while (stopit==0) %check for valid object and chek for line 1 %and see if the mouse was clicked if mousedown==1 %get the mouse position in graph units mouse = get(gca,'currentpoint'); %calculate the point nearest to the %mouse click lineX = get(line1,'xdata'); lineY = get(line1,'ydata'); [val, pnt] = min(abs(lineX-mouse(1,1))); %move the control point on the plot lineY(pnt) = mouse(1,2); set(line1, 'ydata', lineY); %make new spline if ForceZeroSlope cs = spline(t,[0 lineY 0]); else cs = spline(t,lineY); end yy = ppval(cs,tt); set(sp, 'ydata', yy); %wait for the next click if mouseup == 1 mouseup = 0; mousedown = 0; mousemotion = 0; end end drawnow end close
set(gcf,'WindowButtonDownFcn',... ['initialpt=get(gca,''currentpoint'');'... 'rect=rbbox;' ... ]); set(gcf,'WindowButtonUpFcn',... [... 'finalpt=get(gca,''currentpoint'');'... 'disp(finalpt(1,1)-initialpt(1,1));'... ]);Another small code fragment shows how to detect which mouse button was pushed. The undocumented figure property
selectiontype
holds the current
mouse button depressed. The values it can contain are the strings normal
,
alt, extend
or open
. Any button, when double-clicked,
causes this property to return open
.
%Detecting which button is pushed. %Use: %get(gcf,'selectiontype') %Which returns: % normal | open | alt | extend %Meaning: % left button | doubleclick | right button | middle button figure(1);clf; axis set(gcf,'windowbuttondownfcn', ... ['disp(get(gcf,''selectiontype''));'])