As we discussed last time there are some very fundamental functions that we must understand to use a graphical object. One of the is the "get" function. Say we create a window that contains a pushbutton by using the following code:
Not much going on in the above statements. If we want to give the pushbutton some task to do, we would want to specify the callback function. To see all the attributes that can be set on the pushbutton, issue the command:
Which will return something like this:
BackgroundColor = [0.941176 0.941176 0.941176]Callback =CData = Enable = onExtent = [0 0 4 4]FontAngle = normalFontName = MS Sans SerifFontSize = FontUnits = pointsFontWeight = normalForegroundColor = [0 0 0]HorizontalAlignment = centerKeyPressFcn =ListboxTop = Max = Min = Position = [20 20 60 20]String =Style = pushbuttonSliderStep = [0.01 0.1]TooltipString =Units = pixelsValue = BeingDeleted = offButtonDownFcn =Children = Clipping = onCreateFcn =DeleteFcn =BusyAction = queueHandleVisibility = onHitTest = onInterruptible = onParent = Selected = offSelectionHighlight = onTag =Type = uicontrolUIContextMenu = UserData = Visible = on
As you can see, "Callback" is not set to anything by default. Lets say we want it to compute x=sqrt(2) whenever we push the button. There are two ways we can set the callback.
Generally, the best way to handle a callback function is to make a function that does what you want the callback to do. In this case we would make and save a function like:
And we would set the callback using:
To make things even more trackable in your code you could make a single function that contains all the callback functions. For example, if you make a callback function called callbackFcn you could do this:
function callbackFcn(ID)switch IDcase 1disp('ID=1, pb1 pressed...')sqrt(2)otherwisedisp('Incorrect Callback ID...')disp('Doing nothing.')end
And you would set the Callback with the specific ID you want the function to be passed:
However, since this is such a simple task, instead of making another file that can make it difficult to navigate through your code, you may want to just emmbed that function into the callback string. This can be done using:
Note: that if the function you are trying to use contains a string and you want to embed the function inout the callback string, then you need to use a second quotation for every single quote in the statement. For example, if I want to use the statement below in my callback:
The I would have to use the "set" function like this:
These second quotation marks act as a sort of "escape character" that prevents the callback function from being misinterpreted.
I think this is all I will discuss about callback functions for now. But be sure to use the "Product Help" in Matlab (search for uicontrol properties) to get more information.
But before I conclude this post I want to discuss two properties that are sort of overlooked by the average user. When you get more advanced in GUI design using Matlab, it isn't uncommon to have 100 handles that you need to interact with. Managing these handles can be a nightmare if you done understand some of the options that Matlab has set forth for such occassions. Two of the most useful properties that can be used are "Tag" and "UserData". The "Tag" is generally understood to be a unique name to that uicontrol. Say for instance you have three pushbuttons, it might be logical to give them Tag names: "pb1", "pb2", and "pb3". What this does is it gives the user a means to find a handle that a function does not have stored locally in its memory space. This is where the power of the function "findobj" comes in. Findobj takes in a couple arguments, the first is a property name and the second is the corresponding property value to look for. If I want to find the handle of the pushbutton with the Tag='pb2', I would issue the command:
The second and more interesting property is the 'UserData' property. Matlab documentation says that this has no inherent function or purpose, so what we can do is exploit this and use it as a sort of heirarchy for graphical objects. Say you have several objects that you would like to operate on in the same exact manner. Instead of individually referencing their unique Tag names you can make a group name using UserData. If I want pb1, pb2, and pb3 to all get set to invisible it might be nice to group them first so that in the future the number of statements I have to code are reduced. Here is a full example of how one could use UserData:
This is a very primative example but it should get the point across that you can keep using Tags to individually reference a handle and you can use UserData to reference a collection of handles. You can even get fancy with the UserData and have a function that reads the UserData and checks to see if an object belongs to more than one grouping and operate on that object accordingly.
I think this is enough for now. Eventually, I will post a videoclip that will showcase some GUIs that I made that use the features I have outlined above.