类中的 Matplotlib 事件处理

问题描述 投票:0回答:1

有人可以解释一下吗?

此代码应该在按下鼠标按钮时打印出事件详细信息。如果我将

button_press_event
插槽连接到
on_button_press
(在类之外),代码将按预期工作。如果我改用类方法
self.on_button_press
,则不会打印任何内容。这是为什么?

import matplotlib.pyplot as plt

class Modifier:
    def __init__(self, initial_line):
        self.initial_line = initial_line
        self.ax = initial_line.axes
    
        canvas = self.ax.figure.canvas
        cid = canvas.mpl_connect('button_press_event', self.on_button_press)

    def on_button_press(self, event):
        print(event)

def on_button_press(event):
    print(event)


fig, ax = plt.subplots()
ax.set_aspect('equal')
initial = ax.plot([1,2,3], [4,5,6], color='b', lw=1, clip_on=False)

Modifier(initial[0])

plt.show()
python matplotlib events
1个回答
0
投票

因为您创建了对象但没有将其保存到变量中,所以 Python 在创建后会立即自动销毁它。我们可以通过添加一个

__del__
方法来检查这一点,并调用
print
来显示它正在被删除。我还添加了一个短暂的睡眠来证明破坏是在程序终止之前发生的。

import matplotlib.pyplot as plt
import time

class Modifier:
    def __init__(self, initial_line):
        self.initial_line = initial_line
        self.ax = initial_line.axes
    
        canvas = self.ax.figure.canvas
        cid = canvas.mpl_connect("button_press_event", self.on_button_press)

    def on_button_press(self, event):
        print(event)

    def __del__(self):
        print("Destroyed.")

fig, ax = plt.subplots()
ax.set_aspect("equal")
initial = ax.plot([1,2,3], [4,5,6], color='b', lw=1, clip_on=False)

Modifier(initial[0])

print("Starting to sleep...")
time.sleep(5)
print("Done sleeping.")

plt.show()

输出:

Destroyed.
Starting to sleep...
Done sleeping.

因此,您的类实例在显示情节之前就被销毁了。在使用外部按钮功能的情况下,

mpl_connect
仍然知道该功能并可以使用它。在类方法的情况下,类被销毁,因此
mpl_connect
不再有可调用的函数(我不确定为什么会默默地发生这种情况)。

简单的解决方法是将对象保存到变量中,这样它就不会立即被销毁,即

m = Modifier(initial[0])

一旦执行此操作,代码将与类方法一起使用。

作为旁注,您可能应该将

cid
保存为类属性,以确保也保持不变。

© www.soinside.com 2019 - 2024. All rights reserved.