openGL和PyQt5存在的问题

3
我将从Winpython3.4.3.7Qt4迁移到Winpython3.x.x.xQt5(我尝试了许多版本),并遇到以下问题:
下面的示例代码(它没有实际用途,但演示了错误):
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)

这个程序在我所有安装了Winpython3.4.3.7Qt4的机器上运行,并打印出'1'。但是当我使用Winpython3.x.x.xQt5时,它就不能在我的虚拟机上运行了。我得到的错误信息是:

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
)

我有一种感觉,window.makeCurrent() 没有成功执行,但我不知道为什么。从Qt4到Qt5在这方面有什么变化?


我已经在Linux上使用Python 3.7和PyQt 5.11.2进行了测试,没有发现任何问题。 - eyllanesc
在Windows上试一下,很可能只是那里出了问题。在四台Windows机器中,有一台可以无问题地运行代码。 - zeus300
1
检查您所获得的OpenGL上下文版本。glGenLists已经在现代OpenGL版本中被移除了十年。 - derhass
我修改了我的答案,像你的例子一样包含了makeCurrent()的调用,问题似乎已经解决了,让我知道它对你有何影响;-) - Isma
1个回答

1
根据OpenGL文档,glGenLists在以下情况下会返回GL_INVALID_OPERATION

如果在glBegin的执行和相应的glEnd的执行之间执行glGenLists,则会生成GL_INVALID_OPERATION。

因此,看起来您是在OpenGL初始化之前或在glBegin glEnd绘图调用之间调用了glGenLists
我通过创建一个从QGLWidget继承的小部件并等待它被初始化后再调用gl.glGenLists(1)来解决了这个问题,正如下面所示,在init方法中发送了一个信号:
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_())

错误已经消失了...

参考资料:http://docs.gl/gl3/glGenLists


抱歉,Isma,但是在你的代码第22行我得到了相同的错误。 - zeus300
你在使用虚拟机吗? - Isma
事实上,是的,我有几个。这是一个好提示,因为现在我想起来了,代码只能在一个真实的机器上运行,而不能在任何虚拟机上运行。我刚刚在另一台真实的机器上运行了我的原始小样例代码,它可以正常工作。所以最新的QtOpenGL(或者问题出在哪里)似乎与虚拟机有关。这在某种程度上缓解了我的问题,但最终我也想在虚拟机上使用该代码。(是的,我知道,最终我将不得不将代码转换为现代OpenGL。) - zeus300
你使用的是哪种虚拟机?这很关键,因为其中一些不支持OpenGL或仅支持部分功能。 - Isma
这是一个基于KVM的Windows 10。但我认为问题不在虚拟机上,而是因为新的Python/Qt/其他库,因为我的Qt5/OpenGL之前的软件可以在我所有的虚拟机上运行。 - zeus300
也许你可以尝试使用GPU直通:https://arrayfire.com/using-gpus-kvm-virutal-machines/虽然我建议先尝试其他的虚拟机管理程序,或者你可以选择使用之前支持KVM OpenGL版本的Qt旧版本。 - Isma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接