An open exchange for the MATLAB and Simulink user community |
Hosted by The MathWorks |
|
| Related Topics |
| New Products | Support | Documentation | Training | Webinars | Jobs | Newsletters |
| Problems? Suggestions? Contact us at files@mathworks.com | © 1994-2008 The MathWorks, Inc. Trademarks Privacy Policy |
Hi Doug!
Nice video. Maybe you should have mentioned that the contents of h in the callback is static. Adding the field h.buttonTwo in function addButton does not change the contents of h as saved in the callback of buttonOne. Looking at the line “h = rmfield(h, ‘buttonTwo’);”, which is not necessary here, one might think that h is somehow a global variable.
When programming GUIs, I often save data like other handles in the “UserData” field of the figure. In the callback of your example, you could get the handles using the “Parent” property of the buttons. What do you think about that?
Regards
Markus
I’m surprised you didn’t use nested functions for the callbacks to go with earlier hints about GUIs - or maybe that was Loren’s blog…
function simpleGuiNested
h.fig = figure(’position’, [800 30 210 60]);
h.buttonOne = uicontrol(’style’, ‘pushbutton’,…
‘position’,[10 10 100 40], …
’string’ , ‘Add button’, …
‘callback’, {@addButton});
function addButton(hObject, eventdata)
h.buttonTwo = uicontrol(’style’, ‘pushbutton’, …
‘position’,[100 10 100 40], …
’string’ , ‘Remove button’, …
‘callback’, {@removeButton});
set(h.buttonOne, ‘enable’, ‘off’);
end
function removeButton(hObject, eventdata)
delete(h.buttonTwo)
h = rmfield(h, ‘buttonTwo’);
set(h.buttonOne, ‘enable’, ‘on’)
end
end
By the way, the iPod .m4v file is only playing audio for me. “Parsing code for better understanding” is also audio-only.
Aaargh, I am glad Doug does NOT promote nested functions!! The concept of variable scope gets very complicated with nested functions. I really don’t want to be the one who has to debug code with nested functions. There is always a good way without using nested functions.
Markus
Sorry that the indentation of my code got eaten, making it not as readable. Note the trick of creating the control first, then setting the callback because the uicontrol gets passed the structure of handles is no longer needed. You also don’t then really need to store everything in a structure for convenience of passing the handles around since they do not need to be.
It seems to me that perhaps a good convention might be to decorate the names of the nested functions with the name of the function they are nested in, for example: simpleGuiNested_ addButton and simpleGuiNested_ removeButton.
I don’t think the variable scope is what gets complicated with nested functions; if anything, it’s the variable persistence. When you take the handles to the nested functions, you are causing the enclosing scope they depend on to not be destroyed automatically. So, when the main function ends, its variable space persists until the references are released, which happens here when the window is destroyed, which destroys the callback handles. That’s the part I find hard about nested functions.
I guess it helps if you’ve programmed Pascal, which has nested functions. One technique I use them for that I used to use in Pascal was to cleanup a procedure by just throwing a section of code into a nested function. You don’t have to go through and figure out what variables you need to pass and return since the scope is the same. The bonus is that temporary variables that apply only to that segment can be local to the nested function and not persist in the rest of the larger procedure where they might cause trouble. This makes creating subroutines almost trivial, so that you will tend to do it rather than think about how you should and moan that it will take too much effort to figure out all the call parameters, pass them in and also declare them in the function definition.
Markus,
Excellent catch with the scoping and the static nature of h. Scoping can be tricky and I made a mistake! You are completely correct. E-mail me your snail mail address and I will send you some MATLAB goodies for catching this.
While it is an unneeded step, it does not harm anything, so I am not going to reshoot the video. Thanks for the catch.
Doug
Ryan,
Indeed, it is Loren that has covered Nested Functions more:
http://blogs.mathworks.com/loren/2006/02/08/use-nested-functions-to-memoize-costly-functions/
I have an upcoming post with nested functions, but Loren is very good with them.
Doug
Ryan,
I just remade the video and posted it. It seems to be working now. Not sure what happened.
Thanks,
Doug