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:
value
of the togglebutton)startStop_togglebutton
callbach only to update the string
displayed on the togglebuttonThe 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:
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.