필터 지우기
필터 지우기

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

조회 수: 12 (최근 30일)
Brendan Hall
Brendan Hall 2023년 9월 29일
댓글: Voss 2023년 9월 29일
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
  댓글 수: 3
Voss
Voss 2023년 9월 29일
You're welcome!

댓글을 달려면 로그인하십시오.

추가 답변 (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