uicontrol not working inside a function

7 ビュー (過去 30 日間)
Alessandro
Alessandro 2025 年 2 月 12 日
回答済み: Walter Roberson 2025 年 2 月 12 日
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 Center および File ExchangeInteractive 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