Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.
-
@ankou29666 said in Is it possible to add GUI for QOpenGLWindow?:
The only option I see then would be something like nesting QOpenGLWindow inside a QQuickWindow and do your ui in QtQuick and QML instead.
I will first try placing a QPushButton on top of a QOpenGLWindow as suggested by JoeCFD and then try your way.
-
@8Observer8 it is pseudocode. I do not know the center coordinates of your widget. You need to know where it is.
-
@JoeCFD said in Is it possible to add GUI for QOpenGLWindow?:
make a layout and add m_openGLWidget;
How to add it to layout?
QHBoxLayout *hbox = new QHBoxLayout(); hbox->addWidget(m_pOpenGLWindow);
error: no matching function for call to 'QHBoxLayout::addWidget(OpenGLWindow*&)' vbox->addWidget(m_pOpenGLWindow);
main_window.h
#ifndef MAIN_WINDOW_H #define MAIN_WINDOW_H #include <QtCore/QSize> #include <QtCore/QString> #include <QtWidgets/QHBoxLayout> #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)); m_pStartGameButton = new QPushButton(QString("Start Game"), this); // m_pStartGameButton->move(center); QHBoxLayout *hbox = new QHBoxLayout(); m_pOpenGLWindow = new OpenGLWindow(); hbox->addWidget(m_pOpenGLWindow); } ~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.2, 0.2, 1); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); // std::cout << "paintGL" << std::endl; } }; #endif // OPENGL_WINDOW_H
main.cpp
/* .pro file: QT += core gui opengl widgets win32: LIBS += -lopengl32 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(); }
-
@8Observer8 said in Is it possible to add GUI for QOpenGLWindow?:
m_pOpenGLWindow
m_pOpenGLWindow is not created. Is its header included? QOpenGLWidget is a widget. Sure you can add it to the layout.
-
I posted all the example code above.
-
@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