在 PyQT5 中动画矩形:为什么未定义 QtCore?

Animating a rectangle in PyQT5: Why is QtCore not defined?

我正在尝试通过创建动画循环来为 PyQT 中的矩形制作动画。我在 TKinter 中使用 window.after() 方法完成了此操作,并尝试在 PyQt5 中使用 QtCore.QTimer.singleShot() 执行相同的操作,但是,当我 运行 代码时,它表示 QtCore尚未定义我相信我已经导入了它!?另外 - 这种方法无论如何都会起作用吗?有没有更好的方法?

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.Qt import *
from PyQt5.QtCore import *


def animate():
    global a
    global x
    mw.paintEvent = paintEvent
    a = a+1
    x = x+1
    QtCore.QTimer.singleShot(33, animate)


def paintEvent(e):
    qp = QPainter()
    qp.begin(mw)
    qp.setBrush(QColor(200, 0, 0))
    qp.drawRect(a, b, x, y)
    qp.end()

a = 10
b = 15
x = 90
y = 60

app = QApplication(sys.argv)

mw = QMainWindow()
mw.setWindowTitle('PyQt5 - Main Window')
mw.setWindowIcon(QIcon("icon.jpg"))
mw.resize(300,100)

animate()

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

您还没有导入 QTCore,您已经导入了 QTCore 中的所有内容。

更改导入方式

尝试改变这个:

from PyQt5.QtCore import *

对此:

from PyQt5 import QtCore

或者,改变调用 QTimer 的方式

改变这个:

QTCore.QTimer.singleShot(33, animate)

对此:

QTImer.singleShot(33, animate)

QtCore 引用未定义,因为您正在使用星号导入:

from PyQt5.QtCore import *

这会将 inside QtCore 中的所有内容导入全局命名空间,但它 not 导入名称 QtCore.

事实上你可以使用:

QTimer.singleShot(x)

前面不需要QtCore.

但是你应该使用:

from PyQt5 import QtCore

这表示:

我不知道你为什么要使用 singleShot 计时器,而你 想要一个单次计时器,而是一个周期计时器。你应该这样做:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.Qt import *
from PyQt5.QtCore import *


class MyWindow(QMainWindow):
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        qp.setBrush(QColor(200, 0, 0))
        qp.drawRect(a, b, x, y)
        qp.end()


def updateValues():
    global a, x
    a += 1
    x += 1
    mw.update()  # <-- update the window!


a = 10
b = 15
x = 90
y = 60

app = QApplication(sys.argv)

mw = MyWindow()
mw.setWindowTitle('PyQt5 - Main Window')
mw.setWindowIcon(QIcon("icon.jpg"))
mw.resize(300,100)

timer = QTimer()
timer.timeout.connect(updateValues)
timer.start(33)

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

start(msec) 调用的 QTimer 对象将每 msec 毫秒发出一个 timeout() 信号。这样就不用每次都重启

此外,我发现像在 animate()mw.paintEvent = paintEvent 中那样通过更改它们的方法来修补实例真的很难看。此外:您可以将该行放在函数之外。

注意:在更新值的函数中必须调用mw.update(),否则不会生成paintEvent。 此外,似乎 timer 正在收集垃圾,从而阻塞计时器,因此最好只对它进行全局引用。