Hi all, I've developed a GUI with 3 simple buttons on it, with tags pb1, pb2, and pb3. I start by calling the GUI .m file, which initializes the handles object. The pb2 and pb3 buttons are initially invisible. When the callback function for pb1 is activated, pb1 is made invisible and pb2 and pb3 visible. Inside the pb1 callback code block another function is called with the handles object as an argument, which runs a psych experiment. Inside the psych experiment after a stimulus is presented, the program waits for a response from the user (using waitforbuttonpress). When the user clicks on pb2, handles.resp is set to 2, and when they click on pb3, handles.resp is set to 3, and the handles object is updated (handles.resp = 3; guidata(hObject, handles)). However, the handles object that was passed as an argument to the psych experiment function is not updated, so handles.resp winds up referring to the incorrect value. This suggests to me that the handles object is not behaving as if it were passed by reference. How do I pass the handles object by reference so its elements update properly?
MATLAB: Handles object behaving like it was passed by value
handles
Related Solutions
In GUIDE, you can create a panel that is a button group. Put your radio buttons inside of that. If you do that, it will automatically take care of toggling the radio buttons so that only one is "true" and the others are all false/off. In your pushbutton callbacks, you can still get the values of the radio buttons, like
if handles.R1.Value % load 4 mat files
end
Like you said.
Michael - I'm not really sure what you mean by The problem is that the plot saved in handles.plots{1} is deleted in the process without a logical reason (for me at least). When I step through the code, I still see that handles.plots{1} is non-empty, so perhaps you mean that it is deleted from the plot or axes. If that is the case, then one problem is that you are missing a call to hold which will retain the current plot when adding new plots. Without this, each time you create a new plot, the previous one is deleted.
I would do the following in the code that supposedly only happens once
% The first time we press the button PB2, X1 will be empty, hence we
% preallocate the memory by creatintg an empty cell of the right size
if all(X1(:)==0) handles.plots(1:length(files)) = {0}; X = handles.plots; X1 = cell2mat(X); hold(handles.axes1,'on');end
Note the call to hold(handles.axes1,'on'); and so all plots will be retained. (You could put this same line in the GUI's OpeningFcn too.
I'm also not sure why you clear the axes with cla. Why not just show and hide your plots based on whether the checkboxes have been checked or not?
% --- Executes on button press in PB2.
function PB2_Callback(hObject, eventdata, handles) % Recover the handles
handles = guidata(hObject); files = handles.files; X = handles.plots; % Save in table the logical value of the checkboxes and convert to mat
table = get(handles.uitable2, 'Data'); CB_answer = cell2mat(table(1:end,1)); % This will be skipped the first time we press PB2. If we have already
% pressed it, in handles.plots there will be stored some plots,
% we have to convert them to 1 to use the next part of the code
for z = 1:length(X) if X{z} > 0 && ishandle(X{z}) X{z} = 1; end end % Convert X to mat to further use
X1 = cell2mat(X); % The first time we press the button PB2, X1 will be empty, hence we % preallocate the memory by creatintg an empty cell of the right size if all(X1(:)==0) handles.plots(1:length(files)) = {0}; X = handles.plots; X1 = cell2mat(X); hold(handles.axes1,'on'); end % Check the status of the pushbutton, if they are true their value is == 1
for i = 1:length(CB_answer) if CB_answer(i) == 1 % If the value of X1(i) == 0 it could mean that we pressed PB2 for
% the first time or the last time we pressed it, the checkbox(i)
% wasn't selected, hence it's not saved in handles.plots{i}.
if X1(i) == 0 f1 = cell2mat(files{i,1}); f2 = cell2mat(files{i,2}); handles.plots{i} = plot(f1,f2); else set(handles.plots{i}, 'Visible','on'); end elseif ~isempty(X1) && X1(i) == 1 set(handles.plots{i}, 'Visible','off'); end end guidata(hObject, handles); end
Note how we use ishandle to check to see if the values in handles.plots are valid handles to graphics objects, and how we hide and show the plots as checked
set(handles.plots{i}, 'Visible','on');
or
set(handles.plots{i}, 'Visible','off');
Related Question
- Oop: how to switch between passing by reference and value
- Trouble with function called from a GUI callback fonction
- How to get a listbox value using a push button callback
- Help using guidata in a script
- Best way to pass uicontrols/data to callback function.
- How to output the result as a matrix in GUI, like any nxn matrix??
Best Answer