在GUI中使用附加参数的MATLAB addlistener

在GUI中使用附加参数的MATLAB addlistener,matlab,matlab-guide,Matlab,Matlab Guide,我正在编写一个MATLABGUI,它有一个轴,可以使用按钮显示图像。我还使用impixelfoval显示鼠标位置的像素坐标,如下所示: h = imshow('hestain.png', 'Parent', handles.axes1); hp = impixelinfoval(gcf, h); 我可以成功地将侦听器添加到impixelinfoval的句柄中,而无需通过以下方式将参数传递给回调函数: addlistener(hp, 'String', 'PostSet', @mycallbac

我正在编写一个MATLAB
GUI
,它有一个轴,可以使用按钮显示图像。我还使用
impixelfoval
显示鼠标位置的像素坐标,如下所示:

h = imshow('hestain.png', 'Parent', handles.axes1);
hp = impixelinfoval(gcf, h);
我可以成功地将侦听器添加到
impixelinfoval
的句柄中,而无需通过以下方式将参数传递给回调函数:

addlistener(hp, 'String', 'PostSet', @mycallback) % Works
但是,我尝试按如下方式将两个参数传递给回调函数,但未能成功地将它们传递给回调函数。我需要
handles
来存储回调函数中计算的变量,以及
hObject
来执行
guidata(hObject,handles)
,这样我就可以访问整个GUI中的新变量

addlistener(hp, 'String', 'PostSet', @mycallback1(hObject, handles))  % Does not work
有人能帮我解决这个问题吗

以下是测试此问题的整个MWE:

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)

根据您的示例,侦听器在默认情况下希望传递2个默认参数:

addlistener(hp, 'String', 'PostSet', @mycallback() )
您应该注意到,在函数中有两个输入:

function mycallback ( src, event )
   ...
end
您试图做的是:

  • 添加2个额外参数
  • 用不同的2替换2个默认参数
  • 您可以通过控制回调函数来执行此操作:

    addlistener(hp, 'String', 'PostSet', @(src,evt)mycallback1(src, evt, hObject, handles))
    

    上面的行捕获默认回调
    src
    evt
    ,第一行将它们与其他变量一起传递给回调,另一行则不传递

    edit我的答案是如何调用侦听器,我没有图像处理工具箱,因此无法创建使用
    impixelinfoval
    函数的代码

    由于您的代码本身不运行,因此我在下面创建了一个小示例,它向您展示了如何添加侦听器,当设置了(在本例中为axes title)字符串属性时,侦听器会做出反应,它会自行运行,因此您应该能够运行它并查看它的工作方式

    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
    
    此GUI是根据代码(而不是指南)创建的

    这通过在鼠标移动以提供当前点时更新轴标题来实现。我添加了两个侦听器,它们在设置标题后更新X和Y标签字符串

    通过了解如何添加侦听器,您应该能够在自己的代码中使用此理论,这可能会突出显示您所存在的任何剩余错误

    下面评论中的错误消息

    addlistener(hp, 'String', 'PostSet', @(source, event, hObject, handles)myImageMagnifier3(source, event, hObject, handles))
    
    我认为这应该是:

    addlistener(hp, 'String', 'PostSet', @(source, event)myImageMagnifier3(source, event, hObject, handles))
    

    就像我最初的例子一样。

    我尝试了你提出的两种方法,但都不起作用。我收到此错误:
    警告:在matlab.ui.control.UIControl类的对象中对字符串动态属性执行PostSet事件的侦听器回调时出错:输入参数不足。GUI_get_mouse_positions>@(source,event,hObject,handles)myImageMagnifier3(source,event,hObject,handles)(第147行)addlistener(hp,'String','PostSet',@(source,event,hObject,handles)myImageMagnifier3(source,event,hObject,handles))中出现错误。
    addlistener(hp, 'String', 'PostSet', @(source, event)myImageMagnifier3(source, event, hObject, handles))