Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt5: How to set a custom mouse pointer for each role?

1. Intro

I'm creating an application in Python 3.7 with PyQt5 for the GUI. I would like to customize the mouse cursors in the application.

Let's start from the standard cursor set in Qt5 as shown in a table here: https://doc.qt.io/qt-5/qt.html#CursorShape-enum. You will notice that Qt5 has a dedicated Enum Qt::CursorShape describing the role of the corresponding cursor. For example:

Qt standard cursors

 
I would like to replace each Standard Qt cursor with a custom made one:

Custom cursors

 

2. First approach

At first I tried something like this:

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

Unfortunately, this approach is not good for my purpose. From the documentation:

Application override cursors are intended for showing the user that the application is in a special state, for example during an operation that might take some time.
 
The override cursor will be displayed in all the application's widgets until restoreOverrideCursor() or another setOverrideCursor() is called.

In other words, using the setOverrideCursor() approach has two downsides:

  1. I would have to track manually to which role the mouse pointer should change, call setOverrideCursor() each time and feed it with the proper QCursor().

  2. I'd need to track wherever Qt automatically calls restoreOverrideCursor(), because that effectively undoes my own changes. It would be a constant battle against Qt.

 

3. Second approach

My second approach was playing around with the setCursor() function:

pixmap = QPixmap("C:/../Arrow.png")
cursor = QCursor(pixmap, 32, 32)
my_widget.setCursor(cursor)

I do this on the toplevel widget - the QMainWindow() - such that the effect is applied on the whole application.

It works great, but it has one downside. This function only changes the "default cursor" (the pointing arrow) but that's it. All the special cursors are still the same.

 
In fact, I would like to do something like this:

# 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 )
...

Unfortunately, that's not how the setCursor() function works.

 
Do you have a solution that matches best my purpose?

 

4. Resources

I've learned a lot from the following sources:

  • Default mouse icons for Qt applications

  • Is there a way to create a custom animated / gif QCursor?

Unfortunately, none of them provided the solution to my problem. I just mention them here, because they are related to - but not the same as(!) - what I'm trying to do.

like image 489
K.Mulier Avatar asked May 15 '19 08:05

K.Mulier


People also ask

How do I set a default pointer scheme?

In the Registry Editor, navigate to HKEY_CURRENT_USER > Control Panel > Cursors. To Select a Pointer Scheme, double-click the (Default) string value in the right-hand side panel. By default, the value data for this string will be Windows Default.

How do I create a custom cursor in QQT?

Qt has a number of standard cursor shapes, but you can also make custom cursor shapes based on a QBitmap, a mask and a hotspot. To associate a cursor with a widget, use setCursor().

How do I trigger the mouse press event in PyQt?

If your object is inherited from a standard widget, it will likely have sensible behavior implemented by default. You can trigger this by calling up to the parent implementation using super (). This is the Python parent class, not the PyQt .parent (). def mousePressEvent(self, event): print ( "Mouse pressed!"

Can you customize a mouse pointer on Windows 11?

The mouse pointer is arguably the most useful feature of a standard operating system. While the mouse pointer has a default shape and size, Windows allows a user to customize and change this entirely. If you want to add some flair to your PC, here is how you can customize a mouse cursor on Windows 11.

What is PyQt5 and why should I use it?

PyQt5 is one of the most advanced GUI library for Python. While being powerful, it’s also well structured and makes it easy for you to build ‘advanced’ items. Custom widgets in PyQt5 is a breeze.


1 Answers

# 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)
like image 55
parzulpan Avatar answered Oct 18 '22 10:10

parzulpan