【问题标题】:How do I set up PyOpenGL with PyQt5?如何使用 PyQt5 设置 PyOpenGL?
【发布时间】:2020-02-12 07:30:27
【问题描述】:

我想用 python 设置几个 3D 数学项目。我能看到渲染这些的最好方法是使用 PyOpenGL。我还想在 PyQt5 中运行它,这样我就可以在渲染的旁边有 GUI。我能找到的所有信息都是使用 PyGame 或 QtDesigner。我想在没有 QtDesigner 的情况下工作。有谁知道我在哪里可以找到有关如何设置它的教程?

编辑:

我设法完成了一些网络搜索。我在https://pythonprogramming.net/community/37/Cube%20rotation%20with%20pyopengl%20and%20pyqt/ 找到了以下代码,作者在此寻求有关它无法运行的帮助。他说:

我对 python 很陌生。我的代码有问题,它是一个非常简单的旋转立方体。我对这个带有 pygame 屏幕的多维数据集代码没有任何问题,但是当我将它与 pyqt(或 Qt 设计器小部件)一起使用时,它运行但什么也没显示!!!

我将他的代码复制到我的 IDe 中,然后将其保存为 cubes.py。我在文件的 thae 目录中打开了一个 CMD 实例并调用它。它在屏幕中间打开了一个小小的黑色 Qt 窗口:

当我尝试通过拖动角来调整窗口大小时,它会抛出一个 deep 回溯:

  File "C:\Users\aweso\Documents\Python\cubes\cubes.py", line 1, in <module>
    from OpenGL.GL import *
ModuleNotFoundError: No module named 'OpenGL'

C:\Users\aweso\Documents\Python\cubes>cubes.py
Traceback (most recent call last):
  File "C:\Users\aweso\Documents\Python\cubes\cubes.py", line 56, in paintGL
    glEnd()
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\latebind.py", line 63, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\GL\exceptional.py", line 45, in glEnd
    return baseFunction( )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__
    return self( *args, **named )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\error.py", line 234, in glCheckError
    baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
        err = 1280,
        description = b'invalid enumerant',
        baseOperation = glEnd,
        cArguments = ()
)

这是他的代码,未修改:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL import *
from PyQt5.QtOpenGL import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
import sys,time

class MainWindow(QGLWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.widget = glWidget(self)
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.widget)
        self.setLayout(mainLayout)

class glWidget(QGLWidget):

    def __init__(self, parent):
        QGLWidget.__init__(self, parent)

        #self.setMinimumSize(400, 400)

        self.verticies = (
            (1,-1,-1),
            (1,1,-1),
            (-1,1,-1),
            (-1,-1,-1),
            (1,-1,1),
            (1,1,1),
            (-1,-1,1),
            (-1,1,1))
        self.edges = (
            (0,1),
            (0,3),
            (0,4),
            (2,1),
            (2,3),
            (2,7),
            (6,3),
            (6,4),
            (6,7),
            (5,1),
            (5,4),
            (5,7))

    def paintGL(self):
        while True:
            #glRotatef(1,3,1,1)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glBegin(GL_LINE)
            for self.edge in self.edges:
                for self.vertex in self.edge:
                    glVertex3fv(self.verticies[self.vertex])
            glEnd()
            glFlush()
            time.sleep(1)       

    def resizeGL(self, w, h):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(-50, 50, -50, 50, -50.0, 50.0)
        glViewport(0, 0, w, h)

    def initializeGL(self):

        #glClearColor(0.0, 0.0, 0.0, 1.0)
        gluPerspective(45,800/600,0.1,50.0)
        glTranslatef(0.0,0.0,-5)
        glRotatef(0,0,0,0)

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

