MATLAB: Button callback in GUI _OpeningFcn does not update a guidata variable

guiguidataguide

Consider the following easy example:
function GUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB

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

% varargin command line arguments to GUI (see VARARGIN)
% Choose default command line output for GUI
handles.output = hObject;
clc
handles.ColVec = []
pushbutton4_Callback(hObject, eventdata, handles)% calling Button4 here
% Update handles structure
guidata(hObject, handles);
and the following callback function for Button4,
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.ColVec = [1 .1 .1];
guidata(hObject,handles)
Naturally when the GUI runs for the very first time, the ColVec should be equal to [1 .1 .1], while it shows empty! handles.ColVec however is equal to [1 .1 .1] when I manually press the Button4! Does somebody know why the handles value cannot be automatically changed when the Button4 is called back in OpeningFcn? and what's the workaround of it to get the ColVec = [1 .1 .1] without manually pressing Button4?
Thanks

Best Answer

The debugger would help you to examine, what's going on: Set a break point in the code and step through it line by line. You will see:
% In GUI_OpeningFcn:
...
handles.ColVec = [];
% Now handles.ColVec is []
pushbutton4_Callback(hObject, eventdata, handles)
% ==> function pushbutton4_Callback(hObject, eventdata, handles)
handles.ColVec = [1 .1 .1];
guidata(hObject,handles)
% Now handles.ColVec is [] and handles is written to the figure
% <== return to GUI_OpeningFcn:
% Now the changes inside pushbutton4_Callback are written to the figure, but
% the handles struct here still contains ColVec = [].
guidata(hObject, handles);
% This overwrites the version saved in the pushbutton4_Callback.
Passing around the handles struct is discussed mutliple times each day. Therefore I consider it as a severe design error, which is too susceptible for confusions. At least this is less dangerous than global's because it concerns the local figure and it's callbacks only.
Solution:
function GUI_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
clc
handles.ColVec = []
pushbutton4_Callback(hObject, eventdata, handles)% calling Button4 here
% Either omit: guidata(hObject, handles);
% Or get the version changed in the callback at first:
handles = guidata(hObject);
guidata(hObject, handles);
The latter is useful only, if there are some additional actions in between.