24 Mar 2023

Matlab: Terminate Execution by emulating CTRL+C

收藏到CSDN网摘

This is a really usful trick for GUI development in Matlab. Although Matlab has some advanced methods such as Future object to run the process in background. But a simple method to mimic what the user does by pressing CTRL+C would be nice to have! Credit goes to: https://stackoverflow.com/a/10097294/1300650 This trick has bee tested in Matlab 2020a App designer. The bad news is that the use of 'com.mathworks' would be deprecated in a future version of Matlab - and there would be NO alternatives! The whole process would be: 1. get matlab session 2. transfer focus to command windows 3. import java robot to press CTRL+C for 2 or 3 times (could be more as it won't hurt!) Working code:
function terminateTraining(~)
    % stop operation by emulates CTRL-C in command window

    %1) request focus be transferred to the command window
    %   (H/T http://undocumentedmatlab.com/blog/changing-matlab-command-window-colors/)
    cmdWindow = com.mathworks.mde.cmdwin.CmdWin.getInstance();
    cmdWindow.grabFocus();

    %2) Wait for focus transfer to complete (up to 2 seconds)
    focustransferTimer = tic;
    while ~cmdWindow.isFocusOwner
        pause(0.1);  % Pause some small interval
        if (toc(focustransferTimer) > 2)
            error('Error transferring focus for CTRL+C press.')
        end
    end

    %3) Use Java robot to execute a CTRL+C in the (now focused) command window.

    %3.1)  Setup a timer to relase CTRL + C in 1 second
    %  Try to reuse an existing timer if possible (this would be a holdover
    %  from a previous execution)
    t_all = timerfindall;
    releaseTimer = [];
    ix_timer = 1;
    while isempty(releaseTimer) && (ix_timer <= length(t_all))
        if isequal(t_all(ix_timer).TimerFcn, @app.releaseCtrl_C)
            releaseTimer = t_all(ix_timer);
        end
        ix_timer = ix_timer+1;
    end
    if isempty(releaseTimer)
        releaseTimer = timer;
        releaseTimer.TimerFcn = @app.releaseCtrl_C;
    end
    releaseTimer.StartDelay = 1;
    start(releaseTimer);

    %3.2)  Press press CTRL+C for 3 times
    app.pressCtrl_C();
    app.pressCtrl_C();
    app.pressCtrl_C();
end

function pressCtrl_C(~)
    import java.awt.Robot;
    import java.awt.event.*;
    SimKey = Robot;
    SimKey.keyPress(KeyEvent.VK_CONTROL);
    SimKey.keyPress(KeyEvent.VK_C);
end

function releaseCtrl_C(~)
    import java.awt.Robot;
    import java.awt.event.*;
    SimKey = Robot;
    SimKey.keyRelease(KeyEvent.VK_CONTROL);
    SimKey.keyRelease(KeyEvent.VK_C);
end

No comments :

Post a Comment