My current PyQt6 example does not show a window and does not give me any error messages. This PyQt6 example is just a copy of Qt C++. The following Qt C++ example works without problems even in the browser and on Android:
pro
QT += core gui openglwidgets
win32: LIBS += -lopengl32
CONFIG += c++17
SOURCES += \
main.cpp
main.cpp
#include <QtGui/QOpenGLFunctions>
#include <QtOpenGL/QOpenGLBuffer>
#include <QtOpenGL/QOpenGLShader>
#include <QtOpenGL/QOpenGLShaderProgram>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QtWidgets/QApplication>
class OpenGLWindow : public QOpenGLWidget, private QOpenGLFunctions
{
public:
OpenGLWindow()
{
setWindowTitle("OpenGL ES 2.0, Qt6, C++");
resize(350, 350);
}
void initializeGL() override
{
initializeOpenGLFunctions();
glClearColor(48.f / 255.f, 56.f / 255.f, 65.f / 255.f, 1.f);
QString vertShaderSrc =
"attribute vec2 aPosition;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPosition, 0.0, 1.0);\n"
"}\n";
QString fragShaderSrc =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(0.2, 0.7, 0.3, 1.0);\n"
"}\n";
m_program.create();
m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::ShaderTypeBit::Fragment, fragShaderSrc);
m_program.link();
m_program.bind();
float vertPositions[] = {
-0.5f, -0.5f,
0.5f, -0.5f,
0.f, 0.5f
};
m_vertPosBuffer.create();
m_vertPosBuffer.bind();
m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
}
void paintGL() override
{
glClear(GL_COLOR_BUFFER_BIT);
m_program.bind();
m_vertPosBuffer.bind();
m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2);
m_program.enableAttributeArray("aPosition");
glDrawArrays(GL_TRIANGLES, 0, 3);
}
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertPosBuffer;
};
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
QApplication app(argc, argv);
OpenGLWindow w;
w.show();
return app.exec();
}
This is my trying to rewrite the code above to PyQt6. As you can see I want to rewrite it very close to Qt C++. I want to have two very similar example. But this code does not show a window and does not show any error messages.
Note. I have fixed the problem after eyllanesc's answer in the code below:
main.py
import sys
import numpy as np
from OpenGL.GL import (GL_COLOR_BUFFER_BIT, GL_FLOAT, GL_TRIANGLES, glClear,
glClearColor, glDrawArrays)
from PyQt6.QtCore import Qt
from PyQt6.QtOpenGL import QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
from PyQt6.QtWidgets import QApplication
class OpenGLWindow(QOpenGLWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("OpenGL ES 2.0, PyQt6, Python")
self.resize(350, 350)
def initializeGL(self):
glClearColor(48 / 255, 56 / 255, 65 / 255, 1)
vertShaderSrc = """
attribute vec2 aPosition;
void main()
{
gl_Position = vec4(aPosition, 0.0, 1.0);
}
"""
fragShaderSrc = """
#ifdef GL_ES
precision mediump float;
#endif
void main()
{
gl_FragColor = vec4(0.2, 0.7, 0.3, 1.0);
}
"""
self.program = QOpenGLShaderProgram(self)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, vertShaderSrc)
self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, fragShaderSrc)
self.program.link()
self.program.bind()
vertPositions = np.array([
-0.5, -0.5,
0.5, -0.5,
0, 0.5], dtype=np.float32)
self.vertPosBuffer = QOpenGLBuffer()
self.vertPosBuffer.create()
self.vertPosBuffer.bind()
self.vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4)
def resizeGL(self, w, h):
pass
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT)
self.program.bind()
self.vertPosBuffer.bind()
self.program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 2)
self.program.enableAttributeArray("aPosition")
glDrawArrays(GL_TRIANGLES, 0, 3)
if __name__ == "__main__":
QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
app = QApplication(sys.argv)
w = OpenGLWindow()
w.show()
sys.exit(app.exec())
The problem is that the QOpenGLBuffer is a local variable that is destroyed instantly, whereas in C++ QOpenGLBuffer is an attribute of the class. The solution is to change vertPosBuffer
to self.vertPosBuffer