Подтвердить что ты не робот

Matlab: реализация CTRL + C, но в коде

Я хотел бы иметь возможность прекратить выполнение текущих скриптов (функций), вызвав команду в коде. Возврат ограничивает текущую функцию не целым script. Поэтому возврат не тот.

То, что я ищу, - это команда, которая делает именно то, что делает CTRL + C. Я уже видел это: как остановить выполнение и заметил, что никто еще не предоставил правильный ответ на этот вопрос там.

В конечном итоге я хочу завершить все запущенные скрипты после закрытия фигуры:

hFig = figure('CloseRequestFcn',{@closeHandler});

.
.
.
function closeHandler (src,evnt)

    CTRL+C    <--- I am looking for such a command     
end

PS. Ошибка функции() также не будет работать: Попробуйте следующее:

function terminateInCode()

hFig = figure('CloseRequestFcn',{@closeHandler});

while(1)

   plot(10*rand,10*rand,'+');
   pause(0.1);
end;

   function closeHandler (src,evnt)
      delete(hFig);
      error('program terminated!');
   end
end
4b9b3361

Ответ 1

Вот примерная функция с примером, основанным на yuk answer. Компоненты включают:

  • Убедитесь, что окно команды имеет фокус, чтобы получить CTRL + C
  • Используйте таймер для освобождения CTRL + C после того, как произошел разрыв.
  • С помощью робота Java нажмите CTRL + C

Пример функции ниже:

function terminateExecution
%terminateExecution  Emulates CTRL-C
%    terminateExecution   Stops operation of a program by emulating a
%    CTRL-C press by the user.
%
%    Running this function
%
%Example:
%for ix = 1:100
%    disp(ix)
%    if ix>20
%        terminateExecution;
%    end
%end

%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, @releaseCtrl_C)
        releaseTimer = t_all(ix_timer);
    end
    ix_timer = ix_timer+1;
end
if isempty(releaseTimer)
    releaseTimer = timer;
    releaseTimer.TimerFcn = @releaseCtrl_C;
end
releaseTimer.StartDelay = 1;
start(releaseTimer);

%3.2)  Press press CTRL+C
pressCtrl_C

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function releaseCtrl_C(ignore1, ignore2)
    import java.awt.Robot;
    import java.awt.event.*;
    SimKey=Robot;
    SimKey.keyRelease(KeyEvent.VK_CONTROL);
    SimKey.keyRelease(KeyEvent.VK_C);

Ответ 2

Не уверен, что это сработает, просто идея. Как эмулировать нажатие клавиши клавиатуры с MATLAB?

Вы можете попробовать либо java.awd.Robot:

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

или WScript.Shell и SendKeys.

Ответ 3

К сожалению, похоже, это невозможно:

Mathworks

В MATLAB нет возможности программно выпускать Ctrl + C, используя комбинацию клавиш Ctrl + C.

В качестве альтернативы вы можете использовать команду ERROR для принудительной ошибки, которая выйдет из кода. Например:

error('Program terminated for a specific reason')

Ответ 4

Здесь альтернатива, которая использует недокументированные вызовы Matlab для размещения ключевого события непосредственно в окне команд. Способ для этого защищен; это использует отражение, чтобы снять защиту.

В отличие от ответов @yuk и @Persuit у этого, похоже, нет проблем с блокировкой ключа управления. Кроме того, он всегда будет публиковаться непосредственно в командном окне без каких-либо условий гонки или других проблем обеспечения фокуса. И я думаю, что он срабатывает детерминистически - он будет выполняться немедленно.

Одно из предостережений заключается в том, что он использует недокументированный вызов для возврата дескриптора экземпляра окна командной строки. Это немного отличается от выпуска, поскольку оно зависит от компоновки оконной рамы. Некоторые из Yair Altman (undocumentedmatlab.com) работают над обменом файлами, имеют более надежные функции, чтобы захватить это в более общем виде; этот код должен работать с большинством современных выпусков Matlab (протестирован на R2011a, как Mac, так и Win).

function interrupt

import java.awt.event.KeyEvent
import java.util.Calendar
import java.lang.reflection.*

cmdwin = handle(com.mathworks.mde.cmdwin.CmdWin.getInstance().getComponent(0).getComponent(0).getComponent(0),'CallbackProperties');

argSig = javaArray('java.lang.Class',1);
argSig(1) = java.lang.Class.forName('java.awt.event.KeyEvent');
method = cmdwin.getClass().getDeclaredMethod('processKeyEvent',argSig);
method.setAccessible(true);

cal = Calendar.getInstance();
args = javaArray('java.lang.Object',1);
args(1) = KeyEvent(cmdwin,KeyEvent.KEY_PRESSED,cal.getTime().getTime(),KeyEvent.CTRL_DOWN_MASK,KeyEvent.VK_C,KeyEvent.CHAR_UNDEFINED);
method.invoke(cmdwin,args);

Ответ 5

Вы можете использовать функцию error. Вы вернетесь в Matlab.

Это приведет к ошибке, но это также происходит, когда вы нажимаете CTRL+C, в matlab script.

Вам следует добавить какое-то сообщение типа error('Interrupted by user');

Ответ 6

Это не совсем то, о чем вы просите, но, учитывая ваш пример, ваша проблема может быть решена следующим образом:

function terminateInCode()

hFig = figure('CloseRequestFcn',{@closeHandler});

stop=0;
while(~stop)
   plot(10*rand,10*rand,'+');
   pause(0.1);
end;

   function closeHandler (src,evnt)
      delete(hFig);
      stop=1;
   end
end

Ответ 7

Попробуйте оператор return. Это вытолкнет вас из функции.

Если вы хотите полностью его закончить, вам нужно использовать ERROR.

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