如何在Matplotlib结合Tkinter时保持默认光标状态?
问题描述
我正在使用Matplotlib搭配Tkinter开发,代码如下:
from tkinter import * import matplotlib.pyplot as plt from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk root = Tk() graph_frame=Frame(root,bg="red",height=10,width=10) graph_frame.pack(side=TOP) fig = Figure(figsize=(5, 4), dpi=100) a=fig.add_subplot(1,1,1) x = [1,3,12,15,1] y = [10,9,8,55,19] a.plot(x,y) canvas = FigureCanvasTkAgg(fig, master=graph_frame) # A tk.DrawingArea. canvas.draw() canvas.get_tk_widget().pack(side=TOP, expand=1) toolbar = NavigationToolbar2Tk(canvas, graph_frame) # toolbar toolbar.update() canvas.get_tk_widget().pack(side=TOP, expand=1) root.mainloop()
当点击缩放(zoom)或平移(pan)按钮时,光标会变为放大镜或十字移动光标,我希望光标始终保持默认模式,请问该如何实现?
解决方案
提供两种简单有效的实现方式:
方法1:重写工具栏的光标设置方法
自定义继承自NavigationToolbar2Tk的工具栏类,重写set_cursor方法,彻底阻止工具栏修改光标:
from tkinter import * import matplotlib.pyplot as plt from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk # 自定义工具栏,禁用光标切换逻辑 class CustomToolbar(NavigationToolbar2Tk): def set_cursor(self, cursor): # 空实现,不执行任何光标修改操作 pass root = Tk() graph_frame=Frame(root,bg="red",height=10,width=10) graph_frame.pack(side=TOP) fig = Figure(figsize=(5, 4), dpi=100) a=fig.add_subplot(1,1,1) x = [1,3,12,15,1] y = [10,9,8,55,19] a.plot(x,y) canvas = FigureCanvasTkAgg(fig, master=graph_frame) canvas.draw() canvas.get_tk_widget().pack(side=TOP, expand=1) # 使用自定义工具栏替代默认工具栏 toolbar = CustomToolbar(canvas, graph_frame) toolbar.update() canvas.get_tk_widget().pack(side=TOP, expand=1) root.mainloop()
方法2:绑定画布事件强制重置光标
通过监听鼠标进入画布的事件,强制将光标设置为默认箭头:
from tkinter import * import matplotlib.pyplot as plt from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk root = Tk() graph_frame=Frame(root,bg="red",height=10,width=10) graph_frame.pack(side=TOP) fig = Figure(figsize=(5, 4), dpi=100) a=fig.add_subplot(1,1,1) x = [1,3,12,15,1] y = [10,9,8,55,19] a.plot(x,y) canvas = FigureCanvasTkAgg(fig, master=graph_frame) canvas.draw() canvas_widget = canvas.get_tk_widget() canvas_widget.pack(side=TOP, expand=1) # 强制光标为默认箭头 def reset_cursor(event): canvas_widget.config(cursor="arrow") canvas_widget.bind("<Enter>", reset_cursor) toolbar = NavigationToolbar2Tk(canvas, graph_frame) toolbar.update() canvas_widget.pack(side=TOP, expand=1) root.mainloop()
说明
- 方法1从根源上禁用了所有工具栏的光标切换逻辑,是最彻底的方案;
- 方法2通过事件监听补强制重置光标,适合不需要完全修改工具栏逻辑的场景。
内容的提问来源于stack exchange,提问作者cak3_lover
相关产品推荐
相关产品推荐

