当前位置: 动力学知识库 > 问答 > 编程问答 >

toggle button in Gui Matlab

问题描述:

I want to create a button which work as on/off switch: If the user pushes it, it starts counting and displays the counter on a static text. If the user pushes it again, it stops counting. Then, if the user pushes it for a third time, it continues counting.

I tried this code

function startStop_togglebutton_Callback(hObject, eventdata, handles)

% hObject handle to startStop_togglebutton (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of startStop_togglebutton

persistent counter ;

if isempty(counter)

counter = 0 ;

end

button_state = get(hObject,'Value');

if button_state == get(hObject,'Max')

set(handles.startStop_togglebutton,'String','Stop','ForegroundColor','red')

setappdata(handles.startStop_togglebutton,'sw',1)

while counter < 10

counter = counter+1;

set(handles.statusBar,'String',strcat(['the counter = ' num2str(counter) ]))

pause(1)

end

set(handles.startStop_togglebutton,'String','Finished','ForegroundColor','cyan')

elseif button_state == get(hobject,'min')

set(handles.startstop_togglebutton,'string','resume','foregroundcolor','blue')

setappdata(handles.startstop_togglebutton,'sw',0)

set(handles.statusBar,'String',strcat([' stopped & the counter = ' num2str(counter) ' !']))

end

but it doesn't work correctly: When I push the button for the first time, it starts counting and when I pushed it a second, time it's name changed but it was still counting.

网友答案:

In your present implementation of the counter, the while loop in the startStop_togglebutton callback is activated the first time you press the pushbuttonn to Start counting.

It keeps running until the condition (counter < 10) holds even if you press again the ushbutton to Stop the counting.

Therefore, to fix the problem you can use the value of the startStop_togglebutton insted of "1" to increment the counter.

Below, you can find the updated version of the callback. I've also added a couple of "if" blocks to manage the displaying of the strings in the statusbar

% --- Executes on button press in startStop_togglebutton.
function startStop_togglebutton_Callback(hObject, eventdata, handles)
% hObject    handle to startStop_togglebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of startStop_togglebutton

% hObject    handle to startStop_togglebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of startStop_togglebutton

persistent counter ;

if isempty(counter)

    counter = 0 ;

end

button_state = get(hObject,'Value');

if button_state == get(hObject,'Max')

    set(handles.startStop_togglebutton,'String','Stop','ForegroundColor','red')

    setappdata(handles.startStop_togglebutton,'sw',1)

    while counter < 10
%
% Inserted acquisition of button state within the while loop
%
       button_state = get(hObject,'Value');
%
% Modified the counter increment:
%    the increment is based on the status of the button
%
%        counter = counter+1;
       counter = counter+button_state;
%
% Added "if" condition
%    The "statusbar" is updated only if counting is on
%
       if(button_state)
           set(handles.statusBar,'String',strcat(['the counter = ' num2str(counter) ]))
       end

       pause(1)
    end

%
% Added "if" condition
%    The "statusbar" is updatred only if counting is finished
%
if(counter == 10)
    set(handles.startStop_togglebutton,'String','Finished','ForegroundColor','cyan')
end

elseif button_state == get(hObject,'min')

    set(handles.startStop_togglebutton,'string','resume','foregroundcolor','blue')

    setappdata(handles.startStop_togglebutton,'sw',0)
    set(handles.statusBar,'String',strcat([' stopped & the counter = ' num2str(counter) ' !']))

end

UPDATING TO ANSWER TO THE COMMENT

The reason for using the value of the togglebutton to increment the counter is the following.

The first time you push the togglebutton to start the counter, the while loop is activated and the GUI is "waiting" for another callback regardless the loop is completed.

Moreover the while loop has been coded into the if block that catches the Start / Continue action.

This implies that when you push the togglebutton to stop the counter, the while loop is skipped.

Getting the value of the togglebutton in the while loop allows to catch the change of the status of the button independently of the intended action (Stop / Restart).

Indeed, when you push it to Stop the counter, the value is set to 0 so it does not increment the counter while when you push it to restart, its value is set to 1 and the counter is incremented.

I suggest to model the counter GUI in a different way:

  • To code the counter in a separate ".m" file (or in a function)
  • To code in this ".m" file the logic for the increment of the counter (based on the value of the togglebutton)
  • To add a pushbutton which run the counter (the ".m" file)
  • To use the startStop_togglebutton callbach only to update the string displayed on the togglebutton

The handling of the data between the GUI and the ".m" file is done by using the guidata function.

The ".m". files identifies the GUI through its tag (in the code I've used to test the solution I've set the GUI figure tag as counter_gui).

You should also set the property HandleVisibility of your GUI to 'on'

In the following you can find:

  • the updated startStop_togglebutton callback, now very simple
  • the callback of the pushbutton used to start the counter
  • the ".m" file chich manages the counter

startStop_togglebutton Callback

% --- Executes on button press in startStop_togglebutton.
function startStop_togglebutton_Callback(hObject, eventdata, handles)
% hObject    handle to startStop_togglebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of startStop_togglebutton

% hObject    handle to startStop_togglebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of startStop_togglebutton

button_state = get(hObject,'Value');

if(button_state == 1)
   set(handles.startStop_togglebutton,'String','Stop','ForegroundColor','red')
else
    set(handles.startStop_togglebutton,'string','resume','foregroundcolor','blue')
end

run_counter callback

% --- Executes on button press in run_counter.
function run_counter_Callback(hObject, eventdata, handles)
% hObject    handle to run_counter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

set(handles.startStop_togglebutton,'enable','on');
set(handles.startStop_togglebutton,'Value',1);
set(handles.run_counter,'enable','off');
% Run the counter ".m" file
run_counter;

".m" file managing the counter

% Get tha handle of the GUI figure
gui_h=findobj('tag','counter_gui');
% Get gudata
gui_my_data=guidata(gui_h);

counter=0;
while(counter < 10)
   % Get togglebutton value
   button_status=get(gui_my_data.startStop_togglebutton,'value');
   % Increment to counter only if the togglebutton is set to "Start/Resume"
   counter=counter+button_status;
   % Update strings
   if(button_status)
      set(gui_my_data.startStop_togglebutton,'String','Stop','ForegroundColor','red')
      set(gui_my_data.statusBar,'String',strcat(['the counter = ' num2str(counter) ]))
   else
      set(gui_my_data.statusBar,'String',strcat([' stopped & the counter = ' num2str(counter) ' !']))
   end
   pause(1);
end

set(gui_my_data.startStop_togglebutton,'String','Finished','ForegroundColor','cyan')
set(gui_my_data.startStop_togglebutton,'enable','off');
set(gui_my_data.run_counter,'enable','on');

Hope this helps.

分享给朋友:
您可能感兴趣的文章:
随机阅读: