在 PyQt5 中动画 QLabel 的字体大小

问题描述

我想问一下我们是否可以使用 QPropertyAnimation 为 PyQt5 中的 QLabel 的字体大小设置动画。

我尝试添加 QPropertyAnimation(self.label,b"fontSize") 但它不起作用并且我收到警告

我希望你增加 QLabel 的文本,然后再次切换到正常大小

解决方法

来自QPropertyAnimation description

QPropertyAnimation 在 Qt properties 上进行插值。由于属性值存储在 QVariants 中,该类继承了 QVariantAnimation,并支持与其超类相同元类型的动画。

声明属性的类必须是 QObject。为了可以为属性设置动画,它必须提供一个 setter(以便 QPropertyAnimation 可以设置属性的值)。

所有继承自 QObject 的类(包括小部件)都支持 Qt 属性,实际上它们中的大多数都有“内置”属性,但显然,并非所有属性都支持动画:它们必须基于数值。您可以为数字变化(例如:从 0 到 100)而不是文本(例如从“ABC”到“PYZ”)设置动画。

例如,所有 QWidget 都有一个 pos 属性,并且由于该属性(即 QPoint)是基于数字的,因此您可以创建动画。您可以在 QVariantAnimation docs 中查看动画支持的变体类型列表。考虑到所有关于 QObject 子类的文档页面都包含一个 property 部分(例如参见 QWidget properties),并且这些属性显然是从它们的超类继承的。

虽然没有字体size的属性,所以有两种可能性:

  1. 创建自定义属性(通过使用 PyQt 中的 library(tidyverse) expand_grid(one = c("A","T","C","G"),two = "NG") %>% mutate(three = paste0(one,two)) %>% pull(three) [1] "ANG" "TNG" "CNG" "GNG" 装饰器);
  2. 使用未绑定到任何属性的 QVariantAnimation;

根据情况,人们可能更喜欢一种方法或另一种方法,但对于这种特定情况,它并没有太大变化; QVariantAnimation当然更简单,Qt属性方法更“合规”。

在这里您可以看到如何使用 pyqtProperty 装饰器创建属性。由于动画写入属性,因此必须使用 setter。

pyqtProperty

变体动画肯定更短:

class AnimationTest(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.startButton = QtWidgets.QPushButton('Start')
        self.label = QtWidgets.QLabel('Hello!')
        self.labelFont = self.font()
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.startButton)
        layout.addWidget(self.label)

        self.ani = QtCore.QPropertyAnimation(self,b'labelFontSize')
        self.ani.setStartValue(10)
        self.ani.setEndValue(80)
        self.ani.setDuration(1500)

        self.startButton.clicked.connect(self.ani.start)

    @QtCore.pyqtProperty(int)
    def labelFontSize(self):
        return self.labelFont.pointSize()

    @labelFontSize.setter
    def labelFontSize(self,size):
        self.labelFont.setPointSize(size)
        self.label.setFont(self.labelFont)


import sys
app = QtWidgets.QApplication(sys.argv)
test = AnimationTest()
test.show()
sys.exit(app.exec_())

请注意,字体大小动画通常是有问题的,因为大多数字体的字形和间距根据大小略有不同。在上面的例子中,我使用了一个很长的动画,可能会显示效果:虽然大小线性增加,但字体的变化通常不是很平滑。