I am trying hide two list widgets upon start by animating the maximum width to zero, then two buttons to toggle each widget to appear and disappear, this works fine, but not at start, only one of the two widget gets animated, the other just stays on, but the same command works fine when signaled by the push buttons.
Please suggest if there is any better approach to achieve the same effect or the reason behind it.
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import QPropertyAnimation
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(640, 480)
self.horizontalLayout = QtWidgets.QHBoxLayout(Form)
self.horizontalLayout.setObjectName("horizontalLayout")
self.frame = QtWidgets.QFrame(Form)
self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
self.frame.setObjectName("frame")
self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton = QtWidgets.QPushButton(self.frame)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.frame)
self.pushButton_2.setObjectName("pushButton_2")
self.verticalLayout.addWidget(self.pushButton_2)
self.pushButton_3 = QtWidgets.QPushButton(self.frame)
self.pushButton_3.setObjectName("pushButton_3")
self.verticalLayout.addWidget(self.pushButton_3)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.horizontalLayout.addWidget(self.frame)
self.listWidget = QtWidgets.QListWidget(Form)
self.listWidget.setObjectName("listWidget")
self.horizontalLayout.addWidget(self.listWidget)
self.listWidget_2 = QtWidgets.QListWidget(Form)
self.listWidget_2.setObjectName("listWidget_2")
self.horizontalLayout.addWidget(self.listWidget_2)
self.listWidget_3 = QtWidgets.QListWidget(Form)
self.listWidget_3.setObjectName("listWidget_3")
self.horizontalLayout.addWidget(self.listWidget_3)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
# Trying to Hide both widgets upon start, but one gets hidden
self.animate_listwidget2()
self.animate_listwidget3()
self.pushButton_2.clicked.connect(self.animate_listwidget2)
self.pushButton_3.clicked.connect(self.animate_listwidget3)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pushButton.setText(_translate("Form", "PushButton"))
self.pushButton_2.setText(_translate("Form", "toggle lw2"))
self.pushButton_3.setText(_translate("Form", "toggle lw3"))
def animate_listwidget2(self):
width = self.listWidget_2.width()
if width != 0:
width1 = 0
else:
width1 = 350
self.animation = QPropertyAnimation(self.listWidget_2, b'maximumWidth')
self.animation.setDuration(800)
self.animation.setStartValue(width)
self.animation.setEndValue(width1)
self.animation.setEasingCurve(QtCore.QEasingCurve.Type.Linear)
self.animation.start()
def animate_listwidget3(self):
width = self.listWidget_3.width()
if width != 0:
width1 = 0
else:
width1 = 350
self.animation = QPropertyAnimation(self.listWidget_3, b'maximumWidth')
self.animation.setDuration(800)
self.animation.setStartValue(width)
self.animation.setEndValue(width1)
self.animation.setEasingCurve(QtCore.QEasingCurve.Type.Linear)
self.animation.start()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec())
First of all you should not modify the code generated by QtDesigner since that could cause other bugs so to apply my solutions you have to restore the file and call it gui.py
The problem is that using the same attribute is destroying the previous animation.
There are several solutions such as changing the name of the attribute assigned to one of them (for example, changing the name of the second to self.animation2) but the implementation can still be improved since with the current one, animations are always being created unnecessarily since one is enough single for each QListWidget.
from PyQt6.QtCore import QEasingCurve, QPropertyAnimation
from PyQt6.QtWidgets import QApplication, QWidget
from gui import Ui_Form
class Form(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.pushButton_2.clicked.connect(self.animate_listwidget2)
self.ui.pushButton_3.clicked.connect(self.animate_listwidget3)
self.animation1 = self.build_animation(self.ui.listWidget_2)
self.animation2 = self.build_animation(self.ui.listWidget_3)
self.animate_listwidget2()
self.animate_listwidget3()
def build_animation(self, listwidget):
animation = QPropertyAnimation(listwidget, b"maximumWidth")
animation.setDuration(800)
animation.setEasingCurve(QEasingCurve.Type.Linear)
return animation
def start_animation(self, animation):
width = animation.targetObject().width()
animation.stop()
animation.setStartValue(width)
animation.setEndValue(0 if width != 0 else 350)
animation.start()
def animate_listwidget2(self):
self.start_animation(self.animation1)
def animate_listwidget3(self):
self.start_animation(self.animation2)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = Form()
w.show()
sys.exit(app.exec())