2016-07-28 445 views
0

我一直试图让the PyQt5 helloGL example code编译。当我尝试构建解决方案,我得到:PyQt5的OpenGL模块和版本问题(调用不正确的_QOpenGLFunctions_(ver))

Traceback (most recent call last): 
    File "C:\Users\\-PATH-\trunk\view\test.py", line 142, in initializeGL 
    self.gl = self.context().versionFunctions() 
ImportError: No module named 'PyQt5._QOpenGLFunctions_4_3_Compatibility' 
[Finished in 0.3s] 

在我PyQt5文件夹中,我有:

_QOpenGLFunctions_4_1_Core.pyd 
_QOpenGLFunctions_2_0.pyd 
_QOpenGLFunctions_2_1.pyd 

为我设置为QOpenGLFunctions不同的版本。我试着搜索调用versionFunctions()的工作方式,看看我是否可以强制它使用4_1_Core文件,但无济于事。我已经重新安装了PyQt5两次后,重新启动几次,看看它是不是奇怪的注册表shenanigans - 这是我确保我的图形驱动程序更新后,以便正确的版本的OpenGL甚至在我的系统上(如果这是某种方式造成问题)

PyOpenGL已安装并更新,我也重新安装了它。

我最终的目标是将OpenGL渲染器嵌入到Qt窗口中,但是我还没有找到很多关于如何在python中执行此操作的示例。我一直在使用Vispy,但也遇到了很多问题,因为他们以前的Qt示例也不再工作。

回答

3

这是使用这两条线的问题:

self.gl = self.context().versionFunctions() 
    self.gl.initializeOpenGLFunctions() 

相反,你应该用适当的主要/次要版本创建自定义QSurfaceFormat和使用QContext的setFormat,使其与适当的OpenGL版本。

无论如何,我建议你一个更简单的选择。对于我所有的pyqt opengl项目,我只是直接在我的小部件上使用PyOpenGL,并免费获得最新的opengl版本。找到下面的hellogl例子,直接使用PyOpengl,我还添加了一些例程来打印你的gpu信息,所以你会看到使用的opengl版本会匹配你的系统的一个版本(检查出gpu caps viewer或类似):

import sys 
import math 

from PyQt5.QtCore import pyqtSignal, QPoint, QSize, Qt 
from PyQt5.QtGui import QColor 
from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QOpenGLWidget, QSlider, 
          QWidget) 

import OpenGL.GL as gl 


class Window(QWidget): 

    def __init__(self): 
     super(Window, self).__init__() 

     self.glWidget = GLWidget() 

     self.xSlider = self.createSlider() 
     self.ySlider = self.createSlider() 
     self.zSlider = self.createSlider() 

     self.xSlider.valueChanged.connect(self.glWidget.setXRotation) 
     self.glWidget.xRotationChanged.connect(self.xSlider.setValue) 
     self.ySlider.valueChanged.connect(self.glWidget.setYRotation) 
     self.glWidget.yRotationChanged.connect(self.ySlider.setValue) 
     self.zSlider.valueChanged.connect(self.glWidget.setZRotation) 
     self.glWidget.zRotationChanged.connect(self.zSlider.setValue) 

     mainLayout = QHBoxLayout() 
     mainLayout.addWidget(self.glWidget) 
     mainLayout.addWidget(self.xSlider) 
     mainLayout.addWidget(self.ySlider) 
     mainLayout.addWidget(self.zSlider) 
     self.setLayout(mainLayout) 

     self.xSlider.setValue(15 * 16) 
     self.ySlider.setValue(345 * 16) 
     self.zSlider.setValue(0 * 16) 

     self.setWindowTitle("Hello GL") 

    def createSlider(self): 
     slider = QSlider(Qt.Vertical) 

     slider.setRange(0, 360 * 16) 
     slider.setSingleStep(16) 
     slider.setPageStep(15 * 16) 
     slider.setTickInterval(15 * 16) 
     slider.setTickPosition(QSlider.TicksRight) 

     return slider 


