python - PyQt5 中 QLabel 的 FontSize 动画
问题描述
我想问一下我们是否可以使用 QPropertyAnimation 为 PyQt5 中 QLabel 的字体大小设置动画。
我尝试添加QPropertyAnimation(self.label , b"fontSize")
,但它不起作用,我收到了警告
我希望你增加 QLabel 的文本,然后再次切换到正常大小
解决方案
QPropertyAnimation 对Qt 属性进行插值。由于属性值存储在QVariants中,因此该类继承QVariantAnimation并支持与其超类相同的元类型的动画。
声明属性的类必须是 QObject。为了使属性动画成为可能,它必须提供一个设置器(以便 QPropertyAnimation 可以设置属性的值)。
所有从 QObject 继承的类(包括小部件)都支持 Qt 属性,实际上它们中的大多数都有“内置”属性,但显然,并非所有属性都支持动画:它们必须基于数值。您可以动画数字变化(例如:从 0 到 100),而不是文本(例如,从 'ABC' 到 'PYZ')。
例如,所有 QWidget 都有一个pos
属性,并且由于该属性(即 QPoint)是基于数字的,因此您可以创建动画。您可以在QVariantAnimation 文档中查看支持的动画变体类型列表。考虑到所有关于 QObject 子类的文档页面都包含一个属性部分(例如,参见QWidget 属性),并且这些属性显然是从它们的超类继承的。
但是,字体大小没有属性,因此有两种可能性:
- 创建一个自定义属性(通过使用
pyqtProperty
PyQt 中的装饰器); - 使用不绑定到任何属性的 QVariantAnimation;
根据具体情况,人们可能更喜欢一种方法或另一种方法,但对于这种特定情况,它并没有太大变化;QVariantAnimation 当然更简单,Qt 属性方法更“兼容”。
在这里,您可以看到如何使用 pyqtProperty 装饰器创建属性。由于动画会写入属性,因此必须有一个 setter。
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_())
变体动画肯定更短:
class AnimationTest(QtWidgets.QWidget):
def __init__(self):
# ...
self.ani = QtCore.QVariantAnimation()
self.ani.setStartValue(10)
self.ani.setEndValue(80)
self.ani.setDuration(1500)
self.ani.valueChanged.connect(self.updateLabelFont)
self.startButton.clicked.connect(self.ani.start)
def updateLabelFont(self, value):
self.labelFont.setPointSize(value)
self.label.setFont(self.labelFont)
请考虑字体大小动画通常是有问题的,因为大多数字体的字形和间距根据大小略有不同。在上面的示例中,我使用了一个很长的动画,可能会显示效果:虽然大小线性增加,但字体的变化通常不是很平滑。
推荐阅读
- java - 最大/最小输出没有展示正确的价值
- c# - 尝试在所有屏幕上显示屏幕保护程序,仅在一个屏幕上显示
- node.js - 定义无限循环以从 API 读取数据并与数据库进行比较的最佳位置
- sql - 在另一列中选择具有相同 id 但相同值的行
- coq - 用 list_beq 证明列表的相等性
- magento2 - Magento 2 自定义控制台命令创建具有角色的管理员用户,Laminas 服务定位器问题
- database - 为什么 laradock 为不同的项目使用一个数据库?
- node.js - 错误 [ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置标头 | NodeJS ExpressJS MySQL
- ruby-on-rails - 如何在 Rails 中加密 csv/xlsx 文件
- python - AES 128 如何在 python 中使用部分密钥进行暴力破解