Windows 上 Tkinter 的自定义鼠标光标

Custom Mouse Cursor for Tkinter on Windows

我正在尝试使用 tkinter 制作一款游戏,该游戏将拥有自己的特殊鼠标。我已经看到很多桌面游戏使用这个并且看到了相关问题但是不知道如何为 windows 和 python 做 3. 我尝试做 root['cursor']="@mouse.cur" 但我收到此错误:

Traceback (most recent call last):
  File "C:/Python32/game.py", line 4, in <module>
    root["cursor"]="@mouse.cur"
  File "C:\Python32\lib\tkinter\__init__.py", line 1200, in __setitem__
    self.configure({key: value})
  File "C:\Python32\lib\tkinter\__init__.py", line 1193, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Python32\lib\tkinter\__init__.py", line 1184, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: bad cursor spec "@mouse.cur"

我在同一目录中有一个名为 mouse.cur 的文件,尺寸正确 (32x32) 并且没有损坏。有人可以告诉我是否应该将它放入某种子文件夹中或以其他方式进行。提前致谢。

Windows 10, Python 3.2.2

我无法在我拥有的任何 Win 系统上重现您的问题。然而,尽管有模糊的错误 _tkinter.TclError: bad cursor spec "@mouse.cur",您仍然可以找到您的问题。

"bad cursor spec" 错误发生在 TkGetCursorByName 函数内部:

...
if (argv[0][0] == '@') {

    ...

    cursorPtr->winCursor = LoadCursorFromFile(&(argv[0][1]));
} else {

    ...

}

if (cursorPtr->winCursor == NULL) {
    ckfree((char *) cursorPtr);
    badCursorSpec:
    ckfree((char *) argv);
    Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"",
        (char *) NULL);
    return NULL;
} else {
    ckfree((char *) argv);
    return (TkCursor *) cursorPtr;
}
...

如您所见,问题源于 LoadCursorFromFile,这是针对这种情况的标准 WinAPI 函数。

我假设 LoadCursorFromFile(&(argv[0][1])); 会产生 Null 结果,因此 cursorPtr->winCursor == NULL 的计算结果为 True,因此会出现错误。

但是,我们可以在tkinter之外调用这个函数,并检查错误:

import ctypes

get_error = ctypes.windll.kernel32.GetLastError
load_cursor = ctypes.windll.user32.LoadCursorFromFileW

cur_handle = load_cursor('mouse.cur')
err = get_error()

print('cursor handle:\t%s, '
      'err no:\t%d, '
      'err desc:\t%s' % (cur_handle, err, ctypes.FormatError(err)))
  • cur_handle 不是 0 (Null),err0 - 不是我们的情况
  • cur_handle0 (Null),err2 - 仔细检查名称和路径
  • cur_handle0 (Null),err0 - 可能是 GDI/User 对象泄漏(句柄耗尽)
  • cur_handle0 (Null),err8 - 绝对是 GDI/User 对象泄漏

尝试使用

root.config(cursor="crosshair")

此外,以下 link 可能会为您提供不同类型的可用游标: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/cursors.html

如果这也不起作用,请告诉我。乐于助人。