简体   繁体   English

如何使用 PyQt5 设置 PyOpenGL?

[英]How do I set up PyOpenGL with PyQt5?

I am wanting to set up several 3D mathematical projects with python.我想用 python 设置几个 3D 数学项目。 The best way I can see to render these is with PyOpenGL.我能看到的渲染这些的最好方法是使用 PyOpenGL。 I also want to run it in PyQt5, so that I can have GUI's along side the render.我也想在 PyQt5 中运行它,这样我就可以在渲染旁边有 GUI。 All the information I can find is either using PyGame or QtDesigner.我能找到的所有信息都是使用 PyGame 或 QtDesigner。 I would like to work without QtDesigner.我想在没有 QtDesigner 的情况下工作。 Does anyone know where I could find a tutorial on how to set this up?有谁知道我在哪里可以找到有关如何设置的教程?

EDIT:编辑:

I managed to get some web scrounging done.我设法完成了一些网络搜索。 I found the following code at https://pythonprogramming.net/community/37/Cube%20rotation%20with%20pyopengl%20and%20pyqt/ where the author asks for help regarding it not running.我在https://pythonprogramming.net/community/37/Cube%20rotation%20with%20pyopengl%20and%20pyqt/找到了以下代码,作者在此处寻求有关它未运行的帮助。 he says the following about it:他是这样说的:

I'm very new to python.我对python很陌生。 I have a problem with my code, it's a very simple rotating cube.我的代码有问题,它是一个非常简单的旋转立方体。 I don't have any problem with this cube code with pygame screen but when I use it with pyqt (or Qt designer widgets), it runs but it shows nothing!!!我对这个带有 pygame 屏幕的立方体代码没有任何问题,但是当我将它与 pyqt(或 Qt 设计器小部件)一起使用时,它运行但什么也没显示!!!

I copied his code into my IDe, then saved it as cubes.py .我将他的代码复制到我的 IDe 中,然后将其保存为cubes.py I opened up a CMD instance in thae directory of the file and called it.我在文件的目录中打开了一个 CMD 实例并调用了它。 It opened a tiny black Qt window in the middle of the screen:它在屏幕中间打开了一个黑色的小 Qt 窗口: 代码的结果

When I try to resize the window by dragging the corner, it throws a deep traceback:当我尝试通过拖动角来调整窗口大小时,它会抛出一个很深的回溯:

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

Here is his code, unmodified:这是他的代码,未经修改:

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

I once developed an interactive 3D program using PyOpenGL and PyQt5.我曾经使用 PyOpenGL 和 PyQt5 开发了一个交互式 3D 程序。 Here's the spike code of that time.这是当时的秒杀代码。 I wish this could be helpful to you.我希望这对你有帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM