このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。
コールバック実行への割り込み
MATLAB® では、コールバック関数の実行中に割り込みを許可するかどうかを制御できます。割り込みを許可するかどうかは状況によって異なります。たとえば、ユーザーがアニメーションのループを停止できるようにするには、アニメーションに割り込むコールバックを作成します。一方で、実行するコールバックの順序が重要な場合は、割り込みが発生しないようにする必要があります。たとえば、アプリの応答性を高めるために、ポインターの動きに応答するコールバックの割り込みを禁止する場合があります。
コールバックの割り込み時の動作
コールバック関数は、キュー内での順序に従って実行されます。コールバックの実行中にユーザーのアクションによって 2 番目のコールバックがトリガーされると、2 番目のコールバックは最初のコールバックに割り込もうとします。最初のコールバックは "実行中コールバック" です。2 番目のコールバックは "割り込みコールバック" です。
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
というファイルを作成し、そのファイルで同じ名前の関数を定義します。この関数は、それぞれに 2 つのボタンがある 2 つの Figure ウィンドウをもつアプリ作成します。それぞれのボタンに ButtonPushedFcn
コールバックがあり、コールバック実行プロパティの値がそれぞれ異なります。いずれかのボタンをクリックした後、それが完了する前に 2 つ目のボタンをクリックすると、2 つ目のボタンのコールバックが 1 つ目に割り込もうとします。1 つ目のウィンドウのボタンをクリックすると、進行状況ダイアログが表示および更新されます。2 つ目のウィンドウのボタンをクリックすると、データがプロットされます。2 つのボタンの割り込み動作を定義して動作を制御できます。
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
を呼び出して Figure ウィンドウを表示します。
callbackBehavior
ボタンをペアごとにクリックして、Interruptible
プロパティの値と BusyAction
プロパティの値のそれぞれの組み合わせの効果を調べます。
コールバックの割り込み — [Wait (interruptible)] をクリックした後、すぐに 2 つ目のウィンドウのいずれかのボタンをクリックします。[Plot (queue)] または [Plot (cancel)] です。1 つ目のボタンの
Interruptible
の値が'on'
に設定されているため、割り込みが発生します。進行状況ダイアログがまだ実行されている間にプロットが表示されます。コールバックのキューイング — [Wait (not interruptible)] をクリックした後、すぐに [Plot (queue)] をクリックします。1 つ目のボタンの
Interruptible
の値が'off'
に設定され、2 つ目のボタンのBusyAction
の値が'queue'
に設定されているため、キューイングが発生します。進行状況ダイアログが最後まで実行されます。その後にプロットが表示されます。コールバックのキャンセル — [Wait (not interruptible)] をクリックした後、すぐに [Plot (cancel)] をクリックします。1 つ目のボタンの
Interruptible
の値が'off'
に設定され、2 つ目のボタンのBusyAction
の値が'cancel'
に設定されているため、キャンセルが発生します。進行状況ダイアログが最後まで実行されます。しかし MATLAB でプロットのコールバックが破棄されているため、その後、プロットは表示されません。
参考
timer
| drawnow
| waitfor
| uiwait