1

I try to run a very simple OpenGL example:

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

But I have this error:

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

It is the same example but in PyQt5 that works:

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

There are two differences:

    1. QOpenGLWidget was moved to PyQt6.QtOpenGLWidgets
    1. the line in the PyQt5 example: QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
8Observer8
  • 868
  • 10
  • 17
  • 2
    @8Observer8 No, the question *must* be self-contained (no pastebin/repository), and the code *must* be shown as text, not as images. The system prevents users to create questions that are almost text, as most of the times it means that there's almost no research efforts (which is a major requirement for StackOverflow). Have you done some research on that particular error? Have you done some attempts in fixing it based on your findings? If yes, then explain what you tried, add more details about those attempts. If not, then your question doesn't meet the basic quality standards of the site. – musicamante Jun 20 '22 at 16:17
  • @musicamante, I tried to google but did not find anything. I rewrote this example to Qt6 C++ - it works in C++. What else can I try? – 8Observer8 Jun 20 '22 at 16:20
  • @Rabbid76 my another example https://rextester.com/JNC31813 works with PyQt5, but why does not it work with PyQt6? – 8Observer8 Jun 20 '22 at 16:23
  • 1
    @8Observer8 Then: 1. find the differences between those two (***all*** differences, not only the OpenGL parts); 2. add all that relevant information to your post. – musicamante Jun 20 '22 at 16:26
  • @musicamante I tried to run this example with PyQt5 and it works. But I cannot add `QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)` I think `Qt.AA_UseDesktopOpenGL` was removed form PyQt6 – 8Observer8 Jun 20 '22 at 16:34
  • 2
    Again, add that relevant information *to the post*. It's by adding details that the question becomes valid (which also means that it probably gets more upvotes, more visibility and, as a result, more possibility that people would notice it and eventually answer it). – musicamante Jun 20 '22 at 16:38
  • @musicamante I must add a lot of text to save it. I have only one fact that `Qt.AA_UseDesktopOpenGL` was removed https://doc.qt.io/qt-6/opengl-changes-qt6.html PyQt6 cannot run the example without this attribute. – 8Observer8 Jun 20 '22 at 16:49
  • If the only difference is that attribute, you obviously don't need to write the same code twice, **explain that difference** in the question. If you want to find the difference between two codes, then you have to *minimize* them until you only get the *actual* difference that makes one run and the other to crash. Right now, the codes you're providing are *too* different. – musicamante Jun 20 '22 at 16:56
  • @musicamante it is the same example but in PyQt5: https://rextester.com/CEG31228 There are two differences: 1) QOpenGLWidget was moved to PyQt6.QtOpenGLWidgets 2) the line in the PyQt5 example: `QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)` – 8Observer8 Jun 20 '22 at 17:14
  • 1
    For the last time: you must write all that ***in the question***. – musicamante Jun 20 '22 at 17:27
  • @Rabbid76 I installed PySide6 and it works: https://rextester.com/ABVBV74278 PySide6 allows to use this line of code like in PyQt5: `QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)` The PyQt6 example does not work without this line but it does not allows to add this line of code. – 8Observer8 Jun 20 '22 at 20:11
  • I made a better topic here: https://forum.qt.io/topic/137360/pyqt6-does-not-allow-to-use-the-qt-aa_usedesktopopengl-attribute – 8Observer8 Jun 20 '22 at 20:18
  • 1
    It doesn't allow because you still don't want to **expand your description**. Add more *verbose* details about your tests, be more descriptive (but not too much, just enough to make things clear - and avoid the system limits of the body/code ratio). Besides, this is ***not*** a forum. That's why you have to add the details *to the question*, and use comments only when necessary. Also, PyQt6 has removed anything from Qt, it's a *binding*: they only changed the *python* access to enums, which now require the full enum scope: `Qt.ApplicationAttribute.AA_UseDesktopOpenGL`. – musicamante Jun 20 '22 at 20:34
  • @musicamante I don't really know what details I could add. These two little examples require as many sentences as I can't compose with all my will. This looks like a PyQt6 bug because PySide6 works just fine. I sent an email to the PyQt6 authors with a link to the topic: https://forum.qt.io/topic/137360/pyqt6-does-not-allow-to-use-the-qt-aa_usedesktopopengl-attribute – 8Observer8 Jun 20 '22 at 20:53
  • 1
    That is *not* a bug, I already explained that PyQt6 introduced the *full* enum scope, so you **must** use the full enum name as said above. – musicamante Jun 20 '22 at 20:58
  • @musicamante Sorry, I didn't read your post to the end. Yes you are right this works: `QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)` Why didn't you answer in this topic? This is the correct answer! Thank you! – 8Observer8 Jun 20 '22 at 20:58
  • 1
    Because it took you 2 hours of showing what was the *actual* code that originally gave you the issue. If you instead had explained the step-by-step procedure and *explained* (not necessarily showing the full code) those differences, we would've solved the issue in minutes since your question. Please, carefully consider this for future reference. There are almost *no* cases for which you can't add more details in your questions, and if you just have a 2 line question body with a >50 lines of code, that just means that you've not being thorough enough with your research or description. – musicamante Jun 20 '22 at 21:24
  • 1
    You don't need to write a novel. You could've *verbosely explained* that you've tried the code on PyQt5 and works fine, that your research showed that an attribute is now obsolete (with the link to that) on Qt6, that the PySide6 version works with that correction, but you couldn't use it on PyQt6, just *pointing* out the line(s) that caused the errors (without showing the whole code again). To clarify, the length of *this* comment alone (a *summary* of what you could've written instead of using comments) would have made your question valid with the code you provided. – musicamante Jun 20 '22 at 21:25
  • A few basic changes in PyQt6 regarding shader-based OpenGL graphics: https://forum.qt.io/topic/137468/a-few-basic-changes-in-pyqt6-regarding-shader-based-opengl-graphics – 8Observer8 Jun 25 '22 at 21:46
  • Falling Collada Cube with Bullet Physics, OpenGL 3.3, PyQt6: https://github.com/8Observer8/falling-collada-cube-bullet-physics-opengl33-pyqt6 – 8Observer8 Jun 26 '22 at 09:52
  • Falling Collada Cube with Bullet Physics, OpenGL 3.3, PySide6: https://github.com/8Observer8/falling-collada-cube-bullet-physics-opengl33-pyside6 – 8Observer8 Jun 26 '22 at 09:52

1 Answers1

2

This line:

QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)

