Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
131 views
in Technique[技术] by (71.8m points)

user interface - Matlab GUI axes extract position from datacursor

hope anyone can help me.

I try to load and display a image in my GUI. After that i activate datacursormode. Now I want to extract the position from my datacursor object and save the informations into a global variable to work on this data.

Here is my code:

function varargout = myGui(varargin)

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
               'gui_Singleton',  gui_Singleton, ...
               'gui_OpeningFcn', @myGui_OpeningFcn, ...
               'gui_OutputFcn',  @myGui_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
% End initialization code - DO NOT EDIT


% --- Executes just before myGui is made visible.

% Choose default command line output for myGui
handles.output = hObject;

path = uigetimagefile;
img = imread(path);

axes(handles.axes1);

imshow(img);

dcm_obj = datacursormode(handles.figure1);
datacursormode on;
set(dcm_obj,'UpdateFcn', @myupdatefcn );


handles.pos = hObject;
handles.pos = get(0,'userdata');
set(handles.txt1,'String',num2str(handles.pos));
guidata(hObject, handles);


% --- Outputs from this function are returned to the command line.
function varargout = myGui_OutputFcn(hObject, eventdata, handles) 

% Get default command line output from handles structure
varargout{1} = handles.output;

And in a extra .m file i have the 'myupdatefcn' like thi

function txt = myupdatefcn(~, event_obj)
posi = event_obj.Position;
disp(['You clicked X:',num2str(posi(1)),', Y:',num2str(posi(2))]);
txt = {'Point to Compute'};
set(0,'userdata',posi(1));
end

Can anyone explane how I can do this?

thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You GUI organization seems a bit chaotic. You have to be careful where you place the extra code in the .m file generated by the GUIDE.

I suggest you replace all the code you placed in the middle of the function by a call to your own initialization function:

myGuiInitialization(handles) ;

Then, in the same file (at the bottom), add the following code:

function myGuiInitialization(handles)
% path = uigetimagefile;       %// uncomment that to retrieve your intital functionality
% img = imread(path);          %// uncomment that to retrieve your intital functionality
img = imread('peppers.png') ;  %// Delete that to retrieve your intital functionality

himg = imshow(img, 'Parent',handles.axes1) ;    %// get the handle of the image graphic object (needed to attach the datatip to it)

dcm_obj  = datacursormode(handles.figure1);     %// get the handle of the datacursor object
set(dcm_obj,'UpdateFcn', @myDatatipUpdateFcn ); %// assign it a callback
dcm_obj.createDatatip(himg) ;                   %// create a new DATATIP and attach it to the image object

This will load an image, create a datatip and associate a callback to it.

Your separate function managing the datatip update becomes:

function txt = myDatatipUpdateFcn(hobj, event_obj)

   handles = guidata( event_obj.Target ) ;  %// retrieve the collection of GUI graphic object handles
   pointPosition = event_obj.Position;      %// get the position of the datatip

   %// Store the position in the figure "appdata", named "pointPosition"
   setappdata( handles.figure1 , 'pointPosition' , pointPosition )  

   %// now we've saved the position in the appdata, you can also display it
   %// on the datatip itself
   txt = {'Point to Compute: ';...
         ['X:',num2str(pointPosition(1))]; ...
         ['Y:',num2str(pointPosition(2))] } ;

Now every time the datatip will be moved, the last point position will be saved in the figure AppData. I recommend you use the function setappdata and getappdata instead of the old userdata (it's a thing of the past, avoid it if you can).

Specially, the way you were doing it, assigning the userdata of the object 0 is not recommeded, because that will be stored in the main root object. If you close your gui these data may still exist. The setappdata will store data attached to your GUI, which is a much cleaner way (when your gui is closed the data disappear with your gui).

Now when you want to do something with your point position saved in your AppData, you can just retrieve them with getappdata.

For the purpose of this example, I created a pushbutton on the figure. When pushed, it will retrieve the point position and display it in the textbox.

When you create the pushbutton, the GUIDE will create an empty callback for it in the gui main function. Place the following code in it:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)

%// retrieve the point position saved in the figure appdata named "pointPosition"
pointPosition = getappdata( handles.figure1 , 'pointPosition' ) ;
%// that's it, you have your point position, now do whatever you need with it

%// prepare a test string with the position and display it in the label
txtstr = sprintf('Point to compute: X=%d , Y=%d',pointPosition) ;
set(handles.txt1,'String',txtstr);

This code will produce something like that: samplegui

The datatip label will update position at every move, but the text label at the bottom will only be updated when you press the pushbutton.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...