class GLWidget(QOpenGLWidget): 
    xRotationChanged = pyqtSignal(int) 
    yRotationChanged = pyqtSignal(int) 
    zRotationChanged = pyqtSignal(int) 

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

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

     self.lastPos = QPoint() 

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

    def getOpenglInfo(self): 
     info = """ 
      Vendor: {0} 
      Renderer: {1} 
      OpenGL Version: {2} 
      Shader Version: {3} 
     """.format(
      gl.glGetString(gl.GL_VENDOR), 
      gl.glGetString(gl.GL_RENDERER), 
      gl.glGetString(gl.GL_VERSION), 
      gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION) 
     ) 

     return info 

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

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

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

    def setYRotation(self, angle): 
     angle = self.normalizeAngle(angle) 
     if angle != self.yRot: 
      self.yRot = angle 
      self.yRotationChanged.emit(angle) 
      self.update() 

    def setZRotation(self, angle): 
     angle = self.normalizeAngle(angle) 
     if angle != self.zRot: 
      self.zRot = angle 
      self.zRotationChanged.emit(angle) 
      self.update() 

    def initializeGL(self): 
     print(self.getOpenglInfo()) 

     self.setClearColor(self.trolltechPurple.darker()) 
     self.object = self.makeObject() 
     gl.glShadeModel(gl.GL_FLAT) 
     gl.glEnable(gl.GL_DEPTH_TEST) 
     gl.glEnable(gl.GL_CULL_FACE) 

    def paintGL(self): 
     gl.glClear(
      gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 
     gl.glLoadIdentity() 
     gl.glTranslated(0.0, 0.0, -10.0) 
     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() & Qt.LeftButton: 
      self.setXRotation(self.xRot + 8 * dy) 
      self.setYRotation(self.yRot + 8 * dx) 
     elif event.buttons() & 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) 

     gl.glBegin(gl.GL_QUADS) 

     x1 = +0.06 
     y1 = -0.14 
     x2 = +0.14 
     y2 = -0.06 
     x3 = +0.08 
     y3 = +0.00 
     x4 = +0.30 
     y4 = +0.22 

     self.quad(x1, y1, x2, y2, y2, x2, y1, x1) 
     self.quad(x3, y3, x4, y4, y4, x4, y3, x3) 

     self.extrude(x1, y1, x2, y2) 
     self.extrude(x2, y2, y2, x2) 
     self.extrude(y2, x2, y1, x1) 
     self.extrude(y1, x1, x1, y1) 
     self.extrude(x3, y3, x4, y4) 
     self.extrude(x4, y4, y4, x4) 
     self.extrude(y4, x4, y3, x3) 

     NumSectors = 200 

     for i in range(NumSectors): 
      angle1 = (i * 2 * math.pi)/NumSectors 
      x5 = 0.30 * math.sin(angle1) 
      y5 = 0.30 * math.cos(angle1) 
      x6 = 0.20 * math.sin(angle1) 
      y6 = 0.20 * math.cos(angle1) 

      angle2 = ((i + 1) * 2 * math.pi)/NumSectors 
      x7 = 0.20 * math.sin(angle2) 
      y7 = 0.20 * math.cos(angle2) 
      x8 = 0.30 * math.sin(angle2) 
      y8 = 0.30 * math.cos(angle2) 

      self.quad(x5, y5, x6, y6, x7, y7, x8, y8) 

      self.extrude(x6, y6, x7, y7) 
      self.extrude(x8, y8, x5, y5) 

     gl.glEnd() 
     gl.glEndList() 

     return genList 

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): 
     self.setColor(self.trolltechGreen) 

     gl.glVertex3d(x1, y1, -0.05) 
     gl.glVertex3d(x2, y2, -0.05) 
     gl.glVertex3d(x3, y3, -0.05) 
     gl.glVertex3d(x4, y4, -0.05) 

     gl.glVertex3d(x4, y4, +0.05) 
     gl.glVertex3d(x3, y3, +0.05) 
     gl.glVertex3d(x2, y2, +0.05) 
     gl.glVertex3d(x1, y1, +0.05) 

    def extrude(self, x1, y1, x2, y2): 
     self.setColor(self.trolltechGreen.darker(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 

    def setClearColor(self, c): 
     gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()) 

    def setColor(self, c): 
     gl.glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()) 


if __name__ == '__main__': 

    app = QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

太棒了,由于缺乏github上的活动,我一直在离开Vispy。你有任何链接到良好的资源,以了解更多关于PyOpenGL?我试图看到机器工具路径(g代码)和网格(stls),并努力克服某些问题。在pyopengl中工作感觉会更好。 – fuchstraumer

+0

@fuchstraumer很高兴答案帮助你,考虑将其标记为有效,关于g代码和stls,请考虑打开另一篇文章,以便我可以进一步阐述这个话题,这是很有趣的顺便说一句。 – BPL

+0

@fuchstraumer关于PyOpengl,我首先从这个[website](http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl)安装轮子,然后读一点[官方文档] (http://pyopengl.sourceforge.net/documentation)。一旦你创建了gl context,如果你熟悉opengl或者webgl,根本就没有神秘感。 – BPL