Interrupt Callback Execution

Control Callback Execution and Interruption

Callback execution is event driven and callbacks from different GUIs share the same event queue. In general, callbacks are triggered by user events such as a mouse click or key press. When a callback initiates, under this event model you cannot know whether another callback is executing. If a callback is executing, your code cannot tell which callback that is.

If a callback is executing and the user triggers an event for which a callback is defined, that callback attempts to interrupt the callback that is already executing. When this occurs, MATLAB® software processes the callbacks according to the values of two properties:

  • The Interruptible property of the object whose callback is already executing. The Interruptible property specifies whether the executing callback can be interrupted. The default value for uicontrol objects is 'on', allowing interruption.

  • The BusyAction property of the object whose callback has just been triggered and is about to execute. The BusyAction property specifies whether to queue the callback to await execution or cancel the callback. The default property value is 'queue'.

Order of Callback Execution

Interacting with figures and graphic objects can trigger a variety of callbacks. More than one callback can execute in response to a given user action, such as a button or key press. In particular, figure window callbacks can respond to some of the same events as uicontrol, uipanel, and uitable callbacks. In most cases, the callbacks execute in a well-defined order. Some applications need to attend to the order of execution in order to respond to user gestures appropriately and consistently, especially when several callbacks are triggered by the same gesture. The following list indicates the normal order of execution of callbacks in response to mouse button presses and movements in figures and graphic objects:

  1. Figure WindowButtonMotionFcn (mouse button can be up or down; no similar callback exists for objects)

  2. Figure WindowButtonDownFcn

  3. Figure ButtonDownFcn

  4. Object Callback (if Enable is on for object)

  5. Object ButtonDownFcn (if Enable is off for object)

  6. Figure WindowButtonUpFcn (no similar callbacks exist)

A different set of callbacks exist to respond to keyboard events. Almost all keyboard callbacks belong to figure windows. The following list indicates the normal order of execution of callbacks in response to keyboard events in figure windows and graphic objects:

  1. WindowKeyPressFcn (in figure window or any of its child objects)

  2. KeyPressFcn (figure window callback)

  3. KeyPressFcn (uicontrol and uitable callback)

  4. KeyReleaseFcn (in figure window only)

  5. WindowKeyReleaseFcn (in figure window or any of its child objects)

How the Interruptible Property Works

You can set an object's Interruptible property to either on (the default) or off.

If the Interruptible property of the object whose callback is executing is on, the callback can be interrupted. However, it is interrupted only when it, or a function it triggers, calls drawnow, figure, getframe, pause, or waitfor. Before performing their defined tasks, these functions process any events in the event queue, including any waiting callbacks. If the executing callback, or a function it triggers, calls none of these functions, it cannot be interrupted regardless of the value of its object's Interruptible property.

If the Interruptible property of an object is set to 'off', then that object's callback cannot be interrupted, unless both of the following items are true:

  • The callback calls drawnow, figure, getframe, pause, or waitfor.

  • The interrupting callback is a DeleteFcn, CloseRequestFcn, or SizeChangedFcn callback.

MATLAB resumes the executing the running callback when the interrupting callback completes.

The callback properties to which Interruptible can apply depend on the objects for which the callback properties are defined:

  • For figures, the Interruptible property only affects callback routines defined for these properties:

    • ButtonDownFcn

    • KeyPressFcn

    • KeyReleaseFcn

    • WindowButtonDownFcn

    • WindowButtonMotionFcn

    • WindowButtonUpFcn

    • WindowScrollWheelFcn

    For callbacks that execute continuously, setting the figure's Interruptible property to 'off' might be necessary if callbacks from other objects or GUIs could fire while such interactions are occurring. The rationale is, do not interrupt callbacks that continuously execute unless there is a specific reason to do so.

  • For GUI components, Interruptible applies to these properties (for components that have these properties):

    • ButtonDownFcn

    • Callback

    • CellSelectionCallback

    • KeyPressFcn

    • SelectionChangedFcn

    • ClickedCallback

    • OffCallback

    • OnCallback

