Tkinter动态提示,跟随光标移动并更新

huangapple go评论103阅读模式
英文:

Tkinter dynamic tooltip that moves with the cursor and updates

问题

我想在我的tkinter GUI 中实现一个tooltip,具体是一个可以显示tk.Canvasmatplot绘图的x值的tooltip,它会随着鼠标的移动而动态更新。

有一些好的示例(在这里)来创建一个tooltip,但似乎都是更新tk.Label或创建一个静态标签弹出窗口 - 没有跟随光标移动的。Matplotlib有一个Cursor类(文档),但它在绘图上绘制线条,而不显示数值。Tkinter也有一个Cursor类(文档),但它只是更改与相关小部件上的光标符号。我很高兴能够通过调用Canvas.canvasx或类似的方法从绘图中获取x值,并将其发送到与鼠标相关联的某个东西(或者最坏的情况下,是一个静态的tk.Label某处)。

以下是显示matplotlib.Cursor功能和tkinter.Cursor的代码。理想情况下,当鼠标移动时,会弹出一个tooltip,显示0-8000之间的x值。

  1. import tkinter as tk
  2. from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
  3. from matplotlib.figure import Figure
  4. from matplotlib.widgets import Cursor
  5. import numpy as np
  6. root = tk.Tk()
  7. Fs = 8000
  8. f = 5
  9. sample = 8000
  10. x = np.arange(sample)
  11. y = np.sin(2 * np.pi * f * x / Fs)
  12. figure = Figure(figsize=(5, 4), dpi=100)
  13. plot = figure.add_subplot(1, 1, 1)
  14. plot.plot(x, y, color="blue")
  15. canvas = FigureCanvasTkAgg(figure, root)
  16. canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
  17. # 添加一个按钮来演示tkinter光标功能
  18. B = tk.Button(root, text="Cursor", relief=tk.RAISED,
  19. cursor="coffee_mug", width = 25)
  20. B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
  21. # matplotlib光标功能
  22. cursor = Cursor(plot, useblit=True, horizOn=False, vertOn=True,
  23. color="green", linewidth=2.0)
  24. root.mainloop()
英文:

I would like to implement a tooltip beside the cursor in my tkinter GUI - specifically one that would display the x value of a matplot plot in a tk.Canvas that moves with and updates dynamically as the mouse moves.

There are some good examples (here) in creating a tooltip, however everything seems to either updating a tk.Label or create a static label popup - nothing that moves with the cursor. Matplotlib has a Cursor class (docs) but that draws lines on the plot, and doesn't display values. Tkinter also has a Cursor class (docs), but that just changes the cursor symbol over the associated widget. I am happy I can get the x value from the plot via calling Canvas.canvasx or similar and send to something associated with the mouse (or worst case, a static tk.Label somewhere)

Below is code showing the matplotlib.Cursor functionality and the tkinter.Cursor. Ideally a tooltip pops up and shows x values between 0-8000 as the mouse moves.

  1. import tkinter as tk
  2. from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
  3. from matplotlib.figure import Figure
  4. from matplotlib.widgets import Cursor
  5. import numpy as np
  6. root = tk.Tk()
  7. Fs = 8000
  8. f = 5
  9. sample = 8000
  10. x = np.arange(sample)
  11. y = np.sin(2 * np.pi * f * x / Fs)
  12. figure = Figure(figsize=(5, 4), dpi=100)
  13. plot = figure.add_subplot(1, 1, 1)
  14. plot.plot(x, y, color="blue")
  15. canvas = FigureCanvasTkAgg(figure, root)
  16. canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
  17. # add button to demonstrate tkinter cursor function
  18. B = tk.Button(root, text ="Cursor", relief=tk.RAISED,
  19. cursor="coffee_mug", width = 25)
  20. B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
  21. # matplotlib cursor function
  22. cursor = Cursor(plot, useblit=True, horizOn=False, vertOn=True,
  23. color="green", linewidth=2.0)
  24. root.mainloop()

答案1

得分: 2

