Skip to main content
 首页 » 编程设计

python之如何处理同一张图上多个对象监听motion_notify_event

2025年05月04日8飞鱼

我正在使用 matplotlib:

假设我有一个对象 A,它有两个属性 B 和 C,以及一个绘制图形的方法。 B 和 C 都有方法在事件“motion_notify_event”的图形上做一些事情。

我注意到这两种方法不能同时起作用,而且似乎存在冲突。

如何处理这种情况?

所以我写了一段代码,比上面的解释更能说明问题。

import matplotlib.pyplot as plt 
from matplotlib.widgets import MultiCursor 
from matplotlib.patches import Circle 
 
 
class Event1(object): 
 
    def __init__(self,axes): 
 
        self.fig  = axes[0].figure 
        self.axes = axes 
 
        self.eid = self.fig.canvas.mpl_connect('motion_notify_event',self.onmove) 
 
 
    def onmove(self,event): 
        for ax in self.axes: 
            c = Circle((event.xdata,event.ydata),radius=0.05) 
            ax.add_patch(c) 
            ax.draw_artist(c) 
 
        self.fig.canvas.blit(self.fig.bbox) 
 
 
 
class plotclass(object): 
 
    def __init__(self): 
 
        pass 
 
    def plotme(self): 
 
        self.fig = plt.figure() 
        self.ax1 = self.fig.add_subplot(211) 
        self.ax2 = self.fig.add_subplot(212) 
 
        for ax in (self.ax1,self.ax2): 
            ax.set_xlim((0,10)) 
            ax.set_ylim((0,10)) 
 
#       self.curs = MultiCursor(self.fig.canvas,(self.ax1,self.ax2)) 
 
        self.ev1 = Event1((self.ax1,self.ax2)) 
 
        self.fig.show() 
 
 
 
def main(): 
 
    pc = plotclass() 
 
    return pc 
 
 
if __name__ == '__main__': 
    main() 

现在在这段代码中有两个监听 motion_notify_event 的东西:Event1 类,它将在光标位置绘制圆圈,以及类“plotclass”,它创建图形并在光标位置绘制光标。

我已经注释掉了 self.curs = ... 这一行,当鼠标移动时我看到了圆圈,但是如果我取消注释,我只会看到光标:为什么?以及如何同时看到两者?

请您参考如下方法:

只是为了详细说明我上面的评论,这不是由于多个事件处理,而是由于 blitting 的不同阶段相互覆盖。

Blitting 通常通过恢复保存的、完全渲染的状态然后在其上绘制来工作。

在您当前的代码中,您正在发送而不是恢复已保存的状态,因此您会得到一个圆圈的“踪迹”(大概这就是您想要的)。

但是,MultiCursor 会调用 fig.canvas.restore_region(...) 在 绘制自身之前(否则你会有一个“轨迹”行)。因此,它会在您刚刚绘制的内容上恢复保存的“空白”图形。

如果你想使用多次位图传递,它们需要相互协调。有许多不同的方法可以处理这个问题,但对于大多数用例来说,它们都有些矫枉过正。快速修复是将 useblit=False 传递给 MultiCursor。但是,这会减慢渲染速度。

您能详细说明一下您要做什么吗?你只想要一个在鼠标位置有一个圆圈的光标吗? (如果是这样,只需继承 MultiCursor。)