Cbas
Cbas

Reputation: 6213

MATLAB GUI stop button issues

EDIT: I rephrased my question a bit, because I have a better understanding of the problem now and there was a lot of unnecessary info in the first draft.

I am creating a standalone MATLAB application, which needs a toggle button that can initiate and stop a looping script.

Based on this helpful video, I was able to implement this idea like this in my gui.m file:

function startBtn_Callback(hObject, eventdata, handles)

    if get(handles.startBtn,'Value')
        set(handles.startBtn,'String','Stop Recording');
    else
        set(handles.startBtn,'String','Start Recording');
    end

    while get(handles.startBtn,'Value');
        disp('looping..');
        pause(.5);
    end

This script works as expected, but when I replace the contents of the while loop the function I would like to loop, the button stops working. It still toggles when I push it, but the callback only gets called the first time the button is pushed. Here is what my final code looks like:

function startBtn_Callback(hObject, eventdata, handles)

    if get(handles.startBtn,'Value')
        set(handles.startBtn,'String','Stop Recording');
        pause(.1);
    else
        set(handles.startBtn,'String','Start Recording');
        disp('Recording Stopped')
    end

    while get(handles.startBtn,'Value');
        myFunction();
    end

When I push the start button, this callback runs and the loop starts. The pause(.1) is needed to get the text to change - if I don't include a pause, the loop initiates, but the text on the button does not change.

After this, no subsequent button pushes do anything. The button toggles on the GUI, but startBtn_Callback never gets called and the loop runs indefinitely. This is a problem because my end user will not have access to the MATLAB console.

To give a bit more information about my function: its a method that records audio for 5 seconds, does some processing, then outputs some graphs. I want this loop to repeat indefinitely until the user pushes stop.

I think that the issue is that MATLAB seems to only be able to run one function at a time, so when myFunction() is running, the callback can't be initiated. The reason it worked in the first example is because there was a pause between loop calls. I can't have this pause, because a requirement of the project is to record every possible second.

How can I make a reliable stop button for this process?

I am running MATLAB R2012b 32-bit.

Upvotes: 1

Views: 5167

Answers (2)

Cbas
Cbas

Reputation: 6213

drawnow() is the function I was looking for. Putting that after myFunction() forces Matlab to handle any stacked up GUI calls before proceeding with the loop.

This code creates a reliable start/stop toggle button for an indefinite and continuous process:

function startBtn_Callback(hObject, eventdata, handles)

  if get(handles.startBtn,'Value')
      set(handles.startBtn,'String','Stop');
      drawnow();
  else
      set(handles.startBtn,'String','Start');
  end
  while get(handles.startBtn,'Value');
      myFunction();
      drawnow()
  end

Upvotes: 0

Jonas
Jonas

Reputation: 74940

In your code snippet

a=get(handles.startBtn,'Value')
while a
    myFunction();
end

the value of a is assigned once, and never changes afterward. Thus, the while-loop will either never run, or it will loop forever.

while get(handles.startBtn,'Value')
    myFunction();
end

will query the value of the button at every iteration, however, especially if myFunction doesn't take very long to execute, there will be lots and lots of java requests that may make your GUI sluggish.

This is why the example you followed uses the pause line, so that the loop only executes every .5 seconds or so.

If you don't want to have the query in the while-line, you can alternatively write

%# read inital value of a
a=get(handles.startBtn,'Value');
while a
    myFunction();
    %# update a
    a=get(handles.startBtn,'Value');
end

Upvotes: 2

Related Questions