Анимация FontSize QLabel в PyQt5

Я хотел спросить, можем ли мы просто анимировать размер шрифта QLabel в PyQt5 с помощью QPropertyAnimation.

Я попытался добавить QPropertyAnimation(self.label , b"fontSize"), но это не сработало, и я получил предупреждение

Я хочу, чтобы вы увеличили текст QLabel, а затем снова переключились на нормальный размер


person 0xsapphir3    schedule 25.06.2021    source источник
comment
Здравствуйте и добро пожаловать в StackOverflow. Пожалуйста, не забывайте всегда предоставлять подробную информацию, когда задаете вопрос (не торопитесь, чтобы прочитать Как задавать хорошие вопросы): это не работало, не очень полезно для нас, но вы могли бы показать нам, что вы на самом деле пробовали. Кроме того, о каком предупреждении вы говорите?   -  person musicamante    schedule 25.06.2021
comment
Я же написал.. См. во втором абзаце.   -  person 0xsapphir3    schedule 25.06.2021
comment
Я имею в виду это предупреждение: Попытка анимировать анимацию, не связанную с собственностью.   -  person 0xsapphir3    schedule 25.06.2021


Ответы (1)


Из описания QPropertyAnimation:

QPropertyAnimation выполняет интерполяцию по свойствам Qt. Поскольку значения свойств хранятся в QVariant, класс наследует QVariantAnimation и поддерживает анимацию тех же метатипов, что и его суперкласс.

Класс, объявляющий свойства, должен быть QObject. Чтобы свойство можно было анимировать, оно должно предоставлять установщик (чтобы QPropertyAnimation мог установить значение свойства).

Все классы, которые унаследованы от QObject (включая виджеты), поддерживают свойства Qt, и на самом деле большинство из них имеют встроенные свойства, но, очевидно, не все свойства поддерживают анимацию: они должны основываться на числовых значениях. Вы можете анимировать числовое изменение (например, от 0 до 100), а не текст (например, с «ABC» на «PYZ»).

Например, все QWidget имеют свойство pos, и поскольку такое свойство (которое является QPoint) основано на числах, вы можете создать анимацию. Вы можете увидеть список поддерживаемых типов вариантов для анимации в документах QVariantAnimation. Учтите, что все страницы документации, касающиеся подклассов QObject, содержат раздел property (см. свойства QWidget), и эти свойства, очевидно, унаследованы от своих суперклассов.

Однако для шрифта size нет свойства, поэтому есть две возможности:

  1. создать пользовательское свойство (используя декоратор pyqtProperty в PyQt);
  2. используйте 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
comment
Спасибо за ваш ответ, я проверю, работает ли этот код - person 0xsapphir3; 26.06.2021
comment
@0xsapphir3 пожалуйста, но учтите, что вам следует сначала попробовать, если решение ответа действительно решает вашу проблему, прежде чем принимать его как принятое. - person musicamante; 26.06.2021
comment
Ну, первый код выдал мне ошибку, но второй сработал. Большое спасибо! :) - person 0xsapphir3; 26.06.2021
comment
@0xsapphir3, пожалуйста, помните, что StackOverflow — это усилие сообщества. Говорить, что это выдало мне ошибку, бесполезно не только для вас, но и для всех, кто может столкнуться с подобной проблемой. Какую ошибку вы получили? Вы реализовали код именно так, как я предложил? Если у вас возникла какая-либо проблема с предоставленным решением, вы должны всегда уточнить, что это за проблема: это может быть важно для многих людей, включая тех, кто пытается вам помочь. Общие и общие знания очень, очень важны. - person musicamante; 26.06.2021
comment
Это была моя ошибка, я не импортировал pyqtSignal, и поэтому я получил ошибку. В любом случае, я решил эту проблему, поэтому я не вставил ошибку. - person 0xsapphir3; 26.06.2021
comment
И, кстати, спасибо за помощь. Я новичок в Stack Overflow, и мой первый опыт оказался намного лучше, чем я думал. Я очень благодарен вам. - person 0xsapphir3; 26.06.2021