How to delay in loop without effect to GUI
9 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I am working in MATLAB with GUI. And I have a `for` loop and GUI with while loop globally, each step I need to delay for about 1 second. But when I use `pause(1)` in nested function, the GUI will get stuck and did not update until for loop finish.
Here is my code:
count= uicontrol('Style','text',...
'String', '0',...
'Tag','Count',...
'Fontsize',12,...
'Position',[40, 350,35,35]);
i = 0;
while i < 1000
%do something
i++;
disp(i);
end
This is `for` loop in nested function:
for m=0:1:10
%do something
c = findobj('Tag','Count');
set(c, 'String', num2str(m));
pause(1);
end
But when I execute this `for` loop, the UI text is not updated and while loop stop. And when finishing, it will display `10` in UI text and while loop continue to work. I want it will display every step from 1 to 10.
I really appreciate your help. Thank you in advance.
2 Kommentare
Walter Roberson
am 27 Feb. 2019
It should be updating; it is defined to do so in that case. But some people find that adding a drawnow() before the pause() can help.
Antworten (1)
Walter Roberson
am 27 Feb. 2019
Graphics updates can only occur under a small number of conditions:
- the code is sitting at the MATLAB keyboard waiting for input (including for debugging); or
- drawnow() is called to flush the graphics queue; or
- figure() is called giving a figure (possibly created) focus, or a figure is made visible
- the code is waiting idle in pause() or uiwait() or waitfor()
Note that graphics updates cannot normally occur in your while loop unless the "do something" calls drawnow() or pause() or creates a figure or makes a figure visible.
When a graphics callback is in control, the main MATLAB code cannot proceed, no matter what the settings of the callback object. If that "nested for loop" were inside a callback for the uicontrol, and the uicontrol callback was active, then it would not be possible to progress on the while loop except by returning from the callback.
When a graphics callback is in control, whether a different graphics callback can run or is to be discarded or is to wait depends upon properties of the object whose callback is executing. But for most graphics objects, the default is that the callback is interruptible -- and since the interrupting callback might interact with graphics changing which object is "current", unless you specifically disable interrupts, you should not assume that any objects remains "current" between any two lines. Like if you do
subplot(1,2,1)
plot(1:10)
then the subplot(1,2,1) makes a particular axes the default axes, but an interupt can be processed between that and the plot() statement, so a different axes might become current and the plot() might get drawn there. You should learn to always parent graphics objects:
fig = ancestor(hObject, 'figure');
ax1 = subplot(1, 2, 1, 'Parent', fig);
plot(ax1, 1:10);
An interrupt between any two of those lines cannot change the graphics (unless the interrupt directly manipulates the properties or objects.)
Now, a complication to this model: timer and other device callbacks (such as serial callbacks or data acquisition callbacks) can trigger even while something else is happening. So you can do things like:
global i
i = 0;
t = timer('RepeatMode', 'fixedRate', 'Period', 1, 'TimerFcn', @(varargin) set(count, 'String', i));
start(t)
while i < 1000
%do something
i = i + 1;
end
stop(t)
... However for that kind of task you should probably use waitbar() instead.
0 Kommentare
Siehe auch
Kategorien
Mehr zu Graphics Performance finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!