【问题讨论】:

    标签: python pyqt5 pyopengl


    【解决方案1】:

    我曾经使用 PyOpenGL 和 PyQt5 开发了一个交互式 3D 程序。 这是当时的尖峰代码。 我希望这对您有所帮助。

    import sys
    import math
    from array import array
    
    from OpenGL import GL
    
    from PyQt5.QtCore import pyqtSignal, QPoint, QSize, Qt
    from PyQt5.QtGui import QColor, QImage
    from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QWidget)
    from PyQt5.QtOpenGL import QGLWidget
    
    from shader import ShaderProgram
    
    
    class Window (QWidget):
    
        def __init__(self):
            super(Window, self).__init__()
    
            self.glWidget = GLWidget()
    
            mainLayout = QHBoxLayout()
            mainLayout.addWidget(self.glWidget)
            self.setLayout(mainLayout)
    
            self.setWindowTitle('Hello')
    
    
    class GLWidget (QGLWidget):
    
        def __init__(self, parent=None):
            super(GLWidget, self).__init__(parent)
    
        def sizeHint(self):
            return QSize(1200, 1000)
    
        def initializeGL(self):
            GL.glClearColor(0.0, 0.0, 1.0, 0.0)  # it's also possible.
    
            GL.glEnable(GL.GL_DEPTH_TEST)
            # GL.glEnable(GL.GL_VERTEX_ARRAY)
    
            self._createVertexBuffer()
    
            self.program = ShaderProgram('hello.vert', 'hello.frag')
            self.program.use()
    
            self.frontTexture = self._createTexture('tex.png')
            self.backTexture = self._createTexture('back-tex.jpg')
    
             # set texture units
    
            GL.glActiveTexture(GL.GL_TEXTURE0)
            GL.glBindTexture(GL.GL_TEXTURE_2D, self.frontTexture)
            GL.glUniform1i(GL.glGetUniformLocation(self.program.getProgram(), b'frontTexture'), 0)
    
            GL.glActiveTexture(GL.GL_TEXTURE1)
            GL.glBindTexture(GL.GL_TEXTURE_2D, self.backTexture)
            GL.glUniform1i(GL.glGetUniformLocation(self.program.getProgram(), b'backTexture'), 1)
    
        def paintGL(self):
            GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
            self._draw()
    
        def resizeGL(self, width, height):
            side = min(width, height)
            if side < 0:
                return
    
            GL.glViewport((width - side) // 2, (height - side) // 2, side, side)
    
        def _createTexture(self, texFilePath):
            qImage = QImage(texFilePath)
    
            texture = QGLWidget.bindTexture(self, qImage, GL.GL_TEXTURE_2D, GL.GL_RGBA)
    
            GL.glGenerateMipmap(GL.GL_TEXTURE_2D)
    
            return texture
    
        def _createVertexBuffer(self):
            vertices = array('f', [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0,  1.0, 0.0, -1.0, 1.0, 0.0]).tobytes()
            colors = array('f', [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0]).tobytes()
            indices = [0, 1, 2, 0, 3, 2]
            texCoords = array('f', [0.0, 0.0, 1.0, 0.0, 1.0,  1.0, 0.0, 1.0]).tobytes()
    
            self.vertices = vertices
            self.colors = colors
            self.indices = indices
            self.texCoords = texCoords
    
        def _draw(self):
    
            GL.glEnableVertexAttribArray(0)
            GL.glEnableVertexAttribArray(1)
            GL.glEnableVertexAttribArray(2)
    
            GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, self.vertices)
            GL.glVertexAttribPointer(1, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, self.colors)
            GL.glVertexAttribPointer(2, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, self.texCoords)
    
            GL.glDrawElements(GL.GL_TRIANGLES, 6, GL.GL_UNSIGNED_INT, self.indices)
    
            GL.glDisableVertexAttribArray(0)
            GL.glDisableVertexAttribArray(1)
            GL.glDisableVertexAttribArray(2)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 感谢您发布代码!当我有机会时,我会挖掘它。
    • 这是 5 年前的代码。但是当我今天在 Ubuntu 18.04 上运行它时,它运行良好。祝你好运。
    • 着色器程序是干什么用的?我可以在没有它的情况下运行 GL 渲染吗?
    • 我在上面使用了一些着色器程序(Python + OpenGL)。你可以用 Python 做任何事,就像用 C++ 做的一样。
    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-30
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    相关资源
    最近更新 更多