Problems with openGL and PyQt5

Viewed 1807

I am moving from Winpython3.4.3.7Qt4 to Winpython3.x.x.xQt5 (I tried a bunch of versions), and I am having the following problem:

The following minimal code (it does nothing usable, but demonstrates the error):

from PyQt5 import QtWidgets
import OpenGL.GL as gl
from PyQt5.QtOpenGL import QGLWidget
qapp = QtWidgets.QApplication([])
window = QGLWidget()
window.makeCurrent()
index = gl.glGenLists(1)
print(index)

runs on all my machines with Winpython3.4.3.7Qt4 and prints '1'. When I use Winpython3.x.x.xQt5, it does not run on my virtual machines anymore. The error I get is:

Traceback (most recent call last):
  File ".\opengl.py", line 12, in <module>
    index = gl.glGenLists(1)
  File "C:\Winpython-64bit-3.6.7.0\python-3.6.7\lib\site-packages\OpenGL\platform\baseplatform.py", line 405, in __call__
    return self( *args, **named )
  File "C:\Winpython-64bit-3.6.7.0\python-3.6.7\lib\site-packages\OpenGL\error.py", line 232, in glCheckError
    baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
        err = 1282,
        description = b'invalid operation',
        baseOperation = glGenLists,
        cArguments = (1,),
        result = 0
)

I have the feeling that window.makeCurrent() isn't coming through, but I have no idea why. What changed in that regard from Qt4 to Qt5?

1 Answers

According the OpenGL documentation glGenLists will return GL_INVALID_OPERATION in the following case:

GL_INVALID_OPERATION is generated if glGenLists is executed between the execution of glBegin and the corresponding execution of glEnd.

So it seems you are calling glGenLists before OpenGL has been initialized or between a glBegin glEnd drawing call.

I was able tol solve the issue by creating a widget that inherits from QGLWidget and waiting until it has been initialized before calling gl.glGenLists(1), as you can see below a signal is sent inside the init method:

import sys
import OpenGL.GL as gl

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import pyqtSignal

from PyQt5.QtOpenGL import QGLWidget


class MyQGLWidget(QGLWidget):
    init = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)

    def glInit(self):
        super().glInit()
        self.init.emit()

    def gl_gen_lists(self, size):
        return gl.glGenLists(size)


class App(QApplication):
    def __init__(self, sys_argv):
        super().__init__(sys_argv)
        self.qgl_widget = MyQGLWidget()
        self.qgl_widget.init.connect(self.on_init)
        self.qgl_widget.show()

    def on_init(self):
        self.qgl_widget.makeCurrent()
        print(self.qgl_widget.gl_gen_lists(1))


if __name__ == '__main__':
    app = App(sys.argv)
    sys.exit(app.exec_())

And the error is gone...

Reference: http://docs.gl/gl3/glGenLists

Related