Из описания QPropertyAnimation:
QPropertyAnimation выполняет интерполяцию по свойствам Qt. Поскольку значения свойств хранятся в QVariant, класс наследует QVariantAnimation и поддерживает анимацию тех же метатипов, что и его суперкласс.
Класс, объявляющий свойства, должен быть QObject. Чтобы свойство можно было анимировать, оно должно предоставлять установщик (чтобы QPropertyAnimation мог установить значение свойства).
Все классы, которые унаследованы от QObject (включая виджеты), поддерживают свойства Qt, и на самом деле большинство из них имеют встроенные свойства, но, очевидно, не все свойства поддерживают анимацию: они должны основываться на числовых значениях. Вы можете анимировать числовое изменение (например, от 0 до 100), а не текст (например, с «ABC» на «PYZ»).
Например, все QWidget имеют свойство pos
, и поскольку такое свойство (которое является QPoint) основано на числах, вы можете создать анимацию. Вы можете увидеть список поддерживаемых типов вариантов для анимации в документах QVariantAnimation. Учтите, что все страницы документации, касающиеся подклассов QObject, содержат раздел property (см. свойства QWidget), и эти свойства, очевидно, унаследованы от своих суперклассов.
Однако для шрифта size нет свойства, поэтому есть две возможности:
- создать пользовательское свойство (используя декоратор
pyqtProperty
в PyQt);
- используйте QVariantAnimation, который не привязан к какому-либо свойству;
В зависимости от ситуации можно предпочесть тот или иной подход, но для данного конкретного случая это не сильно меняется; QVariantAnimation, безусловно, проще, подход свойств Qt более совместим.
Здесь вы можете увидеть, как создается свойство с помощью декоратора 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_())
Анимация варианта конечно короче:
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)
Учтите, что анимация размера шрифта часто проблематична, так как большинство шрифтов имеют немного разные глифы и интервалы в зависимости от размера. В приведенных выше примерах я использовал довольно длинную анимацию, которая, вероятно, покажет эффект: в то время как размер увеличивается линейно, изменение шрифта обычно не очень плавное.
person
musicamante
schedule
25.06.2021