Acces axes from other callback function in GUI - transfer data between functions

2 views (last 30 days)
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.

Accepted Answer

Jan
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.
  1 Comment
Brent Wauters
Brent Wauters on 26 Feb 2019
Hello Jan, thank you for your explanation!
I was not aware that I had to include the tag, to be able to use findobj.
As you suggest to use guidata, below is the correct thinking on how to apply it?
In my main function:
function [] = Power() %In my main function, I define the elements which I would like to display in this GUI screen.
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);
%There is a callback function for the pushbutton, which is reffered as '@pb_call_calculate'. I do not yet define S(?)
S.ax_power = axes('Units','pixels','Position',[1070 380 390 390],'Parent',S.figure);
...
guidata(S.figure, S);%All elements that use 'S.'-notation are stored/saved in the S.figure, except the S.figure itself(?)
In my callback function for the pushbutton:
function [] = pb_call_calculate(source,event)
S = guidata(source);%I call S, which means that I am able to read/modify all 'S.' objects.
...
% PLOT Power
plot(S.ax_power,v,thrust,'-g.')%I am able to plot on S.ax_power, because it is known in this callbackfunction due to the above guidata line.
...
guidata(source,S);% I have modified my plot, and want to keep modifying it each time I push the button.
% Therefore I "update" the S handle so that 'S.ax_power'-axes can be rewritten.
Thank you very much for your help.

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!