You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:42:24