1

我正在尝试通过将最大宽度设置为零来隐藏两个列表小部件,然后通过两个按钮来切换每个小部件以显示和消失,这工作正常,但不是在开始时,只有两个小部件中的一个被动画化,另一个只是保持打开状态,但是当按钮发出信号时,相同的命令可以正常工作。

请提出是否有更好的方法来达到相同的效果或背后的原因。

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())
4

1 回答 1

1

首先,您不应该修改 QtDesigner 生成的代码,因为这可能会导致其他错误,因此要应用我的解决方案,您必须恢复文件并将其命名为 gui.py

问题是使用相同的属性会破坏之前的动画。

有几种解决方案,例如更改分配给其中一个的属性的名称(例如,将第二个的名称更改为 self.animation2),但仍然可以改进实现,因为使用当前的,总是会创建动画不必要的,因为每个 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())
于 2021-07-31T07:39:58.950 回答