uicontrol not working inside a function

7 visualizzazioni (ultimi 30 giorni)
Hi!
Here are some lines of code, regarding a function that is expected to show a dynamic plot that has to be closed when a pushbutton is pressed. To do this, I'm using "uicontrol".
For some reason, the trigger of the pushbutton is correctly detected (i can see the variable "isAnimated" that goes to "false" if i remove the semicolon), but somehow the new iteration of the while loop resets the flag to "true". Therefore, the pushbutton is useless and the loop is never interrupted.
This very same code works perfectly if placed in the main script, could you help me figuring out why it doesn't work in a function?
Thank you very much.
function dynamic_plot_received_power(P_RX,P_RX_double,P_RX_diffr,P_RX_TGT,t_fast,t_sim,P_max)
k = 1;
fig = figure;
uicontrol('Style', 'pushbutton', 'String', 'Chiudi', ...
'Position', [20 20 50 20], ...
'Callback', 'isAnimating=false;'); % create a button that closes the figure if pressed
isAnimating = true;
while isAnimating % keep looping the figure
grid on
hold on
% List of signals that are plotted
plot(t_fast*1e+9,P_RX(k,:),'LineWidth',1.5)
plot(t_fast*1e+9,P_RX_double(k,:),'LineWidth',1.5)
plot(t_fast*1e+9,P_RX_diffr(k,:),'LineWidth',1.5)
plot(t_fast*1e+9,P_RX_TGT(k,:),'LineWidth',1.5)
xlabel('t [ns]')
ylabel('P_{RX} [W]')
ylim([0, P_max*1.1]);
legend('totale','double bounce','diffrazione','solo target')
title(['Potenza ricevuta - ', num2str(t_sim(k)), ' s']);
pause(0.25);
if k < length(t_sim)
k = k+1;
else
k = 1;
end
cla(fig);
hold off
% check condition to close the figure
if ~ishandle(fig) || ~isAnimating
close(fig)
break; % Exit the loop if the figure is closed or the flag is set to false
end
end
end

Risposta accettata

Shivam
Shivam il 12 Feb 2025
Here is the improved version of your code:
function dynamic_plot_received_power(P_RX, P_RX_double, P_RX_diffr, P_RX_TGT, t_fast, t_sim, P_max)
k = 1;
fig = figure;
isAnimating = true;
uicontrol('Style', 'pushbutton', 'String', 'Chiudi', ...
'Position', [20 20 50 20], ...
'Callback', @(src, event) setappdata(fig, 'isAnimating', false));
setappdata(fig, 'isAnimating', true);
while getappdata(fig, 'isAnimating')
grid on;
hold on;
plot(t_fast * 1e+9, P_RX(k, :), 'LineWidth', 1.5);
plot(t_fast * 1e+9, P_RX_double(k, :), 'LineWidth', 1.5);
plot(t_fast * 1e+9, P_RX_diffr(k, :), 'LineWidth', 1.5);
plot(t_fast * 1e+9, P_RX_TGT(k, :), 'LineWidth', 1.5);
xlabel('t [ns]');
ylabel('P_{RX} [W]');
ylim([0, P_max * 1.1]);
legend('totale', 'double bounce', 'diffrazione', 'solo target');
title(['Potenza ricevuta - ', num2str(t_sim(k)), ' s']);
pause(0.25);
if k < length(t_sim)
k = k + 1;
else
k = 1;
end
cla(fig);
hold off;
if ~ishandle(fig) || ~getappdata(fig, 'isAnimating')
close(fig);
break;
end
end
end
Hope it helps.
  1 Commento
Alessandro
Alessandro il 12 Feb 2025
Thank you very much, it works.
Just for the sake of curiosity, why did I see a difference between the implementation of the code in the main and the implementation in the function?
Thank you again, have a nice day!

Accedi per commentare.

Più risposte (1)

Walter Roberson
Walter Roberson il 12 Feb 2025
uicontrol('Style', 'pushbutton', 'String', 'Chiudi', ...
'Position', [20 20 50 20], ...
'Callback', 'isAnimating=false;'); % create a button that closes the figure if pressed
When you specify a script to be executed by a callback, then the script is executed inside the base workspace, not inside any function workspace. So in this case isAnimating would be set to false inside the base workspace, but your code is checking the function workspace version of the variable.

Categorie

Scopri di più su Interactive Control and Callbacks in Help Center e File Exchange

Prodotti


Release

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by