Using GUIDE with object-oriented MATLAB?
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 ge开发者_开发知识库nerates 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.
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.
精彩评论