Home > Blockchain >  Handle mousePressEvent and leaveEvent of QPushButton at the same time
Handle mousePressEvent and leaveEvent of QPushButton at the same time

Time:06-27

I have a pushButton and want to have a specific behaviour while users interact with that button.

Here is what I want:

  1. user pressed on the button (Without release)
  2. Then the user moved the cursor outside the button (Still the mouse is not released yet).

So, the button should take an active icon and whenever he points outside the button that icon should be changed to inactive-icon

Here is what I get:

I made my own QPushButton and overridden both (leaveEvent(), mouseReleaseEvent(), mousePressEvent()), But the problem is that after the user press and keep pressing on that button no other events are handled, So I need a way to handle other events like the leaveEvent()

Here is my own button class:

class ToggledButton(QPushButton):

    def __init__(self, icon: QIcon = None, active_icon: QIcon = None):
        super(ToggledButton, self).__init__()
        self.active_icon= active_icon
        self.inactive_icon = icon
        self.setIcon(icon)
        self.setCheckable(True)
        self.setFlat(False)

    def leaveEvent(self, event):
        super(ToggledButton, self).leaveEvent(event)
        self.setIcon(self.inactive_icon )

    def mousePressEvent(self, event):
        super(ToggledButton, self).mousePressEvent(event)
        self.setIcon(self.active_icon)

    def mouseReleaseEvent(self, event):
        super(ToggledButton, self).mouseReleaseEvent(event)
        self.setIcon(self.inactive_icon )

CodePudding user response:

When a widget receives a mouse button press, it normally becomes the mouse grabber. When that happens, no widget will ever receive an enter or leave event, including that same widget.

A widget that is the mouse grabber will always receive mouse move events, so that is the function that you need to override:

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        if event.buttons() == Qt.LeftButton:
            if event.pos() in self.rect():
                self.setIcon(self.active_icon)
            else:
                self.setIcon(self.inactive_icon)

Note: you should check the button() in the mouse press event, otherwise it will change icon also when the user presses a different mouse button:

    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        if event.button() == Qt.LeftButton:
            self.setIcon(self.active_icon)

Note the difference between buttons() (the pressed mouse buttons at the time of the event) and button(), which is the mouse button that caused the event, which is obviously meaningless for mouse move events, since the event is not caused by mouse buttons but by the movement.

  • Related