如何在Python中修改系统鼠标光标?Tkinter跨窗口十字光标设置
解决Tkinter全局设置十字光标问题
你遇到的hcur未定义错误,是因为没有先加载十字光标的句柄。要实现全局(窗口内外都生效)的十字光标,需要借助Windows API加载系统光标资源,再替换系统默认箭头光标,同时要注意退出时恢复原光标,避免影响系统全局光标。
完整实现代码
import tkinter as tk import ctypes from ctypes import wintypes # 定义Windows API相关常量与函数 user32 = ctypes.windll.user32 IDC_ARROW = 32515 # 默认箭头光标ID IDC_CROSS = 32512 # 十字光标ID # 声明API函数的参数和返回值类型,避免ctypes类型错误 user32.LoadCursorW.argtypes = [wintypes.HINSTANCE, wintypes.LPCWSTR] user32.LoadCursorW.restype = wintypes.HCURSOR user32.SetSystemCursor.argtypes = [wintypes.HCURSOR, wintypes.UINT] user32.SetSystemCursor.restype = wintypes.BOOL user32.CopyImage.argtypes = [wintypes.HANDLE, wintypes.UINT, wintypes.INT, wintypes.INT, wintypes.UINT] user32.CopyImage.restype = wintypes.HANDLE user32.DestroyCursor.argtypes = [wintypes.HCURSOR] user32.DestroyCursor.restype = wintypes.BOOL def set_global_cross_cursor(): # 加载系统内置十字光标 cross_cursor = user32.LoadCursorW(0, IDC_CROSS) if not cross_cursor: raise RuntimeError(f"加载十字光标失败,错误码: {ctypes.GetLastError()}") # 复制原箭头光标(SetSystemCursor会接管光标句柄,直接用原句柄恢复会失效) global original_cursor original_cursor = user32.CopyImage(user32.LoadCursorW(0, IDC_ARROW), 2, 0, 0, 0x4000) # 替换系统默认箭头光标为十字型 user32.SetSystemCursor(cross_cursor, IDC_ARROW) def restore_original_cursor(): # 程序退出时恢复原系统光标 if 'original_cursor' in globals() and original_cursor: user32.SetSystemCursor(original_cursor, IDC_ARROW) user32.DestroyCursor(original_cursor) # 初始化Tkinter窗口 root = tk.Tk() root.title("屏幕截取工具") root.geometry("300x100") # 启动时设置全局十字光标 set_global_cross_cursor() # 绑定窗口关闭事件,确保恢复原光标 root.protocol("WM_DELETE_WINDOW", lambda: (restore_original_cursor(), root.destroy())) # 示例按钮:模拟截取启动逻辑 start_btn = tk.Button(root, text="开始拖拽截取", command=lambda: print("进入屏幕截取模式")) start_btn.pack(pady=20) root.mainloop()
关键说明
LoadCursorW(0, IDC_CROSS):从系统资源中加载预定义的十字光标,第一个参数传0表示使用系统内置资源。CopyImage:必须复制原光标句柄,因为SetSystemCursor会接管传入的光标资源,直接使用原句柄恢复会导致资源释放错误。- 必须在程序退出时调用
restore_original_cursor,否则系统光标会一直保持十字型,直到其他程序修改或系统重启。
内容的提问来源于stack exchange,提问作者josephyumss
相关产品推荐
相关产品推荐

