Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Keep animation/widget state on widget enter event



  • I've got a widget that is revealed when a button is under mouse and it is hidden on leaveEvent of the button unless the mouse enters the revealed widget. I tried something like the following , thought it is simple but doesn't work as intended and not sure what I'm missing.

    # coding=utf-8
    import os
    import sys
    
    from PySide6.QtCore import *
    from PySide6.QtGui import *
    from PySide6.QtWidgets import *
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
    
            self.main_container = QWidget(self)
            self.main_container.setGeometry(50, 0, self.width()-50, self.height())
    
            self.pop = QWidget(self)
            self.pop.setGeometry(-100, 0, 0, 0)
            self.pop.installEventFilter(self)
            self.pop.setStyleSheet("background: orange;")
            self.pop_anim = QPropertyAnimation(self.pop, b"geometry")
            self.pop.setObjectName("pop")
    
            self.but = QPushButton("H")
            self.but.setFixedHeight(50)
            self.but.setStyleSheet("background: green;")
            self.but.installEventFilter(self)
            self.but.setObjectName("but")
    
            self.sidebar = QWidget(self)
            self.sidebar.setGeometry(0, 0, 50, self.height())
            self.sidebar.setStyleSheet("background: black;")
    
            self.sidebar_lay = QHBoxLayout()
            self.sidebar_lay.setSpacing(0)
            self.sidebar_lay.setContentsMargins(0, 0, 0, 0)
            self.sidebar_lay.addWidget(self.but)
            self.sidebar_lay.setAlignment(self.but, Qt.AlignTop)
            self.sidebar.setLayout(self.sidebar_lay)
    
            self.resize(500, 500)
    
        def AnimPop(self, sx, ex, sw, ew):
            self.pop_anim.setStartValue(QRect(sx, 0, sw, 200))
            self.pop_anim.setEndValue(QRect(ex, 0, ew, 200))
            self.pop_anim.start()
    
        def eventFilter(self, obj, e):
            if e.type() == QEvent.Enter:
                if obj.objectName() == self.but.objectName():
                    self.but.setStyleSheet("background: orange;")
                    self.AnimPop(-100, 50, 100, 180)
                elif obj.objectName() == self.pop.objectName():
                    self.pop.setGeometry(self.pop.geometry())
    
            elif e.type() == QEvent.Leave:
                if obj.objectName() == self.but.objectName():
                    self.but.setStyleSheet("background: green;")
                    self.AnimPop(self.pop.x(), -100, 180, 100)
    
            return False
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        mw = MainWindow()
        mw.show()
        sys.exit(app.exec_())
    

    What I need is; the animated widget should stay in place if it is under mouse.


  • Lifetime Qt Champion

    Hi,

    You might want to rather do the hiding if the enter event is not of any of these two widgets and the widget is not already invisible.



  • @SGaist Something like

    if e.type() == QEvent.Enter:
                if obj.objectName() == self.main_container.objectName():
                  self.hidePop()
                    
    

    Am I understanding this correctly?


  • Lifetime Qt Champion

    I would have put the hide in the else after the elif within the EnterEvent handling.


Log in to reply