Have you ever used GUIDE to build a user interface in MATLAB? If yes, I’m curious to hear about the experience. When I started using it for my undergrad research, it was a great way to get user interfaces off the ground quickly and relatively intuitively. However, as user interfaces became more complex, and I had to interact with hardware, programming it became difficult. The problem was that there was no good way to manage state in GUIDE outside of setting everything to the Application Data which felt a lot like using globals.
That was when I started developing user interfaces from scratch using nested functions. Nested functions work well for small user interfaces but for large ones you end up with many shared variables and it becomes confusing. Additionally, it’s difficult to separate things into separate files so the file sizes become overwhelming. This is where object oriented programming becomes really useful. You can componentize different parts of the application, separate the user interface from the algorithm, and make reusable tools.
Neil’s “Guide To Object” tool helps take GUIDE UIs and move them into the object oriented world. Let’s start with the simple example user interface you can select when you open GUIDE.
We then need to take export it to just a function from the file menu drop down in GUIDE. From there we call GuideToObject with the export and then name of the class we want.
GuideToObject('SimpleUI_export.m', 'Blog.SimpleUI', 0)
This builds the classes that we can then work from. Algorithmic pieces should be written after so that they can reference the properties of the object directly rather than indexing into handles. It’s not perfect and there are a few things you may have to do to the generated code as you develop the algorithm. Neil has also given tools to recreate the class in case you make enhancements in GUIDE.
So what has MathWorks done for the user interface development world?
In R2016a MathWorks released App Designer. This is a completely new way to build apps in MATLAB that supercedes GUIDE. It provides an interactive environment like GUIDE for laying out your apps and the code framework for your algorithm right alongside. This code is object oriented and the environment provides programming aids like tab completion to help you develop your algorithms quickly. Additionally, there are many more user interface components you can add and all are more modern looking.
You can get started with it by running appdesigner or selecting “New -> App” from the Home Tab in MATLAB.
Here is an example of the design view and the code view for an app I developed in App Designer. You will see how the code is object oriented with properties for both the components and any other data or state I need to manage.
The other neat thing here is that when I run the app (or create a uifigure, the basis for the app) and look at my task manager you will see a few MATLABWindows.
At this point, I’d recommend using App Designer instead of GUIDE for most use cases. It supports pretty much everything except 3d plots and some of the more advanced charting operations from the toolboxes. Even for those, if they are a small part of the app, you can open a classic MATLAB figure and plot the unsupported things there. A bonus is that because you can have app properties, it’s much easier to manage a second figure from the main application!
Published with MATLAB® R2017a
2 CommentsOldest to Newest
I did some work with app designer, and in most regards I liked it, but the one thing I couldn’t figure out how to do was to return a value to the calling workspace. I was basically trying to generate a complex dialog box, but couldn’t find how to return the values of the controls when I closed the box. I assume there is a method to do so, but I finally ended up going back to hand coding a layout based on the old GUIDE components.
This can be done a few ways. The simplest is by setting a callback function to store a variable. Here’s an example: NumberDialog is a an app designer app with a numeric edit field called EnterANumber. When the number changes, it updates n. If you have a “Done” button in the app, you could also have its ButtonPushed function copy out the properties it needs before closing the app. This would be better for scalability across multiple fields.
function n = getnumfromdlg() n = 0; app = NumberDialog; app.EnteraNumberEditField.Value = n; % Default app.EnteraNumberEditField.ValueChangedFcn = @updaten; uiwait(app.UIFigure) function updaten(~,~) n = app.EnteraNumberEditField.Value; end end
If you want to go the full object oriented route, then there should be another class coexisting with the app designer app and any time anything changes in the app or the object of this other class, the change propagates between them.