To prevent an object's callback from being interrupted repeatedly, set the value of that object's Interruptible property to 'off':

h.Interruptible = 'off';

How the Busy Action Property Works

You can set an object's BusyAction property to either queue (the default) or cancel. The BusyAction property of the interrupting callback's object is taken into account only if the Interruptible property of the executing callback's object is off, i.e., the executing callback is not interruptible.

If a noninterruptible callback is executing and an event (such as a mouse click) triggers a new callback, MATLAB software examines the value of the BusyAction property of the object that generated the new callback:

  • If the BusyAction value is 'queue', the requested callback is added to the event queue and executes in its turn when the executing callback finishes execution.

  • If the value is 'cancel', the event is discarded and the requested callback does not execute.

If an interruptible callback is executing, the requested callback runs when the executing callback terminates or calls drawnow, figure, getframe, pause, or waitfor. The BusyAction property of the requested callback's object has no effect.

Example

This example demonstrates control of callback interruption using the Interruptible and BusyAction properties. It creates two GUIs:

  • The first GUI contains two push buttons:

    • Wait (interruptible) whose Interruptible property is on

    • Wait (noninterruptible) whose Interruptible property is off

    Clicking either button triggers the button's Callback callback, which creates and updates a waitbar.

    This code creates the two Wait buttons and specifies the callbacks that service them.

    h_interrupt = uicontrol(h_panel1,'Style','pushbutton',...
                            'Position',[30,110,120,30],...
                            'String','Wait (interruptible)',...
                            'Interruptible','on',...
                            'Callback',@wait_interruptible);
    h_noninterrupt = uicontrol(h_panel1,'Style','pushbutton',...
                            'Position',[30,40,120,30],...
                            'String','Wait (noninterruptible)',...
                            'Interruptible','off',...
                            'Callback',@wait_noninterruptible);
  • The second GUI contains two push buttons:

    • Surf Plot (queue) whose BusyAction property is queue

    • Mesh Plot (cancel) whose BusyAction property is cancel

    Clicking either button triggers the button's Callback callback to generate a plot in the axes.

    This code creates the two plot buttons and specifies the callbacks that service them.

    hsurf_queue = uicontrol(h_panel2,'Style','pushbutton',...
                            'Position',[30,200,110,30],...
                            'String','Surf Plot (queue)',...
                            'TooltipString','BusyAction = queue',...
                            'BusyAction','queue',...
                            'Callback',@surf_queue);
    hmesh_cancel = uicontrol(h_panel2,'Style','pushbutton',...
                            'Position',[30,130,110,30],...
                            'String','Mesh Plot (cancel)',...
                            'BusyAction','cancel',...
                            'TooltipString','BusyAction = cancel',...
                            'Callback',@mesh_cancel);

Using the Example GUIs.  Click hereClick here to run the example GUIs.

    Note   This link executes MATLAB commands and is designed to work within the MATLAB Help browser. If you are reading this online or in a PDF, go to the corresponding section in the MATLAB Help Browser to use the link.

To see the interplay of the Interruptible and BusyAction properties:

  1. Click one of the Wait buttons in the first GUI. Both buttons create and update a waitbar.

  2. While the waitbar is active, click either the Surf Plot or the Mesh Plot button in the second GUI. The Surf Plot button creates a surf plot using peaks data. The Mesh Plot button creates a mesh plot using the same data.

The following topics describe what happens when you click specific combinations of buttons:

Click a Wait Button.  

The Wait buttons are the same except for their Interruptible properties. Their Callback callbacks, which are essentially the same, call the utility function create_update_waitbar which calls waitbar to create and update a waitbar. The Wait (Interruptible) button Callback callback, wait_interruptible, can be interrupted each time waitbar calls drawnow. The Wait (Noninterruptible) button Callback callback, wait_noninterruptible, cannot be interrupted (except by specific callbacks listed in How the Interruptible Property Works).

