Timer not working in my programmatic app (not app designer)

11 visualizaciones (últimos 30 días)
Brendan Hall
Brendan Hall el 29 de Sept. de 2023
Comentada: Voss el 29 de Sept. de 2023
I have a programmatic app where I'm trying to periodically and automatically update a plot. Whenever I use the start(timer_object) it produces a message "Dot indexing is not supported for variables of this type". Here's the app:

Respuesta aceptada

Voss
Voss el 29 de Sept. de 2023
Editada: Voss el 29 de Sept. de 2023
First, line 25:
%update_timer = data.update_timer;
needs to be uncommented for that error to happen (otherwise you get a different error because "update_timer" is undefined).
Errors in timer callbacks can be tricky to debug because the error message doesn't tell you what line it happened on. To debug it, you can put a breakpoint on the first line of the TimerFcn (axTimerFcn) and step through until you get the error. When you do that, you'll find that this line (line 31)
fig = ancestor(src,"figure","toplevel");
gives fig as an empty array [], which causes the error on the next line when you try to access fig.UserData. fig is empty because timers don't exist inside a figure the way uicontrols do, so ancestor is not going to work for them. You could use timerfind or timerfindall to find your timer object, but I recommend restructuring your code so that the callbacks (the uibutton ButtonPushedFcn StartTimer and the TimerFcn axTimerFcn) are nested inside the main function timer_app_1. Then they'll easily have access to whatever they need and it will no longer be necessary to have to store anything in the figure's UserData. Something like this:
function timer_app_1
fig = uifigure('Position',[100 50 2400 3.5*430],'AutoResizeChildren','off');
grid = uigridlayout(fig, [3 3]);
ax = uiaxes(grid);
ax.Layout.Column = 2;
ax.Layout.Row = 2;
uibutton(grid,"Text","Start Timer","ButtonPushedFcn",@StartTimer);
update_timer = timer('ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 1, ... % Period is 1 second
'BusyMode', 'queue',... % Queue timer callbacks when busy
'TimerFcn', @axTimerFcn);
%start(update_timer);
i=1;
function StartTimer(~,~)
start(update_timer)
end
function axTimerFcn(~,~)
i=i+1;
plot(ax,1:10,i.*ones(1,10))
if i==10
stop(update_timer)
end
end
end
  3 comentarios
Voss
Voss el 29 de Sept. de 2023
You're welcome!

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 29 de Sept. de 2023
The first parameter passed to a timer is the timer object, and the second parameter is the event data.
You are trying to
fig = ancestor(src,"figure","toplevel");
which is assuming that the first parameter is a graphics object rather than a timer object.
The easiest workaround is to use
update_timer = timer('ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 1, ... % Period is 1 second
'BusyMode', 'queue',... % Queue timer callbacks when busy
'TimerFcn', @(src,event)axTimerFcn(fig,event));
so that fig gets passed as the first parameter to the callback function.

Categorías

Más información sobre Develop Apps Using App Designer en Help Center y File Exchange.

Productos


Versión

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by