Acces axes from other callback function in GUI - transfer data between functions
2 views (last 30 days)
Show older comments
Hello!
I am writing a GUI and have difficulties to acces an axes from another (callback)function.
My goal is to plot 'a caculation' on an existing axes with the push of a button.
I have made a simplified version of my code, which should allow to understand my problem.
In this example: Power = velocity x thrust and I wish to plot a (velocity, power)-point on the existing axes.
I have read about: global, findobj, guidata and the article about passing data between functions, but don't seem to figure out how to apply it to my example.
What method (and how) should I use to solve this problem?
My first code example:
function [] = Power()
S.figure = figure('units','pixels','position',[160 140 1600 800]);
S.tx_velocity = uicontrol(S.figure,'style','text','unit','pixels','position',[10 760 230 30],'fontsize',14,'string','Velocity (m/s)','HorizontalAlignment','Left');
S.tx_thrust = uicontrol(S.figure,'style','text','unit','pixels','position',[10 700 230 30],'fontsize',14,'string','Thrust (N)','HorizontalAlignment','Left');
S.ed_velocity = uicontrol(S.figure,'style','edit','unit','pixels','position',[260 760 100 30],'fontsize',14,'string','50');
S.ed_thrust = uicontrol(S.figure,'style','edit','unit','pixels','position',[260 700 100 30],'fontsize',14,'string','1000');
S.tx_power = uicontrol(S.figure,'style','text','unit','pixels','position',[10 300 220 30],'fontsize',14,'string','Power (W)','HorizontalAlignment','Left');
S.ed_power = uicontrol(S.figure,'style','edit','unit','pixels','position',[260 300 100 30],'fontsize',14,'string','');
S.pb_calculate = uicontrol(S.figure,'style','push','units','pix','position',[10 170 350 40],'fontsize',14,'string','Calculate','callback',{@pb_call_calculate,S});
S.ax_power = axes('Units','pixels','Position',[1070 380 390 390],'Parent',S.figure);
set(gca,'FontSize',12)
xlabel('Velocity (m/s)')
ylabel('Power (W)')
title('Power')
function [] = pb_call_calculate(source,event,S)
%USER INPUT
v = str2num(get(S.ed_velocity,'String'));
thrust = str2num(get(S.ed_thrust,'String'));
%CALCULATION
power = thrust*v;
set(S.ed_power,'String',sprintf('%.1f',power));
% PLOT Power
plot(S.ax_power,v,thrust,'-g.')
xlabel(S.ax_power,'Velocity (m/s)')
ylabel(S.ax_power,'Power (W)')
xlabel('Velocity (m/s)')
This is followed by this error message when I press the button:
Reference to non-existent field 'ax_power'.
Error in unititled4>pb_call_calculate (line 32)
plot(S.ax_power,v,thrust,'-g.')
Error while evaluating UIControl Callback.
I understand that the function "pb_call_calculate(source,event,S)" doesn't know the axes "S.ax_power", and that I have to define it somehow in this callback function.
When I try to use findobj -method:
% PLOT Power
S.ax = findobj('Tag','S.ax_power');
plot(S.ax,v,thrust,'-g.')
xlabel(S.ax,'Velocity (m/s)')
ylabel(S.ax,'Power (W)')
xlabel('Velocity (m/s)')
I get this error message:
Error using plot
Parent must be a scalar graphics handle.
Error in unititled4>pb_call_calculate (line 33)
plot(S.ax,v,thrust,'-g.')
Error while evaluating UIControl Callback.
0 Comments
Accepted Answer
Jan
on 25 Feb 2019
Edited: Jan
on 25 Feb 2019
The problem is, that you create the callback before S is created completely:
S.pb_calculate = uicontrol(S.figure,'style','push','units','pix',...
'position',[10 170 350 40],'fontsize',14, ...
'string','Calculate', ...
'callback',{@pb_call_calculate,S}); % *** here the field S.ax_power
% does not exist yet
S.ax_power = axes('Units','pixels','Position',[1070 380 390 390], ...
'Parent',S.figure);
At the end of the main function, store the struct S in the figure:
function [] = Power()
S.figure = figure('units','pixels','position',[160 140 1600 800]);
...
S.pb_calculate = uicontrol(S.figure,'style','push','units','pix',...
'position',[10 170 350 40],'fontsize',14, ...
'string','Calculate', ...
'callback', @pb_call_calculate);
...
title('Power')
guidata(S.figure, S);
Now you can obtain the current value of S dynamically in each callback:
function [] = pb_call_calculate(source,event)
S = guidata(source);
...
By the way, using the tag would work in this way:
S.ax_power = axes('Units','pixels','Position',[1070 380 390 390], ...
'Parent',S.figure, ...
'Tag', 'ax_power'); % You have to set the tag explicitly
... and in the callback:
S.ax = findobj('Tag', 'ax_power');
This is not efficient, because it searchs in all graphic objects. If you have some open GUIs, this can be slow. It is smarter to store the handle explicitly in the figure, e.g. by the shown guidata, or by setappdata or in the UserData of the figure.
More Answers (0)
See Also
Categories
Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!