代码之家  ›  专栏  ›  技术社区  ›  Spencer

小部件属性动画期间qt调整布局

  •  1
  • Spencer  · 技术社区  · 6 年前

    我有一个现有的应用程序,我正在抛光,我想添加一些动画到一些小部件。在布局之外使用qpropertyanimation设置小部件的动画是容易和有趣的,但是当它们在布局中时,我会遇到各种困难。当前让我头疼的是,当我设置小部件大小的动画时,布局没有调整到新的大小。

    假设我有一个带有三个小部件的qvboxlayout:一个应该扩展到所有可用空间的标签、一个树视图和一个按钮。当我点击按钮时,我想让树倒塌,让标签占据它的空间。下面是代码中的这个示例,正如您所看到的,当树设置动画时,它的大小不会发生任何变化,然后当我在动画结束时隐藏它时,标签会弹出以填充现在的空白空间。因此,在动画期间,布局似乎不知道树正在调整大小。我想发生的是,当树缩小时,标签会展开以填充它。

    这不是通过标签的绝对大小来实现的,而是通过调用布局上的大小调整或类似的方法来实现的吗?我这样问是因为我想在我的应用程序中设置几个小部件的动画,我想找到最好的方法来做到这一点,而不必让太多的小部件相互依赖。

    示例代码:

    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class AnimatedWidgets(QtGui.QWidget):
        def __init__(self):
            super(AnimatedWidgets, self).__init__()
    
            layout1 = QtGui.QVBoxLayout()
            self.setLayout(layout1)
    
            expanding_label = QtGui.QLabel("Expanding label!")
            expanding_label.setStyleSheet("border: 1px solid red")
            layout1.addWidget(expanding_label)
    
            self.file_model = QtGui.QFileSystemModel(self)
            sefl.file_model.setRootPath("C:/")
            self.browse_tree = QtGui.QTreeView()
            self.browse_tree.setModel(self.file_model)
            layout1.addWidget(self.browse_tree)
    
            shrink_tree_btn = QtGui.QPushButton("Shrink the tree")
            shrink_tree_btn.clicked.connect(self.shrink_tree)
            layout1.addWidget(shrink_tree_btn)
    
            #--
    
            self.tree_size_anim = QtCore.QPropertyAnimation(self.browse_tree, "size")
            self.tree_size_anim.setDuration(1000)
            self.tree_size_anim.setEasingCurve(QtCore.QEasingCurve.InOutQuart)
            self.tree_pos_anim = QtCore.QPropertyAnimation(self.browse_tree, "pos")
            self.tree_pos_anim.setDuration(1000)
            self.tree_pos_anim.setEasingCurve(QtCore.QEasingCurve.InOutQuart)
            self.tree_anim_out = QtCore.QParallelAnimationGroup()
            self.tree_anim_out.addAnimation(self.tree_size_anim)
            self.tree_anim_out.addAnimation(self.tree_pos_anim)
    
        def shrink_tree(self):
            self.tree_size_anim.setStartValue(self.browse_tree.size())
            self.tree_size_anim.setEndValue(QtCore.QSize(self.browse_tree.width(), 0))
    
            tree_rect = self.browse_tree.geometry()
            self.tree_pos_anim.setStartValue(tree_rect.topLeft())
            self.tree_pos_anim.setEndValue(QtCore.QPoint(tree_rect.left(), tree_rect.bottom()))
    
            self.tree_anim_out.start()
            self.tree_anim_out.finished.connect(self.browse_tree.hide)
    
    def main():
        app = QtGui.QApplication(sys.argv)
        ex = AnimatedWidgets()
    
        ex.show()
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   eyllanesc Yonghwan Shin    6 年前

    布局处理 geometry() 当想要改变 pos 属性这些属性与它们的句柄交互,因此很常见的是,您会得到这种类型的行为,更好的选择是使用 QVariantAnimation 要确定固定高度:

    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class AnimatedWidgets(QtGui.QWidget):
        def __init__(self):
            super(AnimatedWidgets, self).__init__()
    
            layout1 = QtGui.QVBoxLayout(self)
    
            expanding_label = QtGui.QLabel("Expanding label!")
            expanding_label.setStyleSheet("border: 1px solid red")
            layout1.addWidget(expanding_label)
    
            self.file_model = QtGui.QFileSystemModel(self)
            self.file_model.setRootPath(QtCore.QDir.rootPath())
            self.browse_tree = QtGui.QTreeView()
            self.browse_tree.setModel(self.file_model)
            layout1.addWidget(self.browse_tree)
    
            shrink_tree_btn = QtGui.QPushButton("Shrink the tree")
            shrink_tree_btn.clicked.connect(self.shrink_tree)
            layout1.addWidget(shrink_tree_btn)
            #--
            self.tree_anim = QtCore.QVariantAnimation(self)
            self.tree_anim.setDuration(1000)
            self.tree_anim.setEasingCurve(QtCore.QEasingCurve.InOutQuart)
    
        def shrink_tree(self):
            self.tree_anim.setStartValue(self.browse_tree.height())
            self.tree_anim.setEndValue(0)
            self.tree_anim.valueChanged.connect(self.on_valueChanged)
            self.tree_anim.start()
    
        def on_valueChanged(self, val):
            h, isValid = val.toInt()
            if isValid:
                self.browse_tree.setFixedHeight(h)
    
    def main():
        app = QtGui.QApplication(sys.argv)
        ex = AnimatedWidgets()
    
        ex.show()
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()