Search code examples
pythonqtopenglpyqtqtopengl

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


I am using opengl to render some graphics in my Python & QT application. I followed many tutorial to add the openGL to the application and all of them didn't have a continuous update to the scene. A simple example, I want to keep rotating the objects in the scene, so I keep increasing the angle and updating the scene but this leads to an error!

This is my code which is on github (can be found here), I've just added the auto-rotation:

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_())

The updateGL function can be found in the setXRotation function which leads to this error:

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

Thank you


Solution

  • I don't think you should be calling updateGL in setXRotation, because AFAIK that invokes your paintGL directly rather than going through the event loop. Try self.update() instead. (And anywhere else you want the widget to redraw itself due to user action.)