簡體   English   中英

PyQt6 中的最小 OpenGL 示例不起作用。 錯誤:glClearColor 中的“無效操作”

[英]A minimal OpenGL example in PyQt6 does not work. Error: "invalid operation" in glClearColor

我嘗試運行一個非常簡單的 OpenGL 示例:

import sys

from OpenGL import GL as gl
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
from PyQt6.QtWidgets import QApplication


class Widget(QOpenGLWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt6, OpenGL 3.3")
        self.resize(400, 400)

    def initializeGL(self):
        gl.glClearColor(0.5, 0.5, 0.5, 1)
    
    def paintGL(self):
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec())

但我有這個錯誤:

Traceback (most recent call last):
  File "main.py", line 16, in initializeGL
    gl.glClearColor(0, 0, 0, 1)
  File "E:\ProgramFiles\Python\Python38\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__
    return self( *args, **named )
  File "E:\ProgramFiles\Python\Python38\lib\site-packages\OpenGL\error.py", line 230, in glCheckError
    raise self._errorClass(
OpenGL.error.GLError: GLError(
        err = 1282,
        description = b'invalid operation',
        baseOperation = glClearColor,
        cArguments = (0, 0, 0, 1)
)

這是相同的示例,但在 PyQt5 中有效:

import sys

from OpenGL import GL as gl
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QOpenGLWidget


class Widget(QOpenGLWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt5, OpenGL 3.3")
        self.resize(400, 400)

    def initializeGL(self):
        gl.glClearColor(0.5, 0.5, 0.5, 1)
    
    def paintGL(self):
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

if __name__ == "__main__":
    QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

有兩個區別:

    1. QOpenGLWidget 被移動到 PyQt6.QtOpenGLWidgets
    1. PyQt5 示例中的行: QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)

這一行:

QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)

應該替換為:

QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)

這些更改也適用於 PySide6:

  1. OpenGL 類已移至單獨的 PyQt6.QtOpenGL 命名空間:

PyQt5:

from PyQt5.QtGui import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram,
                         QOpenGLTexture)

PyQt6:

from PyQt6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram,
                            QOpenGLTexture)
  1. QOpenGLWidget class 已移至 PyQt6.QtOpenGLWidgets 命名空間:

PyQt5:

from PyQt5.QtWidgets import QApplication, QOpenGLWidget

PyQt6:

from PyQt6.QtOpenGLWidgets import QOpenGLWidget
  1. 更改了着色器類型的枚舉:

PyQt5:

self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc)
self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc)

PyQt6:

self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, vertShaderSrc)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, fragShaderSrc)
  1. 更改了枚舉目標紋理:

PyQt5:

self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)

PyQt6:

self.texture = QOpenGLTexture(QOpenGLTexture.Target.Target2D)
  1. 更改了設置紋理過濾器的枚舉:

PyQt5:

self.texture.setMinMagFilters(QOpenGLTexture.Linear, QOpenGLTexture.Linear)

PyQt6:

self.texture.setMinMagFilters(QOpenGLTexture.Filter.Linear, QOpenGLTexture.Filter.Linear)
  1. 更改了 WrapMode 的枚舉:

PyQt5:

self.texture.setWrapMode(QOpenGLTexture.ClampToEdge)

PyQt6:

self.texture.setWrapMode(QOpenGLTexture.WrapMode.ClampToEdge)
  1. 更改了枚舉以設置應用程序屬性:

PyQt5:

QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)

PyQt6:

QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)

一些基本的非圖形更改:

  1. 更改了文件打開模式的枚舉:

PyQt5:

file = QFile(path)
if not file.open(QIODevice.ReadOnly):
    print("Failed to open the file: " + path)

PyQt6:

file = QFile(path)
if not file.open(QIODevice.OpenModeFlag.ReadOnly):
    print("Failed to open the file: " + path)
  1. QApplication.exec_() 方法已重命名為 QApplication.exec()

PyQt5:

import sys
from PyQt5.QtWidgets import QApplication

app = QApplication(sys.argv)
sys.exit(app.exec_())

PyQt6:

import sys
from PyQt6.QtWidgets import QApplication

app = QApplication(sys.argv)
sys.exit(app.exec())

帶有子彈物理的落下 Collada Cube,OpenGL 3.3:

您應該安裝這些軟件包:

  • pip 安裝 PyQt6(或 PySide6)
  • pip 安裝 PyOpenGL
  • pip 安裝 numpy
  • pip 安裝 Panda3D(用於子彈物理)

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM