MATLAB GUI зависает несмотря на использование drawnow и pause

У меня есть MATLAB GUI, который выглядит так, как показано на рисунке: MATLAB GUI image

Я пытаюсь добиться того, чтобы MATLAB постоянно проверял полночь, за исключением пауз, когда пользователь вносит какие-либо изменения в интерфейс. Следовательно, я постоянно запускаю цикл while в фоновом режиме, так как мне нужно проверить, полночь ли это. Если это так, я выполняю некоторые функции. Функция, которая содержит этот цикл while, вызывается после того, как обнаруживается любое изменение пользовательского ввода, то есть в конце всех функций обратного вызова для всплывающих меню, кнопок, текстовых полей и т. Д. Это причина, по которой у меня был drawnow в цикле while, так что, если пользователь вносит какие-либо изменения и хочет выполнить некоторые вычисления, это будет обнаружено. После завершения вычислений я снова вызываю функцию, которая имеет этот цикл while.

Проблема заключается в том, что, хотя я использую drawnow и pause в цикле while, иногда, не всегда, MATLAB все еще зависает на мне, и графический интерфейс перестает отвечать на запросы и не распознает какой-либо пользовательский ввод. Вот часть цикла while моего кода:

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

Я знаю, что приведенный выше код неэффективен, так как он будет непрерывно вызывать post_mortem в полночь, однако сейчас это не моя проблема. Моя проблема в том, что он иногда зависает от меня, например, даже в полдень. У кого-нибудь есть какое-нибудь решение этого? При поиске ответов на предыдущие похожие вопросы решение, похоже, заключалось в том, чтобы использовать drawnow и pause, но, похоже, это тоже не работает для меня.

Любое руководство будет оценено.

Спасибо

1 ответ

Решение

Поскольку MATLAB не является многопоточным, использование while Цикл непрерывной проверки чего-либо (например, времени) будет вызывать всевозможные блокировки других функций. В то время как drawnow а также pause потенциально может помочь с этим, все еще есть некоторые потенциальные проблемы, которые могут возникнуть.

Более элегантный и надежный подход заключается в использовании timer Объект для проверки времени с заданным интервалом. Таким образом, любое взаимодействие пользователя с GUI будет автоматически зарегистрировано, и любые обратные вызовы будут выполняться без необходимости вызова pause или же drawnow,

Вы можете создать и запустить таймер, как только вы создадите графический интерфейс.

% 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
Другие вопросы по тегам