GUI ButtonDownFcn for clicking on axes

29 次查看(过去 30 天)
Hi all, I've got 2 axes in my GUI, and I want to be able to launch a different .m file when the user clicks either axes.
Currently I can launch a function, but I'm unable to differentiate between the different axes, and I'd rather directly run a .m script if possible.
I currently have:
setappdata(gcf,'bdfcnhandle',load_stuff);
axes(handles.axes3)
h(1)=imshow(thumb_1, [])
axes(handles.axes4)
h(2)=imshow(thumb_2, [])
set(h,'buttondownfcn','feval(getappdata(gcf,''bdfcnhandle''));');%
function load_stuff(hObject, eventdata, handles) X=100;
Also using the code above, I seem to be unable to access the handles structure in my "load_stuff" function!
Can anyone help my plight?
Thanks, Jim

采纳的回答

Patrick Kalita
Patrick Kalita 2011-6-2
I would use the 'ButtonDownFcn' property on each axes, and make the callback function be a call to the run function which will execute your script.
So let's say you have to scripts named s1.m and s2.m. Assuming they're both on the MATLAB path, you can do this:
a1 = axes('Position', [0.1 0.1 0.4 0.4], 'ButtonDownFcn', @(s,e) run('s1'));
a2 = axes('Position', [0.5 0.5 0.4 0.4], 'ButtonDownFcn', @(s,e) run('s2'));
(I'm setting the position property there just so you can see both of the axes in the same figure.)
If the scripts s1.m and s2.m are not on the path, then you can specify the full path to them in the call to run.

更多回答(2 个)

Walter Roberson
Walter Roberson 2011-6-2
setappdata(gcf,'bdfcnhandle',load_stuff);
is going to run load_stuff (with no parameters), and take its return value and set that as bdfcnhandle in the app data.
I would have to do some digging to figure out what you could do along the lines you have been working.
Note that imshow() returns the handle of an image object, not the handle of an axes. When you are setting the buttondownfcn you are doing so for the images, not for the axes. If you want it to be the axes, you should set(h,'HitTest','off') and set the buttondownfcn against the axes.
What I would do is
set([handles.axes3, handles.axes4], 'buttondownfcn', @load_stuff)
function load_stuff(hObject, eventdata)
handles = guidata(hObject);
theaxes = ancestor(hObject,'axes');
if theaxes == handles.axes3
%axes3 stuff
elseif theaxes == handles.axes4
%axes4 stuff
end
end
and I wouldn't use bdfcnhandle at all. This code is also designed for calling for either the image object or the axes object.
  6 个评论
Walter Roberson
Walter Roberson 2011-6-7
In your setup routine,
handles.h = h;
guidata(hObject,handles).
Then in load_stuff,
h = handles.h;
if hObject == h(1)
%image 1 stuff
elseif hObject == h(2)
%image 2 stuff
else
%something went wrong
end
Patrick Kalita
Patrick Kalita 2011-6-7
Generally it would be better to have each image implement it's own ButtionDownFcn, precisely to avoid the "else ... % something went wrong" case.

请先登录,再进行评论。


Robert Cumming
Robert Cumming 2011-6-2
Why dont you just do:
set ( h(1), 'ButtonDownFcn', {@mfile_1} );
set ( h(2), 'ButtonDownFcn', {@mfile_2} );
  3 个评论
Robert Cumming
Robert Cumming 2011-6-2
yes the command is expecting a function. Change your script to a function and it will work.
Walter Roberson
Walter Roberson 2011-6-2
The load_stuff example you should was a function ?
Beware that when you run the script, the workspace will be... ummm, probably the base workspace.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Interactive Control and Callbacks 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by