Inconsistent handles structure in GUI callback function

3 views (last 30 days)
I have a GUI which displays an image (it's a colormap, and each pixel contains signal data.) I want to be able to click a pixel and display a graph of the signal data that was stored in that pixel. That part works fine, the errors pop up when I try to select a second pixel. My intention is to create a subplot on a single figure, 5 rows by 2 columns (the first column is time domain, second is frequency domain.) The GUI would know which row it should be in by a variable "nthline" which is part of the handles structure, and at the end of the callback function, it will increment by 1 and update the handles structure with guidata(hObject, h). At first, it would create brand new figures with the new data which, while worked, is not what I was asked to do, so I continued to try to get it on the same figure, which led to me adding a variable "firstClick" to the handles structure in the GUI. Upon looking at the value of firstClick for the first pixel selection (where firstClick should be true, where it is initialized and saved to the handles structure,) it is indeed saved as true. So, I update the handles structure to assign false to firstclick with
h.firstClick = false; %h is the handles structure
guidata(hObject, h);
On the second pixel selection, h.firstClick is still true, and so it reopens a new figure, but this is not what I want. Why is there this inconsistency in handles structures across different pixels, and how can I keep the firstClick variable from changing back to true?

Accepted Answer

Steven Lord
Steven Lord on 3 Jun 2020
My guess is that you specified the callback function that executes as an anonymous function that does not accept the handles structure as an input but instead "remembers" it.
m = 5;
b = 3;
y = @(x) m*x+b;
y(2) % 13
m = 999;
y(2) % still 13
If that's the case, see the "Variables in the Expression" section on this documentation page.
Instead, pass something that's not likely to change (the handle to your UI perhaps) but with which you can access the handles struct into the callback.
f = figure;
f.UserData = [5 3];
computeme = @(x, fig) fig.UserData(1)*x + fig.UserData(2)
y = @(x) computeme(x, f);
y(2) % still 13
f.UserData = [42, 26];
y(2) % 42*2+26 = 110
  1 Comment
Scott Feltman
Scott Feltman on 3 Jun 2020
While this exact code is unusable in the context of my project, your reasoning allowed me to identify and solve the problem. The relevant line of code is
set(img.ButtonDownFcn,{axes.ButtonDownFcn,handles}) %needed to execute button press over image
This is the primary reason for the inconsistent handles structure. As you said, the function "remembered" an old version of the handles. That was the handles structure that was passed in that line, and so while I updated it in the actual handles structure, this copy was kept and reused in the function. Thank you for your time and solution, and for helping me to solve this problem.

Sign in to comment.

More Answers (0)

Tags

Products


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!