It seems you want to create your tooltip on the plot only. So I would suggest a slightly adapted/simplified version of this answer, ie using ax.annotate:

  1. import tkinter as tk
  2. from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
  3. from matplotlib.figure import Figure
  4. from matplotlib.widgets import Cursor
  5. import numpy as np
  6. root = tk.Tk()
  7. Fs = 8000
  8. f = 5
  9. sample = 8000
  10. x = np.arange(sample)
  11. y = np.sin(2 * np.pi * f * x / Fs)
  12. fig = Figure(figsize=(5, 4), dpi=100)
  13. ax = fig.add_subplot(1, 1, 1)
  14. line, = ax.plot(x, y, color="blue")
  15. canvas = FigureCanvasTkAgg(fig, root)
  16. canvas.get_tk_widget().grid(column=0, row=3, columnspan=4, pady=4, padx=4)
  17. annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
  18. bbox=dict(boxstyle="round", fc="w")
  19. )
  20. annot.set_visible(False)
  21. def update_annot(x, y):
  22. annot.xy = (x, y)
  23. text = "x={}\ny={}".format(*annot.xy)
  24. annot.set_text(text)
  25. annot.get_bbox_patch().set_alpha(0.4)
  26. def hover(event):
  27. vis = annot.get_visible()
  28. if event.inaxes == ax:
  29. update_annot(event.xdata, event.ydata)
  30. annot set_visible(True)
  31. fig.canvas draw()
  32. else:
  33. if vis:
  34. annot.set_visible(False)
  35. fig.canvas draw()
  36. fig.canvas mpl_connect("motion_notify_event", hover)
  37. # add button to demonstrate tkinter cursor function
  38. B = tk.Button(root, text="Cursor", relief=tk.RAISED,
  39. cursor="coffee_mug", width=25)
  40. B.grid(column=0, row=4, columnspan=5, padx=4, pady=4)
  41. # matplotlib cursor function
  42. cursor = Cursor(ax, useblit=True, horizOn=False, vertOn=True,
  43. color="green", linewidth=2.0)
  44. root.mainloop()

Output:

Tkinter动态提示,跟随光标移动并更新

英文:

It seems you want to create your tooltip on the plot only. So I would suggest a slightly adapted/simplified version of this answer, ie using ax.annotate:

  1. import tkinter as tk
  2. from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
  3. from matplotlib.figure import Figure
  4. from matplotlib.widgets import Cursor
  5. import numpy as np
  6. root = tk.Tk()
  7. Fs = 8000
  8. f = 5
  9. sample = 8000
  10. x = np.arange(sample)
  11. y = np.sin(2 * np.pi * f * x / Fs)
  12. fig = Figure(figsize=(5, 4), dpi=100)
  13. ax = fig.add_subplot(1, 1, 1)
  14. line, = ax.plot(x, y, color="blue")
  15. canvas = FigureCanvasTkAgg(fig, root)
  16. canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
  17. annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
  18. bbox=dict(boxstyle="round", fc="w")
  19. )
  20. annot.set_visible(False)
  21. def update_annot(x, y):
  22. annot.xy = (x, y)
  23. text = "x={}\ny={}".format(*annot.xy)
  24. annot.set_text(text)
  25. annot.get_bbox_patch().set_alpha(0.4)
  26. def hover(event):
  27. vis = annot.get_visible()
  28. if event.inaxes == ax:
  29. update_annot(event.xdata,event.ydata)
  30. annot.set_visible(True)
  31. fig.canvas.draw()
  32. else:
  33. if vis:
  34. annot.set_visible(False)
  35. fig.canvas.draw()
  36. fig.canvas.mpl_connect("motion_notify_event", hover)
  37. # add button to demonstrate tkinter cursor function
  38. B = tk.Button(root, text ="Cursor", relief=tk.RAISED,
  39. cursor="coffee_mug", width = 25)
  40. B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
  41. # matplotlib cursor function
  42. cursor = Cursor(ax, useblit=True, horizOn=False, vertOn=True,
  43. color="green", linewidth=2.0)
  44. root.mainloop()

Output:

Tkinter动态提示,跟随光标移动并更新

huangapple
  • 本文由 发表于 2023年3月1日 10:54:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599179.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定