tags:

views:

42

answers:

1

I have an object-oriented MATLAB app that needs a GUI, and I'd like to use GUIDE for the layout (at least). I've tried the manual way, and doing the control positioning is just too painful.

I've noticed that GUIDE is very much procedurally-oriented; it generates M-files that assume they are run from the path and aren't associated with any classes or objects.

Has anyone had experience trying to use GUIDE in an object-oriented way? If it's straightforward, I'd like to do automatic code generation as well, but I'm willing to let GUIDE just generate the .fig file and write the code myself.

+3  A: 

When you create a gui with guide, for every button/textbox/graph etc. you put on the pane, it automatically generates the shells for the necessary callbacks, so all you have to do is fill in the code. If you change the name of the widgets (their "tags") or add or delete them, it updates your m-file for you, which is handy.

You can associate your gui with objects; the autogenerated m-file has a function outline that looks like this

function YourGUIName_OpeningFcn(hObject, eventdata, handles, varargin)

you can require that someone pass your gui an object or objects through the varargin. The canonical matlab way to do this is to pass parameter name/value pairs, so the call from the command line would look like

YourGuiName('importantobject', object1);

but you could also (especially if there is just one unique argument) assume varargin{1} is a specific parameter, varargin{2} is a second, and so on

In this case, the call from the command line would be

YourGuiName(object1);

In your openingfcn, you would then add a line like

if (length(varargin) < 1) || ~isa(varargin{1}, 'importantObjectType')
     error ('you must pass an importantobject to YourGuiName, see help');
end
myimportantobject = varargin{1}

You now have a choice to make. The canonically correct way to store data in your gui is to put it in the handles structure and then store it with guidata, as in

handles.myobject = varargin{1};
guidata(hObject, handles); %this is just boilerplate 

The boilerplate is necessary because, despite its name, handles does not subclass Handle, and is passed by value, not reference. the guidata command sticks handles somewhere associated with the gui figure so you can get it in subsequent callbacks.

The problem with this approach is that when you put a large object in handles, it makes the guidata command take forever. This is true even though MATLAB is not supposed to copy data when passing by value unless absolutely necessary, and it is even true if your object is a Handle, which takes like 4 bytes to pass back and forth. Don't ask me why, but I suspect it has something to do with memory management & garbage collection.

If your gui is taking a while to execute commands, and you use profile and see it hanging on the guidata command, you should just declare your object to be a global and deal with it that way

global YOURGUI_object;  %it's not my fault; blame MATLAB
YOURGUI_object = varargin{1};

Then you can just have all your callbacks execute whatever method of YOURGUI_object they need.

Good luck.

Marc
Thanks for the input, Marc. In GUIDE's autogenerated M-file, there are big scary warnings in the initialization code that say "DON'T EDIT THIS CODE", so I haven't bothered to try messing with input arguments. Is this warning safely ignored? I had assumed it would break the autogeneration routines or something to that effect.
jjkparker
The part you're not allowed to mess with is in the main function and looks like this% Begin initialization code - DO NOT EDITcode% End initialization code - DO NOT EDITAnything else is fair game to edit. If there are create fcns, don't delete these, as they will be called on startup (you can delete all the code in them though if you want). Other than that, have at it
Marc
Ok, well, here's the thing. I want to create this GUI in GUIDE, and have it be represented by an object. Which means in the constructor, the GUIDE-generated M-file is going to need to be called with the syntax MyGui(obj, varargin). This appears to require editing of that initialization code that you're not supposed to edit. I could make MyGui a static function, but then it wouldn't have access to any of my object data. I'm getting the feeling that truly "object-orienting" things would require callbacks as methods as well, so I may need to just write my own code anyway.
jjkparker
No, the gui would have access to your object fields as long as you made them public. If you have private or protected data, I think you should seriously consider not doing this in Matlab, because the object-oriented features of matlab or poor anyway.
Marc

related questions