Unexpected behavior of listener

2 Ansichten (letzte 30 Tage)
Gabriel
Gabriel am 29 Jun. 2016
Beantwortet: Gabriel am 29 Jun. 2016
Dear all,
I am trying to create a GUI which has 3 main components:
1- An axis which shows a slice of a 3D image and where the user must click to plot several points;
2- A scrollbar, which controls which slice of the 3D image is shown;
3- A pushbutton, which activates the drawing function of the axis;
When the user hits the pushbutton, he/ she must click over the image and a method is called in order to plot and register the position of the click. The user should be able to move the scrollbar and visualize the ploted point in all images of the dataset. In order to do so, I created a class (CircularRoi), which has some properties, such as the coordinates of the click and the handle of the GUI. Once the user finishes the selection, he/she hits the RETURN key on the keyboard.
IF the user wants to select more points, he/ she must hit the pushbutton again and click over the points of the image. The class coordinate variables should store the previous and the new values of the coordinates and as the user moves the scrollbar, all the points must be ploted over all the images.
Here is a piece of my code:
classdef CircularRoi < handle
properties
x;
y;
xc;
yc;
handles;
hl;
end
properties (SetObservable = true)
slice;
end
methods
function obj = CircularRoi(hdl, value)
axeshandle = hdl.axs_img;
obj.handles = hdl;
obj.slice = value;
obj.addListener;
if isfield(hdl, 'roi_circle_x')
hold on;
plot(axeshandle, hdl.roi_circle_x{hdl.serie}', ...
hdl.roi_circle_y{hdl.serie}', 'c');
plot(axeshandle, hdl.roi_circle_xcenter{hdl.serie}, ...
hdl.roi_circle_ycenter{hdl.serie}, '*b');
obj.x = hdl.roi_circle_xcenter{hdl.serie};
obj.y = hdl.roi_circle_ycenter{hdl.serie};
obj.xc = hdl.roi_circle_x{hdl.serie};
obj.yc = hdl.roi_circle_y{hdl.serie};
end
end
function addListener(obj)
obj.hl = addlistener(obj.handles.sld_img, ...
'Value', 'PostSet', ...
@(src, event)plotRoi(obj, src, event));
end
function getRoi(obj, hdl, src, event)
obj.getRoiCircle;
obj.slice = get(hdl.sld_img, 'Value');
end
function plotRoi(obj, src, event)
axeshandle = obj.handles.axs_img;
serie = obj.handles.serie;
obj.slice = round(get(obj.handles.sld_img, 'Value'));
txt = findobj(get(axeshandle, 'Children'), 'Type', ...
'Text');
img = obj.handles.img{serie}(:, :, obj.slice);
delete(txt);
imshow(img, [], 'parent', axeshandle);
hold on;
xx = obj.x;
% THE PROBLEM:
disp(xx)
% ---
yy = obj.y;
xxc = obj.xc;
yyc = obj.yc;
plot(axeshandle, xx, yy, '*b', xxc', yyc', 'c');
for ii = 1: length(xx)
text(xx(ii), yy(ii), num2str(ii), 'color', 'c', ...
'Parent', axeshandle);
end
end
The problem is, when the user hits the pushbutton for the second time, clicking on the image and moving the scrollbar, the "x" and "y" coordinates are set to their previous values. And the weirdest thing: if I ask to display the coordinate values (disp(xx)) in the prompt, it prints teh value twice, the first time with correct values of xx and the second time with the previous values of xx, i.e., the values before the user clicked on the pushbutton for the second time.
For example, if for the first time the user selected one point (x = 100, y = 90) and then clicked on the pushbutton in order to add a second point (for example 180, 200), when he/she moves the scrollbar the disp function returns two values for xx:
100 180
100
Instead of just concatenating the two values, it changes the object value for its previous value; Another weird thing: if I add a break point and go line by line, this strange behavior doesn't happen.
Any idea of what is going on?
  2 Kommentare
Adam
Adam am 29 Jun. 2016
Bearbeitet: Adam am 29 Jun. 2016
You should never pass a GUI handles structure around like that if you are using it with dynamic data attached. This is not a pass-by-reference class object, it is simply a struct. When you pass it to your class it takes a copy of the struct at the time you copy it and you then have two different handles structs, one in the class and one in the GUI. Anything added to one will not be added to the other.
I don't know if this is the full source of your problem, but it is certainly a likely candidate for at least some of the problem. UI component handles will be fine, of course, because they should always be there unless you are dynamically changing the components that are on your UI. But what is 'serie' on your obj.handles and when it is set? The version of it in your class will never change from what I can see.
Gabriel
Gabriel am 29 Jun. 2016
Actually I just solved the problem: I had to delete the CircularRoi object/listener. Matlab was creating a different listener for each time I create a CircularRoi object (which is also very strange. I was expecting that the listener would be overwritten).

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Gabriel
Gabriel am 29 Jun. 2016
I had to delete the CircularRoi object/listener. Matlab was creating a different listener for each time I create a CircularRoi object (which is also very strange. I was expecting that the listener would be overwritten).

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by