调用 Python 对象进行连续场景更新时超出最大递归深度

maximum recursion depth exceeded while calling a Python object for continuous scene update

我正在使用 opengl 在我的 Python & QT 应用程序中渲染一些图形。 我按照许多教程将 openGL 添加到应用程序,但所有教程都没有对场景进行持续更新。 一个简单的例子,我想一直旋转场景中的物体,所以我一直增加角度并更新场景但是这会导致错误!

这是我在 github 上的代码(可以找到 here),我刚刚添加了自动旋转:

import math
import sys

from PyQt4 import QtCore, QtGui, QtOpenGL


class Window(QtGui.QWidget):
  def __init__(self):
    super(Window, self).__init__()

    self.glWidget = GLWidget()

    mainLayout = QtGui.QHBoxLayout()
    mainLayout.addWidget(self.glWidget)
    self.setLayout(mainLayout)

    self.setWindowTitle("Hello GL")

class GLWidget(QtOpenGL.QGLWidget):
  def __init__(self, parent=None):
    super(GLWidget, self).__init__(parent)

    self.object = 0
    self.xRot = 0
    self.yRot = 0
    self.zRot = 0
    self.angle = 0

    self.lastPos = QtCore.QPoint()

    self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0)
    self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0)

  def minimumSizeHint(self):
    return QtCore.QSize(50, 50)

  def sizeHint(self):
    return QtCore.QSize(400, 400)

  def setXRotation(self, angle):
    angle = self.normalizeAngle(angle)
    if angle != self.xRot:
        self.xRot = angle
        self.xRotationChanged.emit(angle)
        self.updateGL()

  def initializeGL(self):
    self.qglClearColor(self.trolltechPurple.dark())
    self.object = self.makeObject()
    GL.glShadeModel(GL.GL_FLAT)
    GL.glEnable(GL.GL_DEPTH_TEST)
    GL.glEnable(GL.GL_CULL_FACE)

  def paintGL(self):

    self.angle += 1
    GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
    GL.glLoadIdentity()
    GL.glTranslated(0.0, 0.0, -10.0)
    self.setXRotation(self.angle)
    GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
    GL.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
    GL.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
    GL.glCallList(self.object)

  def resizeGL(self, width, height):
    side = min(width, height)
    if side < 0:
        return

    GL.glViewport((width - side) / 2, (height - side) / 2, side, side)

    GL.glMatrixMode(GL.GL_PROJECTION)
    GL.glLoadIdentity()
    GL.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
    GL.glMatrixMode(GL.GL_MODELVIEW)

  def mousePressEvent(self, event):
    self.lastPos = event.pos()

  def mouseMoveEvent(self, event):
    dx = event.x() - self.lastPos.x()
    dy = event.y() - self.lastPos.y()

    if event.buttons() & QtCore.Qt.LeftButton:
        self.setXRotation(self.xRot + 8 * dy)
        self.setYRotation(self.yRot + 8 * dx)
    elif event.buttons() & QtCore.Qt.RightButton:
        self.setXRotation(self.xRot + 8 * dy)
        self.setZRotation(self.zRot + 8 * dx)

    self.lastPos = event.pos()

  def makeObject(self):
    genList = GL.glGenLists(1)
    GL.glNewList(genList, GL.GL_COMPILE)

    # Drawing code

    GL.glEnd()
    GL.glEndList()

    return genList



  def extrude(self, x1, y1, x2, y2):
    self.qglColor(self.trolltechGreen.dark(250 + int(100 * x1)))

    GL.glVertex3d(x1, y1, +0.05)
    GL.glVertex3d(x2, y2, +0.05)
    GL.glVertex3d(x2, y2, -0.05)
    GL.glVertex3d(x1, y1, -0.05)

  def normalizeAngle(self, angle):
    while angle < 0:
        angle += 360 * 16
    while angle > 360 * 16:
        angle -= 360 * 16
    return angle


if __name__ == '__main__':
  app = QtGui.QApplication(sys.argv)
  window = Window()
window.show()
sys.exit(app.exec_())

可以在导致此错误的 setXRotation 函数中找到 updateGL 函数:

Traceback (most recent call last):
  File "/Users/TheMaestro/Desktop/Max Planck/Micheal/Neurons_Visualizer/Views/GUI/testtt.py", line 115, in paintGL
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
RuntimeError: maximum recursion depth exceeded while calling a Python object
Traceback (most recent call last):
  File "/Users/TheMaestro/Desktop/Max Planck/Micheal/Neurons_Visualizer/Views/GUI/testtt.py", line 119, in paintGL
GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 401, in __call__
if self.load():
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 381, in load
from OpenGL import platform
RuntimeError: maximum recursion depth exceeded while calling a Python object
Traceback (most recent call last):
 File "/Users/TheMaestro/Desktop/Max Planck/Micheal/Neurons_Visualizer/Views/GUI/testtt.py", line 119, in paintGL
GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 401, in __call__
if self.load():
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 390, in load
error_checker = self.error_checker,
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/platform/baseplatform.py", line 168, in constructFunction
*argTypes
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 104, in CFUNCTYPE
class CFunctionType(_CFuncPtr):
RuntimeError: maximum recursion depth exceeded while calling a Python object
Traceback (most recent call last):
  File "/Users/TheMaestro/Desktop/Max Planck/Micheal/Neurons_Visualizer/Views/GUI/testtt.py", line 115, in paintGL
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
RuntimeError: maximum recursion depth exceeded while calling a Python object
2016-05-10 14:29:43.635 Python[3996:1654252] ApplePersistenceIgnoreState:     Existing state will not be touched. New state will be written to /var/folders/b_/cqps_v114gb4yv_b44t9_sx00000gn/T/org.python.python.savedState
Traceback (most recent call last):
  File "/Users/TheMaestro/Desktop/Max Planck/Micheal/Neurons_Visualizer/Views/GUI/testtt.py", line 115, in paintGL
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
ctypes.ArgumentError: argument 1: <type 'exceptions.RuntimeError'>: maximum recursion depth exceeded while calling a Python object

谢谢

我认为您不应该在 setXRotation 中调用 updateGL,因为 AFAIK 直接调用您的 paintGL 而不是通过事件循环。 请尝试 self.update()。 (以及您希望小部件因用户操作而自行重绘的其他任何地方。)