Tkinter 的 cursor 属性支持系统内置光标名,如"arrow"、"hand2"、"watch"、"xterm"、"crosshair"等,不继承、不报错容错,需按平台适配(如macOS需注意版本),且不支持自定义图片。

Tkinter 中 cursor 属性支持哪些值
Tkinter 的 cursor 不是任意字符串都能用,它依赖底层系统(X11 / Windows / macOS)提供的标准光标名称。硬写错名字不会报错,但光标不变——这是最常被忽略的“静默失败”。
常用值包括:"arrow"(默认)、"hand2"(推荐用于可点击区域,比 "hand1" 更通用)、"watch"(沙漏,Windows/macOS 都支持)、"xterm"(文本输入态)、"crosshair"(十字准星)。注意:"pointinghand" 是 Qt 用法,Tkinter 不识别;"pointer" 在部分旧版本 Tcl/Tk 中无效,优先用 "hand2"。
可通过 Tk().config(cursor="?") 查看当前环境支持的完整列表(会抛出 TclError 并打印所有可用名)。
给按钮、标签、画布等控件单独设置 cursor
几乎所有 Tkinter 控件都支持 cursor 参数,但行为有差异:按钮(Button)默认已有手型光标("hand2"),而 Label、Frame、Canvas 默认是箭头,需显式设置。
立即学习“Python免费学习笔记(深入)”;
常见误操作是只设父容器,结果子控件不继承——Tkinter 的 cursor **不继承**,必须逐个设置或通过绑定事件动态控制:
-
btn = Button(root, text="点我", cursor="hand2")—— 直接初始化时指定 -
label.config(cursor="hand2")—— 创建后修改 -
canvas.bind("<enter>", lambda e: canvas.config(cursor="crosshair"))</enter>—— 进入时切换,需配<leave></leave>恢复
全局鼠标样式切换(如加载中禁用交互)
想让整个窗口变成等待态,不要对每个控件循环设 cursor——直接改根窗口的 cursor 属性即可,子控件会自动响应(这是少数能“冒泡”的行为):
root.config(cursor="watch") root.update() # 确保立即生效 # ... 执行耗时操作 ... root.config(cursor="") # 清空即恢复默认
但要注意:cursor="" 是清空,不是设成 "arrow";如果之前手动设过其他值,清空后不一定回到初始状态(比如主窗口初始化时没设,但某个 Frame 设过 "hand2",清空 root 不影响该 Frame)。真正保险的做法是存档原始值再还原。
macOS 上 "hand2" 显示为箭头?
这是 Tcl/Tk 版本问题。macOS 自带的 Tk(8.5 或更老)不支持 "hand2",会退化为箭头。解决方案只有两个:
- 升级到 Tk 8.6+(推荐用
brew install python-tk或从 python.org 下载含新版 Tk 的 Python) - 降级兼容:用
"pointinghand"(仅 macOS)或"hand1"(跨平台但视觉稍弱),并加运行时检测:
import sys cursor_hand = "hand2" if sys.platform != "darwin" else "pointinghand" label.config(cursor=cursor_hand)
别指望靠 CSS 或自定义图片光标——Tkinter 的 cursor 只接受系统内置名,不支持文件路径或数据 URI。


















