uicontrol not working inside a function

7 次查看(过去 30 天)
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

采纳的回答

Shivam
Shivam 2025-2-12
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 个评论
Alessandro
Alessandro 2025-2-12
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!

请先登录,再进行评论。

更多回答(1 个)

Walter Roberson
Walter Roberson 2025-2-12
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.

类别

Help CenterFile Exchange 中查找有关 Interactive Control and Callbacks 的更多信息

产品


版本

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by