获取Matlab处理事件或属性



问题

如何获取双重类型句柄(如figureaxes)的事件和属性列表

问题

Matlab文档告诉您要使用WindowButtonDownFcnWindowButtonMotionFcn等等,以便监听接口上发生的任何事情。问题是,由于以下事实,这种属性非常有限:

将变量保持在范围内

当MATLAB评估函数句柄时,中存在相同的变量创建函数句柄时的作用域(相比之下,回调指定为在基本工作区中计算的字符串。)这个简化了管理全局数据的过程,例如对象句柄,在GUI中

是的,这是完美的,如果您不必重新定义、添加或删除ButtonDownFcn中的回调,因为如果您这样做,您将失去其他函数句柄变量作用域,因为您正在一个新作用域中声明它们,而可能肯定不会包含您所需的变量。

因此,一种方法是监听事件本身,而不是在事件处于活动状态时调用的属性。这样做,您就不必重新声明ButtonDownFcn以及如何将变量保持在范围内,因为其他解决方案实现起来非常慢。如果我可以像使用handle.listeneraddlistener matlab监听工具那样直接监听事件,我就不必为此烦恼了。

一个已知的好方法

最好的解决方案之一似乎是这个FEX,它赋予了弱的matlab WindowButtonDownFcnWindowButtonDownFcn和matlab具有的任何属性"监听器"函数,这样你就可以让任何数量的函数在你的图形界面上监听变化,而不必担心你的其他函数句柄是否会丢失它们的范围变量。

有了这个,我不需要获取matlab事件,因为它为我包装了所有的东西。但让我感到有趣的是,matlab引导用户使用一个坏功能,而不是记录更好的方法,并引导人们包装所有的东西,这样他们就可以按原样使用东西。


可能有用的信息

我知道meta.class,它将为我提供类所具有的所有属性、事件等。对于我从handle:继承的一个类

>> EventMeta = ?Event
EventMeta = 
  class with properties:
                     Name: 'Event'
              Description: ''
      DetailedDescription: ''
                   Hidden: 0
                   Sealed: 0
                 Abstract: 0
          ConstructOnLoad: 0
         HandleCompatible: 1
          InferiorClasses: {0x1 cell}
        ContainingPackage: []
             PropertyList: [64x1 meta.property]
               MethodList: [29x1 meta.method]
                EventList: [2x1 meta.event]
    EnumerationMemberList: [0x1 meta.EnumeratedValue]
           SuperclassList: [1x1 meta.class]

有了这个元,我可以从我的Event类中获得EventList,它们是:

>> EventMeta.EventList.Name
ans =
attemptToClick

ans =
ObjectBeingDestroyed

在这种情况下,这并不是什么好事,因为我已经实现了它,我知道它所发生的事件,因为我有它的来源。问题是,如果我能得到figure的元类(如果可能的话),如果它们在matlab中可用,我就可以访问它实现的Events

在后台,Handle Graphics(HG)是使用未记录的UDD机制实现的,而不是向用户公开的常见classdef风格的OOP。

这就是为什么您不能直接使用meta.class系统来获取此类句柄的元信息。

正如你在亚伊尔·奥特曼的博客上已经发现的那样,有一些未记录的方式可以收听事件:

fig = hg.figure(); plot(rand(100,1))
lh = handle.listener(fig, 'WindowButtonDownEvent',@(~,~)disp('clicked'));

如果您已经有一个现有的HG对象句柄(用数字句柄表示),请使用handle将其转换为UDD句柄:

f = figure();
fig = handle(f);

是的,我知道,术语handle在MATLAB中是相当过载的,可能指的是

当我改进我的问题时,我设法找到了答案(不幸的是,我以前在搜索中似乎没有见过它们,更糟糕的是,一些我以前打开过的链接…)

在这里,未累积的matlab博客展示了如何从matlab句柄对象中获取句柄。2011年,似乎已经有一个关于这个问题的问题在stackoverflow上提出了,@gnovice正确地回答了这个问题。答案是:

>> get(get(classhandle(handle(gcf)),'Events'),'Name')
ans = 
    'SerializeEvent'
    'FigureUpdateEvent'
    'ResizeEvent'
    'WindowKeyReleaseEvent'
    'WindowKeyPressEvent'
    'WindowButtonUpEvent'
    'WindowButtonDownEvent'
    'WindowButtonMotionEvent'
    'WindowPostChangeEvent'
    'WindowPreChangeEvent'

我仍然想提请您注意FEX,它是另一个很好的解决方案,可以为您提供更好的可能性来使用matlab提供的图形组件。

用法示例:

>> k=handle.listener(gcf,'WindowButtonMotionEvent','disp(''MOVEMENT DETECTED!!'')');   
>> MOVEMENT DETECTED!! % When you move the mouse on the figure
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> MOVEMENT DETECTED!!
>> delete(k)

尝试使用get:

fig = gcf();
get(fig)

我不知道该怎么做。我可以提供一些示例代码来演示我所认为的问题。这是一个相对较新(因此未使用)的Matlab功能:

hh = handle(gca);
lsnr = addlistener(hh,'XLim','PreGet',@(~,~)disp('<<<Getting XLIM values>>>'))

查看正在进行的侦听器

>> get(hh,'XLim')
<<<Getting XLIM values>>>
ans =
     0     1

我认为问题是,如果没有存储值,如何从gca中获取lsnr

我找不到路了。

最新更新