breaking for loop on callback execution

3 views (last 30 days)
Original question (my own bad-coding-practice-but-super-simple solution below in the accepted answer):
Hello, I have the following code inside of a for loop:
f = figure();
done_button = uicontrol('Parent',f,'Style','pushbutton',...
'String','Save and quit','Units','normalized','Position',...
[.915 .92 .07 .03],'Visible','on', 'Callback', @quit);
if done_button.UserData
break
end
and this code for the button callback:
function quit(button, event)
button.UserData = 1;
drawnow
end
The idea is that I want to quit out of the loop when the done button is pressed, but the if statement does not work on button press. I think that's because at the time of the if statement evaluation I have not yet pressed the button, but I don't know how to fix that. I don't want to press this button every loop; only when I want to stop iterating. I looked at this and I'm not sure it applies as I'm not using GUIDE. Would really appreciate help.
  4 Comments
Voss
Voss on 14 Dec 2021
I would have to see more of your code, particularly the loop the figure and uicontrol are created in. If I have that information, I can probably advise.
Vasilisa Iatckova
Vasilisa Iatckova on 6 Sep 2022
Quick follow up for beginners who are struggling through this as well: I found that replacing data in axes for sequential sets of data (in my research, it's brain imaging runs) is better than remaking figures. It will also allow using others' solutions for the problem.

Sign in to comment.

Accepted Answer

Vasilisa Iatckova
Vasilisa Iatckova on 14 Dec 2021
Edited: Vasilisa Iatckova on 14 Dec 2021
To solve my problem, I went with using a text document for sharing variables across functions for now (I create it on button click and check inside the for loop for existance, breaking if exists). That works as intended. With some cleanup (e.g., clear text file before the for loop), it's just a doc with a funny name that's not likely to overwrite any other doc in the working directory. This logic can be used in general to share variables across callbacks and functions.
I'm posting this as the accepted answer because it's a straigtforward 3 x one-liner move, with light computation, doesn't require any FEX solutions, and will work for beginners like myself when all else that was tried fails. Here's example code:
% inside main function:
fid = fopen('I_am_done_for_now.txt', 'w'); fclose(fid); % first pass & clean up after the last button press
for i = 1:1000 % or your range of stuff
if isempty(load('I_am_done_for_now.txt')) % do next iteration if file is empty (button hasn't been clicked)
f = figure(); % with some window callbacks
plot(rand([100, 1])) % or your useful data to look at
done_button = uicontrol('Parent',f,'Style','pushbutton',...
'String','Quit','Units','normalized','Position',...
[.915 .92 .07 .03],'Visible','on', 'Callback', @quit); % or any other callback like a key press
else
break
end
end
% callback
function quit(button, ~)
f = fopen('I_am_done_for_now.txt', 'w');
fprintf(f, '1'); % or anything else
fclose(f);
delete(button.Parent) % closes figure
end

More Answers (1)

Walter Roberson
Walter Roberson on 14 Dec 2021
f = figure();
done_button = uicontrol('Parent',h,'Style','pushbutton',...
'String','Save and quit','Units','normalized','Position',...
[.915 .92 .07 .03],'Visible','on', 'Callback', @quit, ...
'UserData', 0);
while ~done_button.UserData
stuff
end
  1 Comment
Vasilisa Iatckova
Vasilisa Iatckova on 14 Dec 2021
Edited: Vasilisa Iatckova on 14 Dec 2021
Thank you! What I want to do during while ~done_button.UserData is keep executing other callbacks in the figure (I have a moving line and solid lines that appear on key presses + some more), and I don't know how to explicitly restrict that to be inside of the while loop. If you're suggesting that I replace my for loop with a while loop, that won't work because I create and close a figure every iteration (the button will be deleted when figure is closed and it will never be clicked until the user is about to close the figure). The loop ends with waitfor(f) to go to the next iteration.

Sign in to comment.

Categories

Find more on Environment and Settings 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!