Matlab: implementando lo que CTRL + C hace, pero en el código

Me gustaría poder finalizar mis secuencias de comandos actuales (funciones) llamando a un comando en el código. El retorno solo terminaría la función actual, no toda la secuencia de comandos. Por lo tanto, el retorno no es el elegido.

Lo que estoy buscando es un comando que haga exactamente lo que CTRL + C hace. Ya he visto esto: cómo detener la ejecución y noté que nadie ha proporcionado una respuesta adecuada para esta pregunta tampoco.

en última instancia, quiero terminar todas las secuencias de comandos en ejecución al cerrar una figura :

hFig = figure('CloseRequestFcn',{@closeHandler}); . . . function closeHandler (src,evnt) CTRL+C <--- I am looking for such a command end 

PD. el error de función () tampoco funcionará: prueba esto:

 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 

Aquí hay una función de ejemplo con un ejemplo basado en la respuesta de yuk . Los componentes incluyen:

  • Asegúrese de que la ventana de comandos tenga foco para recibir el CTRL + C
  • Use un temporizador para liberar CTRL + C después de que se haya producido la ruptura
  • Use un robot Java para presionar CTRL + C

La función de muestra está a continuación:

 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); 

No estoy seguro de que funcione, solo una idea. ¿Qué tal emular la pulsación de tecla del teclado de MATLAB?

Puedes probar java.awd.Robot :

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

o WScript.Shell y SendKeys .

Lamentablemente, parece que no se puede hacer:

Mathworks

No hay forma de emitir programáticamente Ctrl + C en MATLAB además de usar la combinación Ctrl + C del teclado.

Como alternativa, puede usar el comando ERROR para forzar un error que saldrá del código. Por ejemplo:

 error('Program terminated for a specific reason') 

Aquí hay una alternativa que utiliza llamadas de Matlab no documentadas para colocar el evento clave directamente en la ventana de comandos. El método para hacerlo está protegido; esto usa la reflexión para desprotegerlo.

A diferencia de las respuestas de @yuk y @ Persuit, esto no parece tener problemas con la retención de la clave de control. Además, siempre se publicará directamente en la ventana de comandos sin condiciones de carrera u otros problemas para garantizar el enfoque. Y, creo que se dispara de manera determinista, se ejecutará de inmediato.

La única advertencia es que utiliza una llamada no documentada para recuperar el control de la instancia de la ventana de comandos. Esto varía ligeramente según la versión, ya que depende del diseño del marco de la ventana. Algunos de los trabajos de Yair Altman (undocumentedmatlab.com) en el intercambio de archivos tienen funciones más robustas para captar esto de una manera más general; este código debería funcionar con la mayoría de las versiones modernas de Matlab (Probado en R2011a, Mac y 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); 

Puede usar el error función. Regresarás a Matlab.

Producirá un error, pero eso también es lo que generalmente sucede cuando presiona CTRL+C , en un script de matlab.

Debe agregar algún tipo de mensaje como error('Interrupted by user');

No es exactamente lo que está pidiendo, pero teniendo en cuenta su ejemplo, su problema puede resolverse así:

 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 

Pruebe la statement de devolución. Te sacará de una función.

Si quiere terminarlo por completo, necesita usar ERROR.

Siempre puedes usar EXIT si es realmente tan desastroso.