How to control GUI with external m-file

I created a GUI, named 'StartEngine', there is a button 'Run'(handles.pushbutton1) on the GUI.
Now, I opened the GUI and I want to make Background color of this button to be gray with a m-file.
It means how could I implement the following command out of StartEngine.m (corresponding to StartEnge.fig)
set(handles.pushbutton1, 'BackgroundColor', [0.5, 0.5, 0.5]);

11 Comments

Hey Leo,
Are you using guide or appdesigner?
I can just make some assumptions for now and try it later for myself...
But my solution for now:
if the gui is already open you can acess the app. Object which gets created at startup of your gui. Now you can change the behaviour/color of the buttons.
Best Regards
Andi
"Now, I opened the GUI and I want to make Background color of this button to be gray with a m-file."
If you're referring to the m-file that contains the GUI, you would simply execute the line of code you shared in your question,
set(handles.pushbutton1, 'BackgroundColor', [0.5, 0.5, 0.5]);
If you're taking about an external m-file that does not host the GUI, I urge you not to use this approach. External files should not be making these kinds of changes to a GUI
Leo Zhai
Leo Zhai on 16 Dec 2019
Edited: Leo Zhai on 16 Dec 2019
Sorry for I did not describe my question clearly, bellow is the detailed description. After studying your comment, I think I need to figure out a new solution.
Untitled.jpg
The [Run] button should have a callback function and your ExecuteRun.m should be called from within that callback function. That callback function should also control the background color of [Done].
It is incorrect to say that code executed from the base workspace will not affect the GUI. The only reason that could would fail would be if handles does not exist or handles does not have a pushbutton2 field, or it does but it refers to something that does not have a BackgroundColor to set.
The step that is probably missing for you is
fig = findobj('type', 'figure', 'Name', 'StartEngine');
handles = guidata(fig);
If you have the latest version of Matlab, you may want to build your GUI in appdesigner instead.
You can then right click the Run Button in appdesigner and add a callback function. Inside your callback you can execute any code you wish. You can easily access the run button and change its color in the callback. The button would be a property in the app class automatically created by appdesigner.
GUIDE and AppDesigner aren't the only options. Have a look here.
-----------------------------------------------------------------
Thanks to Mohammad Sami and Rik
Many reasons make GUIDE to be the only way for me (and my organization). ?
-----------------------------------------------------------------
Thanks to Walter Roberson
I test your code, but it seems not working.
QTest2.jpg
You could try findall() instead of findobj()
What shows up if you do
figs = findall('type', 'figure');
get(figs, 'Name')
get(figs, 'Tag')
Hi,
after I run the your first line (GUI already opened)
figs = findall('type', 'figure');
the following errors show:
Error using findall (line 24)
Invalid handles passed to findall
figs = findall(0, 'type', 'figure');
get(figs, 'Name')
get(figs, 'Tag')

Sign in to comment.

 Accepted Answer

Leo Zhai
Leo Zhai on 18 Dec 2019
I figure out an alternative solution, which do NOT use "control GUI with external m-file" but use "GUI control itself with feedback of external m-file"
test4.jpg
Before, I thought the GUI(StartEngine.m) and the external m-file(ExcuteRun.m) run parallel, GUI will not "wait for" the external m-file runing to end and get its result/output.
Now, I found the code is "single-thred", GUI will continue after external m-file run to end.
test5.jpg
By the way, I did not find error until now. I wonder if some risk exists using this way.

4 Comments

"I figure out an alternative solution, which do NOT use "control GUI with external m-file" but use "GUI control itself with feedback of external m-file"
Good! That was my first recommendation above. However, the use of evalin() is not a good approach.
" I wonder if some risk exists using this way."
Yes there are risks. Here's a long explanation why eval() and evalin() should be avoided at all cost and a review of some alternatives.
So, it's a step forward to move ExecuteRun into your main GUI file but it's a step backward to use evalin(). I'd be happy to help you fix that but I'd need to hear briefly what ExecuteRun does and what other parts of the GUI need access to it.
For example, if it merely creates a set of variables, you could add a function to your GUI file that executes ExecuteRun, loads the variables into a strcture, and sends that structure variable to whatever callback function needs it.
Leo Zhai
Leo Zhai on 19 Dec 2019
Edited: Leo Zhai on 19 Dec 2019
Thanks Adam Danz for your continued support
Actually, I used not to put ExecuteRun.m in my GUI file or make it as a function called by my GUI.m , because
  • ExecuteRun uses too many inputs from other files running in baseworkspace.
  • ExecuteRun creates too many outputs for other files running in baseworkspace.
  • Besides, I did not understand the side effect of eval() and evalin().
For now, I temporarily solved my problem, and I am going to
  1. learn other Matlab graphical interface tools
  2. learn eval() and evalin()
  3. learn how to choose function vs. m-file wisely.
Then maybe I could figure out a better way or optimization to my solution now.
Sounds like a decent plan, except part 2 ;)
One difficulty you may experience is troubleshooting any of those components when something goes wrong. Let's say you have a variable named "V" in one of the xx.m files in the bottom row. V should always be a positive integer but you noticed it's value is NaN. You have no idea where that value is coming from. It could come from any of these possibilities:
  • from StartEngine
  • from xx.m #1
  • from xx.m #2
  • From within ExecuteRun.m
  • from an interaction in ExecuteRun between StartEngine and xx.m #1
  • from an interaction in ExecuteRun between StartEngine and xx.m #2
  • from an interaction in ExecuteRun between xx.m #1 and xx.m #2 within
and lots of other possibilities. This organization often make reproducibility difficult or even impossible.
One way to deal with many input and output variable is to organize them into a structure. For example,
function [motion, position] = movingObject(action)
end
Where the ouputs & inputs contains many fields
motion.velocity
motion.acceleration
motion.previousPosition
motion.currentPosition
% etc...
Anyway, I'm sure you'll figure this stuff out soon.
Thanks for your greate advice, I will think through it.

Sign in to comment.

More Answers (0)

Categories

Find more on Develop Apps Using App Designer in Help Center and File Exchange

Products

Tags

Asked:

on 12 Dec 2019

Commented:

on 19 Dec 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!