【问题标题】:Set hand cursor for picking matplotlib text设置手形光标以选择 matplotlib 文本
【发布时间】:2015-03-09 10:23:09
【问题描述】:

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

【问题讨论】:

  • 乍一看,这似乎是重复的,但如果这是一个错误,请告诉我,我会重新打开这个问题。
  • @Joe Kington 这与该问题不重复。我想要做的是在文本上方更改鼠标光标,而不是像 matplotlib 的光标那样在图中添加光标。
  • 如果您不认为它是重复的,我会保持打开状态,但无论哪种方式,您都需要更改 tkagg.cursord 中活动工具的光标,与答案相同我最初链接 (stackoverflow.com/questions/27603215/…) 唯一的区别是您只想在将鼠标悬停在特定文本对象上时执行此操作。最后一点你必须跳几圈,但不要太多。 (如果有时间,我稍后会添加一个完整的示例。)
  • @JoeKington 我已经仔细了解了您在链接问题中的答案,但我不明白tkagg.cursord 的意思。而关于Cursor类的详细介绍网上也没有公布。那么你能提供更多关于你的观点吗?再次感谢。
  • matplotlib Cursor 小部件与这个问题没有任何关系。 (它在轴上绘制交互式“十字准线”。)要更改使用 TkAgg 后端时可见的光标,您需要更改 tkagg.cursord,这就是我提到它的原因。

标签: python matplotlib tkinter


【解决方案1】:

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

如果您需要在“悬停”时发生某些事情,则还有一个额外的问题。由于 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()

【讨论】:

  • 非常好,它有效。非常感谢。但在我使用matplotlib.figure.Figurematplotlib 嵌入tkinter 的情况下,应该应用figure.canvas.mpl_connect 而不是fig.canvas.callbacks.connect,否则会引发AttributeError。这就提出了另一个问题,从fig, ax = plt.subplots()fig = matplotlib.figure.Figure()得到的fig都是<matplotlib.figure.Figure object>,为什么None在后面的fig中被fig.canvas返回,因此在使用canvas.callbacks.connect时会出现错误?
  • 还有一个问题,我可以得到一个标签或值来指示工具栏中的缩放或平移按钮是激活还是非激活?当前的错误是单击工具栏按钮时连接被抑制,但鼠标光标仍停留在文本上。我可以获得的一种解决方案是使用text.set_label() 定义标签并检查OnHover 中的标签以识别是否激活了缩放或平移。如果是这样,请将inside 设置为False。但这似乎很冗长。有什么建议吗?
  • 第二个问题通过在激活缩放或平移按钮时使用figure.canvas.mpl_disconnect(cid) 断开'motion_notify_event' 来解决。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 2023-02-13
  • 2012-01-24
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
相关资源
最近更新 更多