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

12 次查看(过去 30 天)
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:

采纳的回答

Voss
Voss 2023-9-29
编辑:Voss 2023-9-29
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

更多回答(1 个)

Walter Roberson
Walter Roberson 2023-9-29
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.

类别

Help CenterFile Exchange 中查找有关 Code Execution 的更多信息

产品


版本

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by