Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.
Forum Updated to NodeBB v4.3 + New Features

Is it possible to add GUI for QOpenGLWindow? The button should be in the center of the OpenGL canvas.

Scheduled Pinned Locked Moved Solved General and Desktop
40 Posts 4 Posters 6.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8Observer88 8Observer8

    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);
    
    JoeCFDJ Offline
    JoeCFDJ Offline
    JoeCFD
    wrote on last edited by
    #30

    @8Observer8

        m_pStartGameButton = new QPushButton(QString("Start Game"), this);
        m_pStartGameButton->move(0, 0);
        m_pStartGameButton->setWindowFlags(m_pStartGameButton->windowFlags() | Qt::WindowStaysOnTopHint);
    
    8Observer88 1 Reply Last reply
    0
    • JoeCFDJ JoeCFD

      @8Observer8

          m_pStartGameButton = new QPushButton(QString("Start Game"), this);
          m_pStartGameButton->move(0, 0);
          m_pStartGameButton->setWindowFlags(m_pStartGameButton->windowFlags() | Qt::WindowStaysOnTopHint);
      
      8Observer88 Offline
      8Observer88 Offline
      8Observer8
      wrote on last edited by 8Observer8
      #31

      @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);
      

      a4cdc27c-2a4d-4481-9543-7866d6401f5b-image.png

      JoeCFDJ 1 Reply Last reply
      0
      • 8Observer88 8Observer8

        @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);
        

        a4cdc27c-2a4d-4481-9543-7866d6401f5b-image.png

        JoeCFDJ Offline
        JoeCFDJ Offline
        JoeCFD
        wrote on last edited by JoeCFD
        #32

        @8Observer8
        Sorry. I will make a test case later.

        8Observer88 1 Reply Last reply
        0
        • JoeCFDJ JoeCFD

          @8Observer8
          Sorry. I will make a test case later.

          8Observer88 Offline
          8Observer88 Offline
          8Observer8
          wrote on last edited by 8Observer8
          #33

          @JoeCFD this is my current project: start-button-qopenglwindow-opengl21-qt6-cpp.zip

          ac756a6d-c021-4c83-9f1d-e19b436bc31f-image.png

          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
          
          JoeCFDJ 1 Reply Last reply
          0
          • S Offline
            S Offline
            SimonSchroeder
            wrote on last edited by
            #34

            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.

            1 Reply Last reply
            0
            • 8Observer88 8Observer8

              @JoeCFD this is my current project: start-button-qopenglwindow-opengl21-qt6-cpp.zip

              ac756a6d-c021-4c83-9f1d-e19b436bc31f-image.png

              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
              
              JoeCFDJ Offline
              JoeCFDJ Offline
              JoeCFD
              wrote on last edited by
              #35

              @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 );

              1 Reply Last reply
              1
              • JoeCFDJ JoeCFD referenced this topic on
              • 8Observer88 Offline
                8Observer88 Offline
                8Observer8
                wrote on last edited by 8Observer8
                #36

                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.

                1 Reply Last reply
                0
                • 8Observer88 Offline
                  8Observer88 Offline
                  8Observer8
                  wrote on last edited by
                  #37

                  I created a bug report:

                  Failed to place widget over widget container containing QOpenGLWindow
                  https://bugreports.qt.io/browse/QTBUG-113117

                  8Observer88 1 Reply Last reply
                  1
                  • 8Observer88 Offline
                    8Observer88 Offline
                    8Observer8
                    wrote on last edited by
                    #38

                    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):
                      086a2022-c230-4ac3-b7ac-714c38f695f2-button.png
                    • 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)

                    custom-start-button-opengl21-pyside6-python.gif

                    1 Reply Last reply
                    0
                    • 8Observer88 8Observer8

                      I created a bug report:

                      Failed to place widget over widget container containing QOpenGLWindow
                      https://bugreports.qt.io/browse/QTBUG-113117

                      8Observer88 Offline
                      8Observer88 Offline
                      8Observer8
                      wrote on last edited by 8Observer8
                      #39

                      @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-113117

                      Laszlo 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:

                      c8fb0a0f-d0e3-4d94-8ca2-622856b637c6-image.png

                      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);
                      

                      236e27e3-9c59-439c-a30d-cc35c08cc8a6-image.png

                      JoeCFDJ 1 Reply Last reply
                      2
                      • 8Observer88 8Observer8

                        @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-113117

                        Laszlo 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:

                        c8fb0a0f-d0e3-4d94-8ca2-622856b637c6-image.png

                        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);
                        

                        236e27e3-9c59-439c-a30d-cc35c08cc8a6-image.png

                        JoeCFDJ Offline
                        JoeCFDJ Offline
                        JoeCFD
                        wrote on last edited by JoeCFD
                        #40

                        @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.

                        1 Reply Last reply
                        2

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved