Timer not working in my programmatic app (not app designer)
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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:
0 comentarios
Respuesta aceptada
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
Más respuestas (1)
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.
Ver también
Categorías
Más información sobre Develop Apps Using App Designer en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!