should be replaced with this:

QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)

These changes also apply to PySide6:

  1. OpenGL classes have been moved to a separate PyQt6.QtOpenGL namespace:

PyQt5:

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

PyQt6:

from PyQt6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram,
                            QOpenGLTexture)
  1. The QOpenGLWidget class has been moved to the PyQt6.QtOpenGLWidgets namespace:

PyQt5:

from PyQt5.QtWidgets import QApplication, QOpenGLWidget

PyQt6:

from PyQt6.QtOpenGLWidgets import QOpenGLWidget
  1. Changed enum for shader types:

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. Changed enum Target texture:

PyQt5:

self.texture = QOpenGLTexture(QOpenGLTexture.Target2D)

PyQt6:

self.texture = QOpenGLTexture(QOpenGLTexture.Target.Target2D)
  1. Changed enum for setting texture filters:

PyQt5:

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

PyQt6:

self.texture.setMinMagFilters(QOpenGLTexture.Filter.Linear, QOpenGLTexture.Filter.Linear)
  1. Changed enum for WrapMode:

PyQt5:

self.texture.setWrapMode(QOpenGLTexture.ClampToEdge)

PyQt6:

self.texture.setWrapMode(QOpenGLTexture.WrapMode.ClampToEdge)
  1. Changed enum to set application attributes:

PyQt5:

QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)

PyQt6:

QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)

A few basic non-graphical changes:

  1. Changed enum for file open mode:

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. The QApplication.exec_() method has been renamed to 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())

Falling Collada Cube with Bullet Physics, OpenGL 3.3:

You should install these packages:

  • pip install PyQt6 (or PySide6)
  • pip install PyOpenGL
  • pip install numpy
  • pip install Panda3D (for Bullet Physics)

enter image description here

8Observer8
  • 868
  • 10
  • 17