matlabmatlab-guidefreezepausedrawnow

MATLAB GUI hangs up despite using drawnow and pause


I have a MATLAB GUI that looks as shown in: MATLAB GUI image

What I am trying to achieve is that MATLAB keep checking for midnight continuously, except for the pauses when the user makes any change to the interface. Hence, I am running a while loop in the background continuously as I need to check if it is midnight. If it is, I perform some functions. The function that contains this while loop is called after any user input change is detected i.e. at the end of all the callback functions for the pop-up menus,pushbuttons, textboxes etc. This is the reason I had the drawnow in the while loop, so that if the user makes any changes and wants to run some calculations, that will be detected. After the completion of the calculations, I again call the function which has this while loop.

The issue is, even though I use drawnow and pause in my while loop, sometimes, not always, MATLAB still hangs-up on me and the GUI becomes unresponsive and does not recognize any of the user inputs. Here is the while loop part of my code:

while 1
    pause(0.1);
    drawnow;
    pause(0.1);
    current_time=clock;
    if current_time(4)==0
        post_mortem;
    end
end

I know the above code is not efficient as it will call post_mortem continuously in the midnight hour, that however is not my issue right now. My issue is that it hangs up on me at times even at noon for example. Does anybody have any solution to this? On searching for answers to previous similar questions, the solution seemed to be to use drawnow and pause, but that doesn't seem to be working for me either.

Any guidance would be appreciated.

Thank you


Solution

  • Since MATLAB is not multi-threaded, using a while loop to continuously check something (such as the time) is going to cause all sorts of blocking of other functionality. While drawnow and pause can potentially help with this, there are still some potential issues that can crop up.

    A more elegant and reliable approach would be to use a timer object to check the time at a pre-specified interval. This way, any user interaction with the GUI will automatically be registered and any callbacks will execute without you having to call either pause or drawnow.

    You can create and start the timer as soon as you create your GUI.

    % Create the timer object
    handles.mytimer = timer('ExecutionMode', 'FixedRate', ...
                            'Period', 1/5, ...
                            'BusyMode', 'drop', ...
                            'TimerFcn', @(s,e)timerCallback());
    
    % Start the timer
    start(handles.mytimer)
    
    function timerCallback()
        % Callback that executes every time the timer ticks
    
        current_time = clock;
        if current_time(4) == 0
            post_mortem;
        end
    end