Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.
-
@JoeCFD said in Is it possible to add GUI for QOpenGLWindow?:
QOpenGLWidget is a widget. Sure you can add it to the layout.
I just replaced QOpenGLWidget to QOpenGLWindow in your example. I don't need QOpenGLWidget.
-
@8Observer8 You can not add it to the layout. I use QOpenGLWidget. You can overlay your button to any widget which holds QOpenGLWindow.
https://stackoverflow.com/questions/32593428/add-qwidget-on-top-of-qopenglwindow
-
@JoeCFD said in Is it possible to add GUI for QOpenGLWindow?:
https://stackoverflow.com/questions/32593428/add-qwidget-on-top-of-qopenglwindow
This is the only information I found on my topic through Google. But this question on StackOverflow doesn't have a solution, so I forgot about it. Now I noticed QWidget::createWindowContainer. But the question remains open. I'm trying to position a button in the center of an OpenGL window:
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); 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")); QHBoxLayout *startButtonLayout = new QHBoxLayout(); startButtonLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); startButtonLayout->addWidget(m_pStartGameButton); rootLayout->addLayout(startButtonLayout); } ~MainWindow() { delete m_pOpenGLWindow; } private: OpenGLWindow *m_pOpenGLWindow {}; QPushButton *m_pStartGameButton {}; }; #endif // MAIN_WINDOW_H
-
I found my mistake:
// rootLayout->addLayout(startButtonLayout); container->setLayout(startButtonLayout);
But it looks like the button is behind the OpenGL canvas like in the topic: https://stackoverflow.com/questions/32593428/add-qwidget-on-top-of-qopenglwindow
Is it a bug? -
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")); QHBoxLayout *startButtonLayout = new QHBoxLayout(); startButtonLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); startButtonLayout->addWidget(m_pStartGameButton); // rootLayout->addLayout(startButtonLayout); container->setLayout(startButtonLayout);
-
@8Observer8
Do not put it in the layout.m_pStartGameButton = new QPushButton(QString("Start Game"), this ); m_pStartGameButton->move( 150, 150 );
-
@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)