PyQt5如何将QLabel更新为动画

PyQt5 how to update QLabel as an animation

我想用我的 qlabel 作为倒计时。基本上,当倒计时被调用时,标签会更改为“3 2 1 begin”,中间有 1 秒的间隔。

但是,如果我这样做:

def nextSound(self):

    self.mainLabel.setText("3")

    sleep(1)

    self.mainLabel.setText("2")

    sleep(1)
    self.mainLabel.setText("1")

它只是等到结束而不更新标签。所以我尝试使用 QPropertyAnimation:

  def nextSound(self):

        self.animate = QPropertyAnimation(self.mainLabel,"setText")

        self.animate.setDuration(1000)
        self.animate.startValue("3")
        self.animate.setEndValue("2")
        self.animate.start()

但是收到这个错误:

self.animate = QPropertyAnimation(self.mainLabel,"setText")
TypeError: arguments did not match any overloaded call:
  QPropertyAnimation(parent: QObject = None): too many arguments
  QPropertyAnimation(QObject, Union[QByteArray, bytes, bytearray], parent: QObject = None): argument 2 has unexpected type 'str'

有什么建议吗?谢谢

QPropertyAnimation 基于内插值 q-属性 需要,当想使用 setText 我认为最接近的是 q-属性 文本但是无法插入文本,因此解决方案是创建一个采用数值的 q-属性。

from PyQt5 import QtCore, QtWidgets

class NumLabel(QtWidgets.QLabel):
    def number(self):
        try:
            return int(self.text())
        except:
            return 0
    def setNumber(self, number):
        self.setNum(number)
    number = QtCore.pyqtProperty(int, fget=number, fset=setNumber)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = NumLabel(alignment=QtCore.Qt.AlignCenter)
    w.resize(640, 480)
    animation = QtCore.QPropertyAnimation(w, b'number')
    animation.setStartValue(3)
    animation.setEndValue(0)
    animation.setDuration(1000*(abs(animation.endValue() - animation.startValue())))
    animation.start()
    w.show()
    sys.exit(app.exec_())

另一个最佳选择是使用 QTimeLine:

from PyQt5 import QtCore, QtWidgets

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
    w.resize(640, 480)
    start = 3
    end = 0
    timeLine = QtCore.QTimeLine(abs(end - start)*1000, w)
    timeLine.setFrameRange(start, end)
    timeLine.frameChanged.connect(w.setNum)

    # set start value
    w.setNum(start)
    # start timer
    timeLine.start()

    w.show()
    sys.exit(app.exec_())