0

Does anyone know of a cleaner solution for the following: I'm running a matlab script that might need to be killed at some point. Hitting "cntrl-C" works but pops open some random file in debug, and might still fail depending on if the figures are in the middle of drawing.

Best I could come up with: add a button to the figure I'm looking at, on mouse-click do "clear all". Simply doing "error" doesn't work because it throws an exception that some matlab function successfully catches and continues running.

Update / Clarification: the force-crash relies on clearing some global variable in the main script.

function  myScript()
global foo;
foo = 1;
while 1

x = DoStuff();
sh = figure(1);
if k == 1
  killable_window( sh );
end
x.display();
drawnow;
y = foo + 1; % <-- crashes if the callback does 'clear all', which kills global variable foo
end


end

Then this is the dirty version of a killable window:

function [] = killable_window( sh )
  S.fh = sh;
  S.pb = uicontrol('style','push',...
                 'units','pix',...
                 'position',[10 30 80 20],...
                 'fontsize',12,...
                 'string','Quit');          

set(S.pb,'callback'   ,{@pb_call,S})
% Check if 'p' is pressed when focus on button and exec callback
set(S.pb,'KeyPressFcn',{@pb_kpf ,S});

% Check if 'p' is pressed when focus on figure and exec callback
set(S.fh,'KeyPressFcn',{@pb_kpf ,S});

% Callback for pushbutton, clears all variables
function pb_call(varargin)
  S = varargin{3};  % Get the structure.

  fprintf('force quitting due to button press...\n');

  % ghetto: clear everything to force a crash later
  % and prevent anyone from successfully catching an exception
  clear all;
end

% Do same action as button when pressed 'p'
function pb_kpf(varargin)
  if varargin{1,2}.Character == 'p'
      pb_call(varargin{:})
  end
end
end

so, if I don't like what I see, I hit the "quit" button, and it dumps back to home screen, but I lose my variables in the process... is there a way to quit, or make "error" prevent anyone from catching the exceptions ?

dsolimano
  • 8,870
  • 3
  • 48
  • 63
peter karasev
  • 2,578
  • 1
  • 28
  • 38
  • 2
    It seems like bad practice to rely on crashing a script or function as part of your works flow. If you know what you are trying to do, why not write to code to do that? Instead of forcing it to crash if you want to prematurely exit? There may be some way to do what you are trying to do, but when I see this question I can't help but think there is a better way to architect the code. – Miebster Mar 03 '11 at 15:23
  • right, well I just want it to be a general-purpose method. Of course the above could just set a particular variable, that is checked in the loop. But I want the "killable window" function to be independent of any details in the caller code, if possible. Remember the alternative is hitting 'cntrl-C' and crashing in a potentially worse way than above. – peter karasev Mar 04 '11 at 21:14

1 Answers1

0

Perhaps the following might help you organize your code within a GUIDE application. I have used application data (see the appdata docs here or the general docs here) to create a execution flag runflag. Once the start button is pressed the main loop is entered within the button's callback. The loop terminates when the stop button is pressed setting which sets the flag in the figures application data to FALSE.

Here are steps I used to set this up.

  1. Start by creating a new GUIDE application,
  2. add two buttons (Start and Stop) and
  3. define the following callbacks

Opening Function Callback

%# --- Executes just before testStop is made visible.
function testStop_OpeningFcn(hObject, eventdata, handles, varargin)

%# Choose default command line output 
handles.output = hObject;

%# Add a global variable as a MATLAB application data 
%# see sharing application data  documentation in the MATLAB
%# docs 
%# APPDATA documentation:
%#    http://www.mathworks.com/help/techdoc/creating_guis/f13-998352.html#f13-999565
%# General doc on sharing application data
%#    http://www.mathworks.com/help/techdoc/creating_guis/f13-998449.html
%# 
setappdata(handles.figure1,'runFlag',true);

%# Update handles structure
guidata(hObject, handles);

Start button call back

%# --- Executes on button press in btnGo.
function btnGo_Callback(hObject, eventdata, handles)
i=0;

%# This loop will stop when the stop button is pressed
%# setting the application data _runFlag_ to false
while  getappdata(handles.figure1,'runFlag')
    i=i+1;
    %# Work you want to inturrupt can go here.
    pause(.1)
end

Stop Button Callback

%# --- Executes on button press in btnStop.
function btnStop_Callback(hObject, eventdata, handles)            
setappdata(handles.figure1,'runFlag',false)
Azim J
  • 8,260
  • 7
  • 38
  • 61
  • Interesting, I guess one could simply pass a function pointer here to some script and run it in the "%# Work you want to inturrupt can go here." block ... – peter karasev Mar 04 '11 at 21:16
  • @peter: I'm sure that could work or you could have the stop button set the value of a global variable and you any loop you wanted interrupted could check the global variable on each interations. It looks like you get the basic idea anyway. – Azim J Mar 04 '11 at 23:39