Reputation: 2327
I am writing a MATLAB GUI
which has an axes to show an image using a push button. I also use impixelinfoval
to show the pixel coordinates of the location of the mouse as follows:
h = imshow('hestain.png', 'Parent', handles.axes1);
hp = impixelinfoval(gcf, h);
I can successfully add a listener to the handle of the impixelinfoval
with no argument passed to the callback function by:
addlistener(hp, 'String', 'PostSet', @mycallback) % Works
However, I am trying to pass two arguments to the callback function as follows and I have not been successful to pass them to the function. I need handles
to store a variable calculated in the callback function as well as hObject
to be able to execute guidata(hObject, handles)
so that I have access to the new variable in the entire GUI.
addlistener(hp, 'String', 'PostSet', @mycallback1(hObject, handles)) % Does not work
Could someone kindly help me with this problem?
The following is the entire MWE to test this issue:
function varargout = untitled(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @untitled_OpeningFcn, ...
'gui_OutputFcn', @untitled_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function untitled_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = untitled_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
h = imshow('hestain.png', 'Parent', handles.axes1);
hp = impixelinfoval(gcf, h);
addlistener(hp, 'String', 'PostSet', @mycallback) % Works
% addlistener(hp, 'String', 'PostSet', @mycallback1(hObject, handles)) % Does not work. I would like to pass both hObject and handles to mycallback function.
function mycallback(src, evt)
disp(evt.AffectedObject.String)
function mycallback1(src, evt, hObject, handles)
disp(evt.AffectedObject.String)
% Create a variable and store it in the handles
handles.pixelcoord = evt.AffectedObject.String;
% Update handles
guidata(hObject, handles)
Upvotes: 0
Views: 1006
Reputation: 21
I just ran into your post, since I am facing a similar problem. I am programming an instrument GUI, the instrument is defined as an object that can send notifiers. I want to have the GUI updated with the information on that particular notifier event. To put a long story short, what finally worked for me is the following:
Definition of listener in GUI opening function: addlistener(handles.Stage, 'PID_changed', @(hObject, eventdata)updatePID_Callback(hObject, eventdata, handles));
Definition of Callback function (regular function, not an object method): function updatePID_Callback(~,~,handles) ... (updating GUI, e.g., set(handles.editbox1, 'string', num2str(someValue)) .. end
That's all I can say, hope it helps ..
Upvotes: 2
Reputation: 5672
A listener will by default want to pass 2 default parameters as per your example that works:
addlistener(hp, 'String', 'PostSet', @mycallback() )
You should notice in your function you have 2 inputs:
function mycallback ( src, event )
...
end
What your trying to do is to either:
You do this my controlling the callback function:
addlistener(hp, 'String', 'PostSet', @(src,evt)mycallback1(src, evt, hObject, handles))
or
addlistener(hp, 'String', 'PostSet', @(src,evt)mycallback1(hObject, handles))
The above lines are capturing the default callbacks src
and evt
and the first one is passing them to your callback with your additional variables, the other is not.
edit My answer was focusing on how to call a listener, I dont have the imageprocessing toolbox so cant create a code which uses the impixelinfoval
function.
Since your code on its own doesn't run I have created a small example below which shows you how to add listeners which react when a (in this case axes title) string property has been set, it runs on its own so you should be able to run it and see how it works.
function untitled
%%
% create a figure
h = figure;
% create an axes
ax = axes ( 'parent', h );
% create a variable which we will plot
p = peaks(50);
% plot the variable
imagesc ( p, 'parent', ax );
% createa some initial title, x and y lables
t = title ( ax, 'Title' );
x = xlabel ( ax, 'X Label' );
y = ylabel ( ax, 'Y Label' );
% add a callback to run when the mouse moves.
h.WindowButtonMotionFcn = @(a,b)moveMouse (ax, t);
% add listeners which are triggered after the title has been set
% this listener passes the standard callbacks and some extras, namely
% the handles of the title and the y label
addlistener ( t, 'String', 'PostSet', @(h,evt)mycallback1(h,evt,t,y) )
% this listener only passes the handle to the title and the x label
addlistener ( t, 'String', 'PostSet', @(h,evt)mycallback(t,x) )
end
function moveMouse ( ax, t )
% update the title of the axes for
t.String = sprintf ( 'current point %.1f,%.1f', ax.CurrentPoint(1,1:2) );
end
function mycallback ( t, x )
% udpate the x label string
x.String = sprintf ( 'X Label -> title value: %s', t.String );
end
function mycallback1 ( h, event, t, y )
% update the y label string
y.String = sprintf ( 'Y Label -> title value: %s', t.String );
end
This GUI is created from code (not guide).
This works by updating the axes title when the mouse moves to provide the current point. I have added 2 listeners which update the X and Y label strings after the title has been set.
From knowing how to add listeners you should be able to use this theory in your own code, and that might highlight what any remaining errors you have are.
your error message in comment below
addlistener(hp, 'String', 'PostSet', @(source, event, hObject, handles)myImageMagnifier3(source, event, hObject, handles))
I suspect this should be:
addlistener(hp, 'String', 'PostSet', @(source, event)myImageMagnifier3(source, event, hObject, handles))
like in my original example.
Upvotes: -1