This is the Wait (Interruptible) button Callback callback, wait_interruptible:

    function wait_interruptible(hObject,eventdata)
        % Disable the other push button.
        h_noninterrupt.Enable = 'off';
        % Clear the axes in the other GUI.
        cla(h_axes2,'reset')
        % Create and update the waitbar.
        create_update_waitbar
        % Enable the other push button
        h_noninterrupt.Enable = 'on';
    end

The callback first disables the other push button and clears the axes in the second GUI. It then calls the utility function create_update_waitbar to create and update a waitbar. When create_update_waitbar returns, it enables the other button.

Click a Plot Button.  

What happens when you click a Plot button depends on which Wait button you clicked first and the BusyAction property of the Plot button.

  • If you click Surf Plot, whose BusyAction property is queue, MATLAB software queues the Surf Plot callback surf_queue.

    If you clicked the Wait (interruptible) button first, surf_queue runs and displays the surf plot when the waitbar issues a call to drawnow, terminates, or is destroyed.

    If you clicked the Wait (noninterruptible) button first, surf_queue runs only when the waitbar terminates or is destroyed.

    This is the surf_queue callback:

    function surf_queue(hObject,eventdata)
            h_plot = surf(h_axes2,peaks_data);
        end
  • If you click Mesh Plot , whose BusyAction property is cancel, after having clicked Wait (noninterruptible), MATLAB software discards the button click event and does not queue the mesh_cancel callback.

    If you click Mesh Plot after having clicked Wait (interruptible), the Mesh Plot BusyAction property has no effect. MATLAB software queues the Mesh Plot callback, mesh_cancel. It runs and displays the mesh plot when the waitbar issues a call to drawnow, terminates, or is destroyed.

    This is the mesh_plot callback:

    function mesh_cancel(hObject,eventdata)
            h_plot = surf(h_axes2,peaks_data);
        end

View the Complete GUI Code File.  If you are reading this in the MATLAB Help browser, click hereclick here to display a complete listing of the code used in this example in the MATLAB Editor.

    Note   This link executes MATLAB commands and is designed to work within the MATLAB Help browser. If you are reading this online or in a PDF, go to the corresponding section in the MATLAB Help Browser to use the links.

Control Program Execution Using Timer Objects

If you create a GUI that performs regularly scheduled tasks, such as acquiring data, updating a display, polling devices or services, or autosaving results, you can manage the activity with timers. Timers are MATLAB objects that time execution of functions and programs. Timers have properties that you can customize for your application. For example, you can make them execute once or repeatedly, wait before running, and handle delays in execution. The following callbacks are among these properties.

Callback PropertyDescriptionExamples of Use
StartFcnFunction the timer calls when it startsOpen an input file or output file, or initialize variables.
TimerFcnTimer callback function that triggers actions that the timer controlsAcquire new data or flush old data, or update a display.
StopFcnFunction the timer calls when it stopsClose input or output files, or compute statistics for session.
ErrorFcnFunction that the timer executes when an error occurs (this function executes before the StopFcn.).Called when a timeout occurs. You can specify conditions under which this can happen.

You can include any of these callbacks in your GUI code file. Your code also needs to create and configure the timer object when your GUI opens, and delete the timer before your GUI closes. To start a timer, call its start method. The timer executes its StartFcn, begins counting, and executes its first TimerFcn callback when the period specified by the StartDelay property expires. To halt a timer, call its stop method.

    Caution   Timers are independent objects that operate asynchronously, as do GUIs. A timer callback can change or even delete data used by your GUI code or code it calls. It can also fail to execute due to timing out. If such possibilities exist for your application, your code must guard against them. For example, it can test whether a variable continues to exist, or place code that can fail within try/catch blocks

For an example of a GUI that uses a timer, see Automatically Refresh Plot in a GUIDE GUI. For more information about setting up timers and controlling their run-time characteristics, see Use a MATLAB Timer Object and the timer reference page.

Was this topic helpful?