PyQt5:如何为每个角色设置自定义鼠标指针?

8

1. 简介

我正在使用 Python 3.7PyQt5 创建一个应用程序。我希望自定义应用程序中的鼠标指针。

我们从 Qt5 中的标准光标集开始,如下表所示: https://doc.qt.io/qt-5/qt.html#CursorShape-enum。您会注意到,Qt5 具有专用枚举 Qt::CursorShape,描述相应光标的角色。例如:

Qt standard cursors

 
我想用 自定义的 光标来替换每个 标准 Qt 光标

Custom cursors

 

2. 第一种尝试

起初,我尝试了这样的代码:

pixmap = QPixmap("C:/../my_arrow.png")
cursor = QCursor(pixmap, 32, 32)
QApplication.setOverrideCursor(cursor)

很遗憾,这种方法不适合我的目的。根据文档:
应用程序覆盖光标是为了向用户显示应用程序处于特殊状态,例如在可能需要一些时间的操作期间。
覆盖光标将显示在所有应用程序的小部件中,直到调用restoreOverrideCursor()或另一个setOverrideCursor()。
换句话说,使用setOverrideCursor()方法有两个缺点:
1.我必须手动跟踪鼠标指针应更改为哪个角色,每次调用setOverrideCursor()并提供正确的QCursor()。
2.我需要追踪Qt自动调用restoreOverrideCursor()的位置,因为它有效地撤消了我的更改。这将是与Qt的持续斗争。
第二种方法是使用setCursor()函数进行尝试:
pixmap = QPixmap("C:/../Arrow.png")
cursor = QCursor(pixmap, 32, 32)
my_widget.setCursor(cursor)

我在顶层窗口小部件(QMainWindow())上执行此操作,从而使效果应用于整个应用程序。

这很好用,但它有一个缺点。此函数仅更改“默认光标”(指向箭头),但仅限如此。所有特殊光标仍然相同。

 
实际上,我想做这样的事情:

# Note: 'mainwin' is the QMainWindow().
mainwin.setCursor( QCursor(QPixmap("C:/../Arrow.png"),     32, 32), Qt.ArrowCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../UpArrow.png"),   32, 32), Qt.UpArrowCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../Cross.png"),     32, 32), Qt.CrossCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../Wait.png"),      32, 32), Qt.WaitCursor      )
mainwin.setCursor( QCursor(QPixmap("C:/../IBeam.png"),     32, 32), Qt.IBeamCursor     )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeVer.png"),   32, 32), Qt.SizeVerCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeHor.png"),   32, 32), Qt.SizeHorCursor   )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeBDiag.png"), 32, 32), Qt.SizeBDiagCursor )
mainwin.setCursor( QCursor(QPixmap("C:/../SizeFDiag.png"), 32, 32), Qt.SizeFDiagCursor )
...

不幸的是,setCursor()函数并不是这样工作的。

你有没有符合我的目的的解决方案?

4. 资源

我从以下资源中学到了很多:

不幸的是,它们都没有提供我问题的解决方案。我在这里提到它们,因为它们与我正在尝试做的事情相关,但并不相同。


在我看来,由于Qt的实现是在私有API中,因此更改光标是不可能的。 - eyllanesc
嗨@eyllanesc, 感谢您关注这个问题。让我们希望有一种方法可以解决它。老实说,我不知道怎么做 - 但这就是StackOverflow的用途 :-) - K.Mulier
这个链接也讨论了你想做的事情。他们的结论也是不可能实现。我认为一般的问题是操作系统绘制光标(我说得对吗?),当光标改变时,你无法得到通知或其他信息。 - Tim Körner
1个回答

2
# I'm coming```.

# 1. Set the cursor map
self.cursor_pix = QPixmap('exa.png')

# 2. Scale textures
self.cursor_scaled_pix = self.cursor_pix.scaled(QSize(20, 20), Qt.KeepAspectRatio)

# 3. Set cursor style and cursor focus position
self.current_cursor = QCursor(self.cursor_scaled_pix, -1, -1)

# 4. Set the cursor for the specified window
widget.setCursor(self.current_cursor)

2
请考虑解释您的代码。没有注释,代码对他人几乎没有任何价值。 - Simas Joneliunas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接