Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.
-
@JoeCFD I don't see the button again:
QVBoxLayout *rootLayout = new QVBoxLayout(); setLayout(rootLayout); m_pOpenGLWindow = new OpenGLWindow(); QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow); rootLayout->addWidget(container); m_pStartGameButton = new QPushButton(QString("Start Game"), this); // QHBoxLayout *startButtonLayout = new QHBoxLayout(); // startButtonLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); // startButtonLayout->addWidget(m_pStartGameButton); // container->setLayout(startButtonLayout); m_pStartGameButton->move(150, 150);
-
@8Observer8
Read the link I posted. Raise your button. Call button->raise();Qt cannot divine what Z order you want if you don't create the widgets in Z order. You need to raise the widget. The whole hiding rigmarole is completely unnecessary anyway. Simply create the widget where you need it.
-
@JoeCFD said in Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.:
Raise your button. Call button->raise();
It doesn't work:
m_pStartGameButton = new QPushButton(QString("Start Game"), this); m_pStartGameButton->raise(); m_pStartGameButton->move(0, 0);
-
Current code:
QVBoxLayout *rootLayout = new QVBoxLayout(); setLayout(rootLayout); m_pOpenGLWindow = new OpenGLWindow(); QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow); rootLayout->addWidget(container); m_pStartGameButton = new QPushButton(QString("Start Game"), this); m_pStartGameButton->raise(); m_pStartGameButton->move(0, 0);
-
m_pStartGameButton = new QPushButton(QString("Start Game"), this); m_pStartGameButton->move(0, 0); m_pStartGameButton->setWindowFlags(m_pStartGameButton->windowFlags() | Qt::WindowStaysOnTopHint);
-
@JoeCFD unfortunately it doesn't work:
QVBoxLayout *rootLayout = new QVBoxLayout(); setLayout(rootLayout); m_pOpenGLWindow = new OpenGLWindow(); QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow); rootLayout->addWidget(container); m_pStartGameButton = new QPushButton(QString("Start Game"), this); // m_pStartGameButton->raise(); m_pStartGameButton->move(0, 0); m_pStartGameButton->setWindowFlags(m_pStartGameButton->windowFlags() | Qt::WindowStaysOnTopHint);
-
@8Observer8
Sorry. I will make a test case later. -
@JoeCFD this is my current project: start-button-qopenglwindow-opengl21-qt6-cpp.zip
main.cpp
/* .pro file: QT += core gui opengl widgets win32: LIBS += -lopengl32 HEADERS += main_window.h opengl_window.h SOURCES += main.cpp TARGET = app ------------------------------- Build and run commands for CMD: > qmake -makefile > mingw32-make > "release/app" */ #ifdef _WIN32 #include <windows.h> extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; #endif #include <QtWidgets/QApplication> #include <iostream> #include "main_window.h" int main(int argc, char *argv[]) { #ifdef _WIN32 if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); } #endif std::cout << std::endl; QApplication app(argc, argv); MainWindow w; w.show(); return app.exec(); }
main_window.h
#ifndef MAIN_WINDOW_H #define MAIN_WINDOW_H #include <QtCore/QSize> #include <QtCore/QString> #include <QtWidgets/QHBoxLayout> #include <QtWidgets/QVBoxLayout> #include <QtWidgets/QPushButton> #include <QtWidgets/QWidget> #include "opengl_window.h" class MainWindow : public QWidget { public: explicit MainWindow(QWidget *parent=nullptr) : QWidget(parent) { setFixedSize(QSize(300, 300)); setWindowTitle("OpenGL 2.1, Qt6, C++"); // m_pStartGameButton->move(center); // QHBoxLayout *startButtonLayout = new QHBoxLayout(); // startButtonLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); // startButtonLayout->addWidget(m_pStartGameButton); // container->setLayout(startButtonLayout); QVBoxLayout *rootLayout = new QVBoxLayout(); setLayout(rootLayout); m_pOpenGLWindow = new OpenGLWindow(); QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow, this); rootLayout->addWidget(container); m_pStartGameButton = new QPushButton(QString("Start Game"), this); // m_pStartGameButton->raise(); m_pStartGameButton->move(0, 0); m_pStartGameButton->setWindowFlags(m_pStartGameButton->windowFlags() | Qt::WindowStaysOnTopHint); } ~MainWindow() { delete m_pOpenGLWindow; } private: OpenGLWindow *m_pOpenGLWindow {}; QPushButton *m_pStartGameButton {}; }; #endif // MAIN_WINDOW_H
opengl_window.h
#ifndef OPENGL_WINDOW_H #define OPENGL_WINDOW_H #include <QtCore/QSize> #include <QtGui/QOpenGLFunctions> #include <QtGui/QSurfaceFormat> #include <QtOpenGL/QOpenGLWindow> #include <iostream> class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions { public: OpenGLWindow() { resize(QSize(300, 300)); setTitle("OpenGL 2.1, Qt6, C++"); // Set format QSurfaceFormat format; format.setSamples(4); format.setSwapInterval(1); setFormat(format); connect(this, SIGNAL(frameSwapped()), this, SLOT(update())); } private: void initializeGL() override { initializeOpenGLFunctions(); glClearColor(0.2, 0.5, 0.2, 1); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); // std::cout << "paintGL" << std::endl; } }; #endif // OPENGL_WINDOW_H
start-button-qopenglwindow-opengl21-qt6-cpp.pro
QT += core gui opengl widgets win32: LIBS += -lopengl32 HEADERS += main_window.h opengl_window.h SOURCES += main.cpp TARGET = app
-
I distinctly remember that Qt at one point announced support for QWidgets within OpenGL. However, I am not quite able to find that announcement again. Maybe support has been discontinued with Qt 6.
What I have found so far is this: https://docs.huihoo.com/qt/5.x/qtwidgets-graphicsview-boxes-example.html
I haven't read through the entire code to make sure that the widgets are drawn on some OpenGL canvas. Having a quick look at QGraphicsProxyWidget suggests that it might help with what you are trying to achieve. It still seems to exist in Qt 6. -
@8Observer8 Sorry I could not make it with QOpenGLWindow. I use QOpenGLWidget which is ok.
You also need to add a parent to the container in order to avoid leak.
QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow, this ); -
-
If QOpenGLWindow is inherited from QWindow, does that mean I can use the QML GUI in QOpenGLWindow?
@JoeCFD said in Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.:
You also need to add a parent to the container in order to avoid leak.
QWidget *container = QWidget::createWindowContainer(m_pOpenGLWindow, this );Fixed in the message above and in the archive.
-
I created a bug report:
Failed to place widget over widget container containing QOpenGLWindow
https://bugreports.qt.io/browse/QTBUG-113117 -
My steps of creation a button on QOpenGLWindow:
- Collection of free GUI assets: https://itch.io/game-assets/tag-gui
- This asset pack https://wenrexa.itch.io/holoui contains two textures for button: normal and active. I added a text in GIMP. The textures was packed with Free Texture Packer (.png + .json):
- I wrote a shader to get a button with glReadPixels by color ID
Source code in PySide6 and OpenGL 2.1
Source code in PyQt6 and OpenGL 2.1
Demo in JavaScript and WebGL 1.0
EXE in Qt C++ for Window 10 64-bit (7.48 MB) -
@8Observer8 said in Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.:
I created a bug report:
Failed to place widget over widget container containing QOpenGLWindow
https://bugreports.qt.io/browse/QTBUG-113117Laszlo Agocs added a comment with the following solution to the problem:
m_pStartGameButton = new QPushButton(QString("Start Game"), this); m_pStartGameButton->winId(); // add this m_pStartGameButton->move(0, 0);
It works:
I added this code to center the button:
float buttonHalfWidth = m_pStartGameButton->width() / 2.f; float buttonHalfHeight = m_pStartGameButton->height() / 2.f; m_pStartGameButton->move(width() / 2.f - buttonHalfWidth, height() / 2.f - buttonHalfHeight);
-
@8Observer8 Good to know. Thanks. Actually, I wanted to ask you if you tried it.
m_pStartGameButton->winId(); // add this <<=========this is the tricky part.