MATLAB® позволяет вам управлять, может ли функция обратного вызова быть прервана, в то время как она выполняется. Время от времени вы можете хотеть разрешить прерывания. Например, вы можете позволить пользователям останавливать цикл анимации путем создания коллбэка, который прерывает анимацию. В других случаях, когда порядок рабочего коллбэка важен, вы можете хотеть предотвратить потенциальные прерывания. Например, для того, чтобы сделать приложение более быстро реагирующим, вы можете предотвратить прерывание коллбэков, которые отвечают на перемещение указателя.
Функции обратного вызова выполняются согласно их порядку в очереди. Если коллбэк выполняется, и пользовательское действие инициировало второй коллбэк, второй коллбэк пытается прервать первый коллбэк. Первым коллбэком является running callback. Вторым коллбэком является interrupting callback.
Определенные команды, которые происходят в рабочем коллбэке, заставляют MATLAB обрабатывать остальную часть очереди коллбэка. MATLAB определяет поведение прерывания коллбэка каждый раз, когда это выполняет одну из этих команд. Эти команды включают drawnow
, figure
, uifigure
, getframe
, waitfor
, и pause
.
Если рабочий коллбэк не содержит одну из этих команд, то никакое прерывание не происходит. MATLAB сначала закончил выполнять рабочий коллбэк, и позже выполняет прерывание обратного вызова.
Если рабочий коллбэк действительно содержит одну из этих команд, то Interruptible
свойство объекта, который владеет рабочим коллбэком, определяет, происходит ли прерывание:
Если значение Interruptible
'on'
, затем прерывание происходит. Когда MATLAB обрабатывает очередь коллбэка, он приостанавливает выполнение рабочего коллбэка и выполняет прерывание обратного вызова. После того, как прерывание обратного вызова завершено, MATLAB затем продолжает выполнять рабочий коллбэк.
Если значение Interruptible
'off'
, затем никакое прерывание не происходит. Вместо этого BusyAction
свойство прерывания обратного вызова определяет то, что MATLAB делает с прерыванием обратного вызова:
Если значение BusyAction
'queue'
, MATLAB выполняет прерывание обратного вызова после того, как рабочий коллбэк закончится.
Если значение BusyAction
'cancel'
, MATLAB отбрасывает прерывание обратного вызова.
Значение по умолчанию Interruptible
'on'
, и значение по умолчанию BusyAction
'queue'
.
Наконец, если прерыванием обратного вызова является DeleteFcn
CloseRequestFcn
, или SizeChangedFcn
коллбэк, затем прерывание происходит независимо от значения Interruptible
свойство.
В этом примере показано, как Interruptible
и BusyAction
свойства компонентов взаимодействуют, чтобы произвести различные типы поведения прерывания коллбэка.
Создайте файл под названием callbackBehavior.m
в вашей текущей папке, и задают в нем функцию с тем же именем. Эта функция создает приложение с двумя окнами рисунка, каждого с двумя кнопками. Каждая из кнопок имеет ButtonPushedFcn
коллбэк и различное значение свойства выполнения обратного вызова. Если вы нажимаете одну кнопку, и затем нажимаете вторую кнопку, прежде чем первый будет сделан, то коллбэк второй кнопки пытается прервать первое. Кнопки в первом окне отображают и обновляют диалоговое окно прогресса, когда кликнувшийся. Кнопки во втором окне отображают данные на графике, когда кликнувшийся. Можно управлять тем, что происходит путем определения поведения прерывания для этих двух кнопок.
function callbackBehavior % Create the figures and grid layouts fig1 = uifigure('Position',[400 600 500 150]); g1 = uigridlayout(fig1,[2,2]); fig2 = uifigure('Position',[400 100 500 400]); g2 = uigridlayout(fig2,[3,2], ... 'RowHeight', {'1x','1x','8x'}); % Create the label for the first figure window lbl1 = uilabel(g1,'Text','1. Click a button to clear the axes and generate a progress dialog.'); lbl1.Layout.Column = [1 2]; lbl1.HorizontalAlignment = 'center'; % Create the buttons that create a progress dialog interrupt = uibutton(g1, ... 'Text','Wait (interruptible)', ... 'Interruptible','on', ... 'ButtonPushedFcn',@createProgressDlg); nointerrupt = uibutton(g1, ... 'Text','Wait (not interruptible)', ... 'Interruptible','off', ... 'ButtonPushedFcn',@createProgressDlg); % Create the label for the second figure window lbl2 = uilabel(g2,'Text','2. Click a button to plot some data.'); lbl2.Layout.Column = [1 2]; lbl2.HorizontalAlignment = 'center'; % Create the axes ax = uiaxes(g2); ax.Layout.Row = 3; ax.Layout.Column = [1 2]; % Create the buttons to plot data queue = uibutton(g2, ... 'Text','Plot (queue)', ... 'BusyAction','queue', ... 'ButtonPushedFcn',@(src,event)surf(ax,peaks(35))); queue.Layout.Row = 2; queue.Layout.Column = 1; cancel = uibutton(g2, ... 'Text','Plot (cancel)', ... 'BusyAction','cancel', ... 'ButtonPushedFcn',@(src,event)surf(ax,peaks(35))); cancel.Layout.Row = 2; cancel.Layout.Column = 2; % Callback function to create and update a progress dialog function createProgressDlg(src,event) % Clear axes cla(ax,'reset') % Create the dialog dlg = uiprogressdlg(fig1,'Title','Please Wait',... 'Message','Loading...'); steps = 250; for step = 1:steps % Update progress dlg.Value = step/steps; pause(0.01) end close(dlg) end end
Вызовите callbackBehavior
функционируйте, чтобы отобразить окна рисунка.
callbackBehavior
Кликните по парам кнопок, чтобы видеть эффекты различных комбинаций Interruptible
и BusyAction
значения свойств.
Прерывание коллбэка — Нажимает Wait (прерываемый) сразу сопровождаемый любой кнопкой во втором окне: Постройте (очередь) или График (отмена). Поскольку первая кнопка имеет свой Interruptible
набор значений к 'on'
, прерывание происходит. График появляется, в то время как диалоговое окно прогресса все еще запускается.
Организация очередей коллбэка — Нажимает Wait (не прерываемый) сразу сопровождаемый Графиком (очередь). Поскольку первая кнопка имеет свой Interruptible
набор значений к 'on'
и вторая кнопка имеет свой BusyAction
набор значений к 'queue'
, организация очередей происходит. Диалоговое окно прогресса выполнение до завершения. Затем отображения графика.
Отмена коллбэка — Нажимает Wait (не прерываемый) сразу сопровождаемый Графиком (отмена). Поскольку первая кнопка имеет свой Interruptible
набор значений к 'on'
и вторая кнопка имеет свой BusyAction
набор значений к 'cancel'
, отмена происходит. Диалоговое окно прогресса выполнение до завершения. Но затем, никакой график не появляется, потому что MATLAB® отбросил коллбэк графика.
timer
| drawnow
| waitfor
| uiwait