PySide(PyQt)尝试动画。 (QWidget :: repaint:检测到递归重绘)

时间:2014-10-18 17:53:06

标签: python animation pyqt pyside qpainter

我正在尝试制作一些动画,但我遇到了问题。当我选中我的复选框时,我收到错误:

QWidget::repaint: Recursive repaint detected

那我怎么做动画呢?我想制作一个简单的动画:

def animation(self, paint):
    for i in range(100):
        paint.eraseRect(0, 0, 1000, 1000)
        paint.drawPoint(i + 1, i + 1)
        QtGui.QApplication.processEvents()
        time.sleep(0.1)
        self.update()

完整代码:

import sys, math, time
from PySide import QtGui , QtCore

class lab(QtGui.QWidget):

    def __init__(self):
        super(lab, self).__init__()
        self.setFixedSize(900, 600)
        self.scene = QtGui.QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 600, 600)
        self.view = QtGui.QGraphicsView()
        self.view.setRenderHint(QtGui.QPainter.Antialiasing)
        self.view.setScene(self.scene)
        self.centerPoint_x_Lable = QtGui.QLabel("cX: ", self)
        self.centerPoint_x_Lable.move(715, 24)
        self.centerPoint_y_Lable = QtGui.QLabel("cY: ", self)
        self.centerPoint_y_Lable.move(815, 24)
        self.astroidRadius_Lable = QtGui.QLabel("R: ", self)
        self.astroidRadius_Lable.move(715, 64)
        self.rotationPoint_x_Lable = QtGui.QLabel("rX: ", self)
        self.rotationPoint_x_Lable.move(715, 124)
        self.rotationPoint_y_Lable = QtGui.QLabel("rY: ", self)
        self.rotationPoint_y_Lable.move(815, 124)
        self.rotationAngle_Lable = QtGui.QLabel("Ang: ", self)
        self.rotationAngle_Lable.move(715, 164)
        self.centerPoint_x = QtGui.QSpinBox(self)
        self.centerPoint_x.setRange(0, 600)
        self.centerPoint_x.setValue(300)
        self.centerPoint_x.move(740, 20)
        self.centerPoint_y = QtGui.QSpinBox(self)
        self.centerPoint_y.setRange(0, 600)
        self.centerPoint_y.setValue(300)
        self.centerPoint_y.move(840, 20)
        self.astroidRadius = QtGui.QSpinBox(self)
        self.astroidRadius.setRange(20, 300)
        self.astroidRadius.setValue(50)
        self.astroidRadius.move(740, 60)
        self.rotationPoint_x = QtGui.QSpinBox(self)
        self.rotationPoint_x.setRange(0, 600)
        self.rotationPoint_x.setValue(300)
        self.rotationPoint_x.move(740, 120)
        self.rotationPoint_y = QtGui.QSpinBox(self)
        self.rotationPoint_y.setRange(0, 600)
        self.rotationPoint_y.setValue(300)
        self.rotationPoint_y.move(840, 120)
        self.rotationAngle = QtGui.QSpinBox(self)
        self.rotationAngle.setRange(0, 360)
        self.rotationAngle.setValue(0)
        self.rotationAngle.move(740, 160)
        self.astroidSquare = QtGui.QLabel("S:        ", self)
        self.astroidSquare.move(715, 220)
        self.cursorPos_x = QtGui.QLabel("X:        ", self)
        self.cursorPos_x.move(715, 260)
        self.cursorPos_y = QtGui.QLabel("Y:        ", self)
        self.cursorPos_y.move(815, 260)
        self.checkBox = QtGui.QCheckBox("Animation", self)
        self.checkBox.move(715, 420)

        self.x0 = self.centerPoint_x.value()
        self.y0 = self.centerPoint_y.value()
        self.aX = []
        self.aY = []
        self.r = self.astroidRadius.value()
        self.xr0 = self.rotationPoint_x.value()
        self.yr0 = self.rotationPoint_y.value()
        self.ang = self.rotationAngle.value()
        self.astriodXY()
        self.RaX = self.rotateX(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.RaY = self.rotateY(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.astroidSquare.setText("S: %d" % (math.pi *3 / 8 * self.r ** 2))


        self.connect(self.centerPoint_x, QtCore.SIGNAL("valueChanged(int)"), self.setFigure)
        self.connect(self.centerPoint_y, QtCore.SIGNAL("valueChanged(int)"), self.setFigure)
        self.connect(self.astroidRadius, QtCore.SIGNAL("valueChanged(int)"), self.changeSize)
        self.connect(self.rotationPoint_x, QtCore.SIGNAL("valueChanged(int)"), self.rotationFigure)
        self.connect(self.rotationPoint_y, QtCore.SIGNAL("valueChanged(int)"), self.rotationFigure)
        self.connect(self.rotationAngle, QtCore.SIGNAL("valueChanged(int)"), self.rotationFigure)

    def setFigure(self):
        self.x0 = self.centerPoint_x.value()
        self.y0 = self.centerPoint_y.value()
        self.aX = []
        self.aY = []
        self.astriodXY()
        self.RaX = self.rotateX(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.RaY = self.rotateY(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.update()

    def changeSize(self):
        self.r = self.astroidRadius.value()
        self.aX = []
        self.aY = []
        self.astriodXY()
        self.RaX = self.rotateX(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.RaY = self.rotateY(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.astroidSquare.setText("S: %d" % (math.pi *3 / 8 * self.r ** 2))
        self.update()

    def rotationFigure(self):
        self.xr0 = self.rotationPoint_x.value()
        self.yr0 = self.rotationPoint_y.value()
        self.ang = self.rotationAngle.value()
        self.aX = []
        self.aY = []
        self.astriodXY()
        self.RaX = self.rotateX(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.RaY = self.rotateY(self.xr0, self.yr0, self.aX, self.aY, self.ang)
        self.update()

    def astriodXY(self):
        for i in range(180):
            self.aX.append(self.r*math.cos(2*i*math.pi/180)**3 + self.x0)
            self.aY.append(self.r*math.sin(2*i*math.pi/180)**3 + self.y0)

    def rotateX(self, x0, y0, listX, listY, ang):
        return [(listX[i] - x0)*math.cos(ang*math.pi/180) - (listY[i] - y0)*math.sin(ang*math.pi/180) + x0 for i in range(len(listX))]

    def rotateY(self, x0, y0, listX, listY, ang):
        return [(listX[i] - x0)*math.sin(ang*math.pi/180) + (listY[i] - y0)*math.cos(ang*math.pi/180) + y0 for i in range(len(listX))]

    def rotX(self, x0, y0, X, Y, ang):
        return (X - x0)*math.cos(ang*math.pi/180) - (Y - y0)*math.sin(ang*math.pi/180) + x0

    def rotY(self, x0, y0, X, Y, ang):
        return (X - x0)*math.sin(ang*math.pi/180) + (Y - y0)*math.cos(ang*math.pi/180) + y0

    def mouseMoveEvent(self, event):
        if self.checkBox.isChecked() == False:
            self.cursorPos_x.setText("X: %d" % event.x())
            self.cursorPos_y.setText("Y: %d" % event.y())
            self.update()

    def paintEvent(self, e):
        painter = QtGui.QPainter(self)
        painter.setPen(QtGui.QPen(QtCore.Qt.red, 3))
        if self.checkBox.isChecked() == False:
            self.drawing(painter)
        else:
            self.animation(painter)

    def drawing(self, paint):
        for i in range(25):
            if i > 0:
                paint.setPen(QtGui.QPen(QtCore.Qt.red, 0.15))
            paint.drawLine(i*25, 0, i*25, 600)
            paint.drawLine(0, i*25, 600, i*25)
        paint.setPen(QtGui.QPen(QtCore.Qt.black, 1))
        for i in range(180):
            if i < 179:
                paint.drawLine(self.RaX[i], self.RaY[i], self.RaX[i+1], self.RaY[i+1])
            else:
                paint.drawLine(self.RaX[i], self.RaY[i], self.RaX[i-i], self.RaY[i-i])

        x = QtGui.QCursor.pos().x() - 233
        y = QtGui.QCursor.pos().y() - 96
        for i in range(180):
            if int(self.RaX[i]) == x and int(self.RaY[i]) == y:
                if i < 179:
                    paint.setPen(QtGui.QPen(QtCore.Qt.blue, 1))
                    paint.drawLine(self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i+1]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i+1]), self.RaX[i] + 1000*(self.RaX[i] - self.RaX[i+1]), self.RaY[i] + 1000*(self.RaY[i] - self.RaY[i+1]))
                    paint.setPen(QtGui.QPen(QtCore.Qt.green, 1))
                    paint.drawLine(self.rotX(self.RaX[i], self.RaY[i], self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i+1]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i+1]), 90), self.rotY(self.RaX[i], self.RaY[i], self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i+1]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i+1]), 90), self.RaX[i], self.RaY[i])
                elif i == 179:
                    paint.drawLine(self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i-i]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i-i]), self.RaX[i] + 1000*(self.RaX[i] - self.RaX[i-i]), self.RaY[i] + 1000*(self.RaY[i] - self.RaY[i-i]))
                    paint.drawLine(self.rotX(self.RaX[i], self.RaY[i], self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i-i]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i-i]), 90), self.rotY(self.RaX[i], self.RaY[i], self.RaX[i] - 1000*(self.RaX[i] - self.RaX[i-i]), self.RaY[i] - 1000*(self.RaY[i] - self.RaY[i-i]), 90), self.RaX[i], self.RaY[i])

    def animation(self, paint):
        for i in range(100):
            paint.eraseRect(0, 0, 1000, 1000)
            paint.drawPoint(i + 1, i + 1)
            QtGui.QApplication.processEvents()
            time.sleep(0.1)
            self.update()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    form = lab()
    form.setWindowTitle("Animation")
    form.show()
    app.exec_()

1 个答案:

答案 0 :(得分:1)

您正在从paintEvent调用的函数中调用update。

update将再次调用paintEvent,导致递归。