Reputation: 13
I'm making a GUI that reads out data from a measurement board via a serial interface. It consists of 8 channels and I want to be able to enable and disable the channels in the figure plot, but the state of my variable handles.channelsEnable isn't saved.
When opening the GUI: handles.channelEnable = [0;0;1;1;0;0;0;0]; While running the GUI I want to modify a handles.channelEnable. Inside the callback function of a checkbox it is changed, but not outside the function. I'm using guidata(hObject,handles) to save the changes made. Why aren't the changes made to handles.channelEnable saved?
% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
% hObject handle to checkbox2 (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 checkbox2
handles.channelEnable(2) = get(hObject,'Value');
guidata(hObject, handles);
end
Upvotes: 1
Views: 605
Reputation: 13
I don't think I fully understand you.
Do you mean that I have to add guidata(hObject) to get the handles? So the code looks like this:
% --- Executes on button press in checkbox2.
function checkbox2_Callback(hObject, eventdata, handles)
% hObject handle to checkbox2 (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 checkbox2
handles
guidata(hObject);
handles
handles.channelEnable(2) = get(hObject,'Value');
guidata(hObject, handles);
end
It does not make any difference with or without. In both cases all handles are known (also channelEnable).
Upvotes: 0
Reputation: 12214
@YisasL's answer is the correct one, but I wanted to clarify it a bit.
When providing an input variable to a callback function, the variable that is passed when you invoke the callback is that variable as it exists when the callback is defined. You can see this with a simple example:
function testcode
handles.mainwindow = figure();
handles.button1 = uicontrol( ...
'Style','pushbutton', ...
'Units','normalized', ...
'Position',[0.05 0.05 .30 .90], ...
'String','Button1', ...
'Callback',{@button1,handles} ...
);
handles.button2 = uicontrol( ...
'Style','pushbutton', ...
'Units','normalized', ...
'Position',[0.35 0.05 .30 .90], ...
'String','Button2', ...
'Callback',{@button2,handles} ...
);
handles.button3 = uicontrol( ...
'Style','pushbutton', ...
'Units','normalized', ...
'Position',[0.65 0.05 .30 .90], ...
'String','Button3', ...
'Callback',{@button3,handles} ...
);
end
function button1(~,~,handles)
fieldnames(handles)
end
function button2(~,~,handles)
fieldnames(handles)
end
function button3(~,~,handles)
fieldnames(handles)
end
Push each button and look at the displayed output from fieldnames
. You'll notice that button 1 only has mainwindow
, button 2 has mainwindow
and button1
, and button3 has mainwindow
, button1
, and button2
. As you've now noticed, no matter what changes you make elsewhere in your code, this result will remain constant.
It's an interesting quirk I noticed when I moved to programmatic GUIs rather than utilizing GUIDE. You generally don't notice with a GUIDE GUI because all of the initialization is taken care of in the background and the users don't tend to modify the handles structure. With a programmatic GUI you need to be conscious of the order in which you define your callbacks (define them after your handles structure is built).
The alternative is to utilize guidata
like @YisasL said. Then you don't need to worry about passing variables to your callbacks.
Upvotes: 1
Reputation: 335
You can use guidata
to include a new handle in the handles
variable, but whenever you want to use handles
you must call guidata
to obtain them. The variable handles
as input variable of the callback won't have it included.
Upvotes: 0