设置手形光标以选择 matplotlib 文本

Set hand cursor for picking matplotlib text

我在 tkinter 的 Toplevel 中嵌入了一个 matplotlib 图,并使用 axes.text 在图中添加了文本。我将文本的 picker 属性 设置为 True 因为我想在用户单击文本时执行某些操作。现在我想在鼠标移到文本上时将 arrow 的鼠标光标更改为 hand。我知道对于 tkinter 的任何小部件,这可以通过设置 cursor='hand2' 来实现。但是,这似乎是 matplotlib 的问题。那么,我怎样才能做到这一点?我的 OS 是 Windows。谢谢。

关键是更改后端的 cursord 查找。 (例如,对于 TkAgg,它是 matplotlib.backend_tkagg.cursord。)否则,导航工具栏将覆盖您通过 Tk 手动指定的任何内容。

如果你需要事情发生,还有一个额外的皱纹 "on hover"。因为 matplotlib 没有悬停事件,所以您需要将回调连接到所有鼠标移动,然后检测您是否在有问题的艺术家上方。

这个例子是针对 TkAgg 支持的,但它对于其他后端来说本质上是相同的。唯一的区别在于导入和指定游标的方式(例如,在 Qt 上,您需要 Qt 游标对象而不是字符串 "hand1" 之类的东西)。

import matplotlib; matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib.backends.backend_tkagg as tkagg

def main():
    fig, ax = plt.subplots()
    text = ax.text(0.5, 0.5, 'TEST', ha='center', va='center', size=25)
    fig.canvas.callbacks.connect('motion_notify_event', OnHover(text))
    plt.show()

class OnHover(object):
    def __init__(self, artist, cursor='hand1'):
        self.artist = artist
        self.cursor = cursor
        self.default_cursor = tkagg.cursord[1]
        self.fig = artist.axes.figure

    def __call__(self, event):
        inside, _ = self.artist.contains(event)
        if inside:
            tkagg.cursord[1] = self.cursor
        else:
            tkagg.cursord[1] = self.default_cursor
        self.fig.canvas.toolbar.set_cursor(1)

main()