在PyQT5中设置矩形动画:为什么没有定义QtCore?

时间:2015-05-14 20:44:19

标签: python pyqt5

我试图通过创建一个动画循环来动画PyQT中的矩形。我在TKinter中使用window.after()方法完成了这项工作,并尝试使用QtCore.QTimer.singleShot()在PyQt5中执行相同操作,但是,当我运行代码时,它表示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_())

2 个答案:

答案 0 :(得分:3)

你还没有导入QTCore,你已经在 QTCore中导入了所有

更改导入方式

尝试更改此内容:

from PyQt5.QtCore import *

到此:

from PyQt5 import QtCore

或者,更改您调用QTimer的方式

改变这个:

QTCore.QTimer.singleShot(33, animate)

到此:

QTImer.singleShot(33, animate)

答案 1 :(得分:1)

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

from PyQt5.QtCore import *

这会将 QtCore内的所有内容导入全局命名空间,但导入名称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_())

使用QTimer调用的start(msec)对象将每timeout()毫秒发出msec个信号。通过这种方式,您不必每次都重新启动它。

此外,我发现通过改变他们的方法来修补实例非常难看,就像你在animate()中使用mw.paintEvent = paintEvent一样。此外:你可以把那条线放在功能之外。

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