Home>

There is a button calling the settings. And I want to make the button rotate (clockwise) on hover, and counterclockwise when moved away from it. Here's what's available:

code:

self.settingsButton= QPushButton (self)
        self.settingsButton.setIcon (QIcon ("Icons /settingsButton.png"))
        self.settingsButton.setToolTip ("Settings")
        self.settingsButton.setIconSize (QSize (35, 35))
        self.settingsButton.setStyleSheet (get_invisible_settingsButton_StyleSheet ())
        self.settingsButton.setCursor (QCursor (Qt.PointingHandCursor))
        self.settingsButton.clicked.connect (self.showSettingsWindow)
def showSettingsWindow (self):
        self.settings= SettingsWindow ()
        self.settings.move (
            self.x () + self.width () //2 -self.settings.width () //2,
            self.y () + self.height () //2 -self.settings.height () //2,
        )
        self.settings.show ()
def get_invisible_settingsButton_StyleSheet ():
    "" "Transparent settings button" ""
    return "" "
        QPushButton {
            background-color: rgba (255, 255, 255, 0);
        }
        QPushButton: hover {
            border-radius: 22px;
            background-color: rgba (100, 100, 100, 40);
        }
        QPushButton: pressed {
            background-color: rgba (0, 0, 0, 70);
        }
    "" "

please provide a minimum reproducible example

S. Nick2021-11-25 22:54:11
  • Answer # 1

    Alternatively:

    import os
    from PyQt5 import QtCore, QtGui, QtWidgets
    class Widget (QtWidgets.QWidget):
        def __init __ (self, parent= None):
            super (Widget, self) .__ init __ (parent)
            self.angle= 0
            self.val= 0
            self.i= 0
            self.image_fname= ('icons /back.png') # set a small image
            self.pushButton= QtWidgets.QPushButton ()
            self.pushButton.setObjectName ("pushButton")
            self.pushButton.setIcon (QtGui.QIcon (self.image_fname))
            self.pushButton.setIconSize (QtCore.QSize (80, 80))
            self.pushButton.installEventFilter (self)
            lay= QtWidgets.QVBoxLayout (self)
            lay.addWidget (self.pushButton, alignment= QtCore.Qt.AlignCenter)
            self.timer= QtCore.QTimer ()
            self.timer.timeout.connect (lambda: self.onRotate (self.val))
        def eventFilter (self, obj, event):
            if self.pushButton is obj:
                if event.type ()== QtCore.QEvent.Enter:
                    self.val= 1
                    self.timer.start (200)
                elif event.type ()== QtCore.QEvent.Leave:
                    self.val= -1
            return super (Widget, self) .eventFilter (obj, event)
        def onRotate (self, val= 0):
            self.i += val
            self.angle += 90 * val
            t= QtGui.QTransform (). rotate (self.angle)
            pix= QtGui.QPixmap (self.image_fname) .transformed (t)
            image_rotated= f '{os.path.splitext (self.image_fname) [0]} _ rotated.png'
            pix.save (image_rotated)
            self.pushButton.setIcon (QtGui.QIcon (image_rotated))
            if not self.i:
                self.timer.stop ()
    Stylesheet= '' '
    #PushButton {
        background-color: transparent;
        min-width: 96px;
        max-width: 96px;
        min-height: 96px;
        max-height: 96px;
        border-radius: 48px;
        border: 0px solid # 09009B;
        font-size: 24px;
    }
    #PushButton: hover: pressed {
        background-color: red;
        color: #fff;
    }
    #PushButton: hover {
        background-color: # 0ff;
        border: 2px solid # FFA6D5;
    }
    '' '
    if __name__== '__main__':
        import sys
        app= QtWidgets.QApplication (sys.argv)
        app.setStyleSheet (Stylesheet)
        w= Widget ()
        w.resize (200, 200)
        w.show ()
        sys.exit (app.exec_ ())
    

    @SkyGuy what's wrong?

    S. Nick2021-11-25 22:54:11

    @ s-nick I need a smooth animation. And also, so that after the cursor is hovered over it and it has rotated 90 degrees, it will stop rotating. And when the cursor was moved from the button. And she also smoothly returned to its original position. something like this. Only I need to do this in PyQt5

    SkyGuy2021-11-25 22:54:11
  • Answer # 2

    Alternatively:

    import os
    from PyQt5 import QtCore, QtGui, QtWidgets
    class Widget (QtWidgets.QWidget):
        def __init __ (self, parent= None):
            super (Widget, self) .__ init __ (parent)
            self.angle= 0
            self.val= 0
            self.i= 0
            self.image_fname= ('icons /back.png') # set a small image
            self.pushButton= QtWidgets.QPushButton ()
            self.pushButton.setObjectName ("pushButton")
            self.pushButton.setIcon (QtGui.QIcon (self.image_fname))
            self.pushButton.setIconSize (QtCore.QSize (80, 80))
            self.pushButton.installEventFilter (self)
            lay= QtWidgets.QVBoxLayout (self)
            lay.addWidget (self.pushButton, alignment= QtCore.Qt.AlignCenter)
            self.timer= QtCore.QTimer ()
            self.timer.timeout.connect (lambda: self.onRotate (self.val))
        def eventFilter (self, obj, event):
            if self.pushButton is obj:
                if event.type ()== QtCore.QEvent.Enter:
                    self.val= 1
                    self.timer.start (200)
                elif event.type ()== QtCore.QEvent.Leave:
                    self.val= -1
            return super (Widget, self) .eventFilter (obj, event)
        def onRotate (self, val= 0):
            self.i += val
            self.angle += 90 * val
            t= QtGui.QTransform (). rotate (self.angle)
            pix= QtGui.QPixmap (self.image_fname) .transformed (t)
            image_rotated= f '{os.path.splitext (self.image_fname) [0]} _ rotated.png'
            pix.save (image_rotated)
            self.pushButton.setIcon (QtGui.QIcon (image_rotated))
            if not self.i:
                self.timer.stop ()
    Stylesheet= '' '
    #PushButton {
        background-color: transparent;
        min-width: 96px;
        max-width: 96px;
        min-height: 96px;
        max-height: 96px;
        border-radius: 48px;
        border: 0px solid # 09009B;
        font-size: 24px;
    }
    #PushButton: hover: pressed {
        background-color: red;
        color: #fff;
    }
    #PushButton: hover {
        background-color: # 0ff;
        border: 2px solid # FFA6D5;
    }
    '' '
    if __name__== '__main__':
        import sys
        app= QtWidgets.QApplication (sys.argv)
        app.setStyleSheet (Stylesheet)
        w= Widget ()
        w.resize (200, 200)
        w.show ()
        sys.exit (app.exec_ ())
    

    @SkyGuy what's wrong?

    S. Nick2021-11-25 22:54:11

    @ s-nick I need a smooth animation. And also, so that after the cursor is hovered over it and it has rotated 90 degrees, it will stop rotating. And when the cursor was moved from the button. And she also smoothly returned to its original position. something like this. Only I need to do this in PyQt5

    SkyGuy2021-11-25 22:54:11