Main Content

コールバック実行への割り込み

MATLAB® では、コールバック関数の実行中に割り込みを許可するかどうかを制御できます。割り込みを許可するかどうかは状況によって異なります。たとえば、ユーザーがアニメーションのループを停止できるようにするには、アニメーションに割り込むコールバックを作成します。一方で、実行するコールバックの順序が重要な場合は、割り込みが発生しないようにする必要があります。たとえば、アプリの応答性を高めるために、ポインターの動きに応答するコールバックの割り込みを禁止する場合があります。

コールバックの割り込み時の動作

コールバック関数は、キュー内での順序に従って実行されます。コールバックの実行中にユーザーのアクションによって 2 番目のコールバックがトリガーされると、2 番目のコールバックは最初のコールバックに割り込もうとします。最初のコールバックは "実行中コールバック" です。2 番目のコールバックは "割り込みコールバック" です。

MATLAB では、実行中コールバックで一部のコマンドが発生するとコールバック キューの残りを処理します。MATLAB は、それらのコマンドのいずれかが実行されるたびにコールバックの割り込み動作を判別します。これらのコマンドには、drawnowfigureuifiguregetframewaitforpause が含まれます。

実行中コールバックにこれらのコマンドが含まれていない場合、割り込みは発生しません。MATLAB は、実行中コールバックの実行を先に終了させ、その後に割り込みコールバックを実行します。

実行中コールバックにこれらのいずれかのコマンドが含まれている場合、実行中コールバックを所有するオブジェクトの Interruptible プロパティに応じて割り込みが発生するかどうかが決まります。

  • Interruptible の値が 'on' の場合、割り込みが発生します。MATLAB は、コールバック キューの処理時に、実行中コールバックの実行を一時停止し、割り込みコールバックを実行します。割り込みコールバックが完了した後、MATLAB は実行中だったコールバックの実行を再開します。

  • Interruptible の値が 'off' の場合、割り込みは発生しません。代わりに、割り込みコールバックの BusyAction プロパティに応じて、MATLAB による割り込みコールバックの処理が決まります。

    • BusyAction の値が 'queue' の場合、MATLAB は実行中コールバックの終了後に割り込みコールバックを実行します。

    • BusyAction の値が 'cancel' の場合、MATLAB は割り込みコールバックを破棄します。

Interruptible の既定値は 'on'BusyAction の既定値は 'queue' です。

最後に、割り込みコールバックが DeleteFcnCloseRequestFcn、または SizeChangedFcn のいずれかのコールバックの場合、Interruptible プロパティの値に関係なく割り込みが発生します。

コールバックの割り込み動作の制御

この例では、コンポーネントの InterruptibleBusyAction のプロパティに応じて、コールバックの割り込み動作がどのように変わるかを示します。

現在のフォルダーに 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 でプロットのコールバックが破棄されているため、その後、プロットは表示されません。

参考

| | |

関連するトピック