英文:
Tkinter dynamic tooltip that moves with the cursor and updates
问题
我想在我的tkinter
GUI 中实现一个tooltip
,具体是一个可以显示tk.Canvas
中matplot
绘图的x值的tooltip
,它会随着鼠标的移动而动态更新。
有一些好的示例(在这里)来创建一个tooltip
,但似乎都是更新tk.Label
或创建一个静态标签弹出窗口 - 没有跟随光标移动的。Matplotlib
有一个Cursor
类(文档),但它在绘图上绘制线条,而不显示数值。Tkinter
也有一个Cursor
类(文档),但它只是更改与相关小部件上的光标符号。我很高兴能够通过调用Canvas.canvasx
或类似的方法从绘图中获取x值,并将其发送到与鼠标相关联的某个东西(或者最坏的情况下,是一个静态的tk.Label
某处)。
以下是显示matplotlib.Cursor
功能和tkinter.Cursor
的代码。理想情况下,当鼠标移动时,会弹出一个tooltip
,显示0-8000之间的x值。
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
from matplotlib.figure import Figure
from matplotlib.widgets import Cursor
import numpy as np
root = tk.Tk()
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
figure = Figure(figsize=(5, 4), dpi=100)
plot = figure.add_subplot(1, 1, 1)
plot.plot(x, y, color="blue")
canvas = FigureCanvasTkAgg(figure, root)
canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
# 添加一个按钮来演示tkinter光标功能
B = tk.Button(root, text="Cursor", relief=tk.RAISED,
cursor="coffee_mug", width = 25)
B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
# matplotlib光标功能
cursor = Cursor(plot, useblit=True, horizOn=False, vertOn=True,
color="green", linewidth=2.0)
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.
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
from matplotlib.figure import Figure
from matplotlib.widgets import Cursor
import numpy as np
root = tk.Tk()
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
figure = Figure(figsize=(5, 4), dpi=100)
plot = figure.add_subplot(1, 1, 1)
plot.plot(x, y, color="blue")
canvas = FigureCanvasTkAgg(figure, root)
canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
# add button to demonstrate tkinter cursor function
B = tk.Button(root, text ="Cursor", relief=tk.RAISED,
cursor="coffee_mug", width = 25)
B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
# matplotlib cursor function
cursor = Cursor(plot, useblit=True, horizOn=False, vertOn=True,
color="green", linewidth=2.0)
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
:
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
from matplotlib.figure import Figure
from matplotlib.widgets import Cursor
import numpy as np
root = tk.Tk()
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, y, color="blue")
canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().grid(column=0, row=3, columnspan=4, pady=4, padx=4)
annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
bbox=dict(boxstyle="round", fc="w")
)
annot.set_visible(False)
def update_annot(x, y):
annot.xy = (x, y)
text = "x={}\ny={}".format(*annot.xy)
annot.set_text(text)
annot.get_bbox_patch().set_alpha(0.4)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
update_annot(event.xdata, event.ydata)
annot set_visible(True)
fig.canvas draw()
else:
if vis:
annot.set_visible(False)
fig.canvas draw()
fig.canvas mpl_connect("motion_notify_event", hover)
# add button to demonstrate tkinter cursor function
B = tk.Button(root, text="Cursor", relief=tk.RAISED,
cursor="coffee_mug", width=25)
B.grid(column=0, row=4, columnspan=5, padx=4, pady=4)
# matplotlib cursor function
cursor = Cursor(ax, useblit=True, horizOn=False, vertOn=True,
color="green", linewidth=2.0)
root.mainloop()
Output:
英文:
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
:
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
from matplotlib.figure import Figure
from matplotlib.widgets import Cursor
import numpy as np
root = tk.Tk()
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, y, color="blue")
canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().grid(column=0, row=3,columnspan=4,pady = 4, padx=4)
annot = ax.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
bbox=dict(boxstyle="round", fc="w")
)
annot.set_visible(False)
def update_annot(x, y):
annot.xy = (x, y)
text = "x={}\ny={}".format(*annot.xy)
annot.set_text(text)
annot.get_bbox_patch().set_alpha(0.4)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
update_annot(event.xdata,event.ydata)
annot.set_visible(True)
fig.canvas.draw()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw()
fig.canvas.mpl_connect("motion_notify_event", hover)
# add button to demonstrate tkinter cursor function
B = tk.Button(root, text ="Cursor", relief=tk.RAISED,
cursor="coffee_mug", width = 25)
B.grid(column = 0, row = 4, columnspan = 5, padx = 4, pady = 4)
# matplotlib cursor function
cursor = Cursor(ax, useblit=True, horizOn=False, vertOn=True,
color="green", linewidth=2.0)
root.mainloop()
Output:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论