Place QLabel over QOpenGLWidget
PySide6, Python:
fe2ce83d-3eb7-4144-9459-751fa9c9c565-image.png
main.py
import sys
from OpenGL.GL import (GL_COLOR_BUFFER_BIT, GL_SCISSOR_TEST, glClear,
glClearColor, glDisable, glEnable, glScissor,
glViewport)
from PySide6.QtCore import Qt
from PySide6.QtGui import QSurfaceFormat
from PySide6.QtOpenGLWidgets import QOpenGLWidget
from PySide6.QtWidgets import QApplication, QLabel
class OpenGLWidget(QOpenGLWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("OpenGL ES 2.0, PySide6, Python")
self.resize(380, 380)
self.worldWidth = 200
self.worldHeight = 100
self.worldAspect = self.worldHeight / self.worldWidth
surfaceFormat = QSurfaceFormat()
surfaceFormat.setDepthBufferSize(24)
surfaceFormat.setSamples(4)
self.setFormat(surfaceFormat)
self.scoreLabel = QLabel("Score: 0", self)
self.scoreLabel.setStyleSheet("font-size: 24px;")
def initializeGL(self):
pass
def resizeGL(self, w, h):
deviceW = w * self.devicePixelRatio()
deviceH = h * self.devicePixelRatio()
deviceAspect = deviceH / deviceW
if deviceAspect > self.worldAspect:
self.viewportWidth = int(deviceW)
self.viewportHeight = int(deviceW * self.worldAspect)
self.viewportX = 0
self.viewportY = int((deviceH - self.viewportHeight) / 2)
else:
self.viewportWidth = int(deviceH / self.worldAspect)
self.viewportHeight = int(deviceH)
self.viewportX = int((deviceW - self.viewportWidth) / 2)
self.viewportY = 0
def paintGL(self):
glClearColor(0.2, 0.2, 0.2, 1)
glClear(GL_COLOR_BUFFER_BIT)
glViewport(self.viewportX, self.viewportY, self.viewportWidth, self.viewportHeight)
glScissor(self.viewportX, self.viewportY, self.viewportWidth, self.viewportHeight)
glClearColor(0.04, 0.62, 0.48, 1)
glEnable(GL_SCISSOR_TEST)
glClear(GL_COLOR_BUFFER_BIT)
glDisable(GL_SCISSOR_TEST)
self.scoreLabel.move(self.viewportX / self.devicePixelRatio() + 10,
self.viewportY / self.devicePixelRatio() + 10);
if __name__ == "__main__":
QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
app = QApplication(sys.argv)
w = OpenGLWidget()
w.show()
sys.exit(app.exec())
Qt6, C++:
e6099583-2553-492d-965e-a9f63d9f4aeb-image.png
main.cpp
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QSurfaceFormat>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtOpenGLWidgets/QOpenGLWidget>
class OpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
{
public:
OpenGLWidget()
{
setWindowTitle("OpenGL ES 2.0, Qt6, C++");
resize(380, 380);
QSurfaceFormat surfaceFormat;
surfaceFormat.setDepthBufferSize(24);
surfaceFormat.setSamples(4);
setFormat(surfaceFormat);
m_pScoreLabel = new QLabel("Score: 0", this);
m_pScoreLabel->setStyleSheet("font-size: 24px;");
}
void initializeGL() override
{
initializeOpenGLFunctions();
}
void resizeGL(int w, int h) override
{
int deviceW = w * devicePixelRatio();
int deviceH = h * devicePixelRatio();
float deviceAspect = deviceH / (float) deviceW;
if (deviceAspect > m_worldAspect)
{
m_viewportWidth = deviceW;
m_viewportHeight = (int) deviceW * m_worldAspect;
m_viewportX = 0;
m_viewportY = (int) (deviceH - m_viewportHeight) / 2.f;
qDebug() << deviceH << m_viewportHeight << m_viewportY;
}
else
{
m_viewportWidth = (int) deviceH / m_worldAspect;
m_viewportHeight = deviceH;
m_viewportX = (int) (deviceW - m_viewportWidth) / 2.f;
m_viewportY = 0;
}
}
void paintGL() override
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.2, 0.2, 0.2, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
glScissor(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
glClearColor(0.04, 0.62, 0.48, 1);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
m_pScoreLabel->move(m_viewportX / devicePixelRatio() + 10,
m_viewportY / devicePixelRatio() + 10);
}
private:
const float m_worldWidth = 200.f;
const float m_worldHeight = 100.f;
float m_worldAspect = m_worldHeight / m_worldWidth;
int m_viewportX;
int m_viewportY;
int m_viewportWidth;
int m_viewportHeight;
QLabel *m_pScoreLabel;
};
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
QApplication app(argc, argv);
OpenGLWidget w;
w.show();
return app.exec();
}
qlabel-over-qopenglwidget-opengles2-qt6-cpp.pro
QT += core gui openglwidgets widgets
win32: LIBS += -lopengl32
CONFIG += c++17
SOURCES += \
main.cpp
It doesn't work on WebAssembly: see demo. Because of this bug: https://bugreports.qt.io/browse/QTBUG-120651 But you can use the patch from the "Gerrit Reviews" (read the comments on the bug report)
But it works on Android:
ada173ff-cfc0-4a44-86a5-be4e530c7cc7-image.png
f7c0e069-3337-4391-8232-cf0676306689-image.png