pythonpyqt5qsplitter

How to animate the splitter when setSizes() method is called?


I have the QSplitter widget in my Qt5 GUI, and there are two child widgets added to that splitter. and there is a QPushButton widget, when that button is pushed second child disappears and when again that button is pushed that child widget appears. but I want like expanding and collapsing of that child widget. but I have no idea how to animate the event when 'setSizes()' is called on the splitter widget.

can anybody provide me the code for that in pyqt5?

Here is my code

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(QtWidgets.QMainWindow):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(400, 300)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralWidget)
        self.verticalLayout.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")

        self.pushButton = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.clicked.connect(self.splitter_resize)
        self.pushButton.setCheckable(True)

        self.verticalLayout.addWidget(self.pushButton)

        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSpacing(6)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.pushButton_2 = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton_2.setObjectName("pushButton_2")

        self.pushButton_3 = QtWidgets.QPushButton(self.centralWidget)
        self.pushButton_3.setObjectName("pushButton_3")

        self.splitter = QtWidgets.QSplitter()
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.addWidget(self.pushButton_2)
        self.splitter.addWidget(self.pushButton_3)

        self.horizontalLayout.addWidget(self.splitter)

        self.verticalLayout.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralWidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def splitter_resize(self):
        if self.pushButton.isChecked():
            self.splitter.setSizes([16777215, 0])
            self.pushButton.setChecked = False
        else:
            self.splitter.setSizes([16777215, 16777215])
            self.pushButton.setChecked = True

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.pushButton_2.setText(_translate("MainWindow", "PushButton"))
        self.pushButton_3.setText(_translate("MainWindow", "PushButton"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Solution

  • You can use QVariantAnimation:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    MIN_SIZE, MAX_SIZE = 0, 16777215
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            button = QtWidgets.QPushButton(
                "Press me", checkable=True, toggled=self.onToggled
            )
            left_button = QtWidgets.QPushButton("Left")
            right_button = QtWidgets.QPushButton("Right")
    
            sp = right_button.sizePolicy()
            sp.setHorizontalPolicy(QtWidgets.QSizePolicy.Ignored)
            right_button.setSizePolicy(sp)
    
            self.m_splitter = QtWidgets.QSplitter(orientation=QtCore.Qt.Horizontal)
            self.m_splitter.addWidget(left_button)
            self.m_splitter.addWidget(right_button)
    
            widget = QtWidgets.QWidget()
            self.setCentralWidget(widget)
    
            lay = QtWidgets.QVBoxLayout(widget)
            lay.addWidget(button)
            lay.addWidget(self.m_splitter)
    
            self.m_animation = QtCore.QVariantAnimation(
                self,
                startValue=MAX_SIZE,
                endValue=MIN_SIZE,
                valueChanged=self.onValueChanged,
                duration=1000,
                easingCurve=QtCore.QEasingCurve.InOutCubic,
            )
    
        @QtCore.pyqtSlot(bool)
        def onToggled(self, checked):
            self.m_animation.setDirection(
                QtCore.QAbstractAnimation.Forward
                if checked
                else QtCore.QAbstractAnimation.Backward
            )
            self.m_animation.start()
    
        @QtCore.pyqtSlot(QtCore.QVariant)
        def onValueChanged(self, value):
            s = [MAX_SIZE, value]
            self.m_splitter.setSizes(s)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())