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. How to create a child-toolwindow for QOpenGLWindow
Forum Updated to NodeBB v4.3 + New Features

How to create a child-toolwindow for QOpenGLWindow

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 3 Posters 1.8k Views 1 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #4

    Can you show how you are handling these two widgets ?

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Joe Malik
      wrote on last edited by
      #5

      Hi SGaist,
      thanks again for your support with this problem.
      Below I'm trying to provide all relevant portions of my code regarding the two widgets while excluding everything else for better clarity.
      My second best option probably would be just to combine viewport and controls in one widget and thus avoid the always-on-top requirement entirely. Although I would of course prefer to learn what I was missing here.

      class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
      {
      	Q_OBJECT
      	friend class ControlDialog;
      public:
      	OpenGLWidget();
      	~OpenGLWidget();
      protected:
      	bool event(QEvent *event) override;
      	void keyPressEvent(QKeyEvent *e) override;
      	void toggleFullscreen();
      private:
      	ControlDialog* m_ctrlDlg = nullptr;
      };
      
      OpenGLWidget::OpenGLWidget()
      	: QOpenGLWidget()
      {
      	setGeometry(300, 300, 800, 800);
      
      	m_ctrlDlg = new ControlDialog(*this, *m_boids);
      	m_ctrlDlg->show();
      	m_ctrlDlg->setWindowFlags(m_ctrlDlg->windowFlags() | Qt::WindowStaysOnTopHint);
      }
      
      OpenGLWidget::~OpenGLWidget()
      {
      	delete m_ctrlDlg;
      	m_ctrlDlg = nullptr;
      }
      
      bool OpenGLWidget::event(QEvent *event)
      {
      	switch (event->type())
      	{
      	case QEvent::Close:
      		m_postfx->running = false;
      		m_ctrlDlg->close();
      		break;
      	}
      	return QOpenGLWidget::event(event);
      }
      
      void OpenGLWidget::keyPressEvent(QKeyEvent *e)
      {
      	switch (e->key())
      	{
      	case Qt::Key_F:
      	case Qt::Key_F11:
      		toggleFullscreen();
      		break;
      	}
      }
      
      void OpenGLWidget::toggleFullscreen()
      {
      	if (windowState() & Qt::WindowFullScreen)
      		showNormal();
      	else
      		showFullScreen(); // TODO: control dialog is in background, bring it back to front
      }
      
      // ----------------------------------------------------------------------------
      
      class ControlDialog : public QDialog
      {
      	Q_OBJECT
      public:
      	ControlDialog(OpenGLWidget& mainWnd, CLBoids& boids);
      
      protected:
      	void keyPressEvent(QKeyEvent *e) override;
      	void showEvent(QShowEvent *e) override {} // empty override to suppress re-centering of dialog on Show event
      
      private:
      	bool eventFilter(QObject *obj, QEvent *event);
      	OpenGLWidget& m_mainWnd;
      	QTimer m_hideTimer;
      };
      
      ControlDialog::ControlDialog(OpenGLWidget& mainWnd)
      	: QDialog(&mainWnd, Qt::WindowStaysOnTopHint)
      	, m_mainWnd(mainWnd)
      {
      	m_ui.setupUi(this);
      	
      	setWindowFlag(Qt::Tool);
      	setWindowFlag(Qt::WindowMaximizeButtonHint, false);
      	setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
      
      	qApp->installEventFilter(this);
      	m_hideTimer.setInterval(5000);
      	m_hideTimer.callOnTimeout([&](){ hide(); });
      	m_hideTimer.start();
      }
      
      void ControlDialog::keyPressEvent(QKeyEvent* e)
      {
      	m_mainWnd.keyPressEvent(e); // forward events to main window
      }
      
      bool ControlDialog::eventFilter(QObject* obj, QEvent* event)
      {
      	switch (event->type())
      	{
      	case QEvent::Close:
      		m_mainWnd.close();
      		break;
      	case QEvent::MouseMove:
      	case QEvent::KeyPress:
      		m_hideTimer.start(); // resets timeeout
      		if( !isVisible() )
      			show();
      		break;
      	}
      	return false;
      }
      
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #6

        That looks a bit very convoluted.

        Can you explain what that tool window is responsible for in your application ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • J Offline
          J Offline
          Joe Malik
          wrote on last edited by
          #7

          OpenGLWidget serves as main window. It is created from main() and does not contain any child widgets and provides the OpenGL viewport.
          The ControlDialog tool window contains a couple of sliders to adjust some parameters and shader uniforms of the animation running in the main window. It is created as child of the OpenGLWidget. The goal of splitting viewport and controls in two windows was to show the UI when required and hide it by timeout when there is no user input so it does not distract the view when running in fullscreen mode.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #8

            Ok, then let's simplify things a bit.

            You should have slots in your OpenGLWidget that allows to adjust whatever values you want.

            Then add signals to your ControlDialog that emits the values of the corresponding controls.

            Connect these to together and voilà, no need for passing events around and you can easily implement new controls without worrying about handling events.

            This also makes both widgets completely independent and thus easier to maintain.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            J 1 Reply Last reply
            1
            • J Joe Malik

              Hi folks,
              I'm working on a small project where I have a QOpenGLWindow as primary window, which can be displayed either as window of fullscreen and I would like to have a second window with some control widgets which should be a non-modal child of the first one and always stay on top if. In the ideal case it should be a toolwindow. Currently I'm using QDialog for this, but it is not working as intended although I'm setting

              setWindowFlag(Qt::Tool);
              setWindowFlags(Qt::WindowStaysOnTopHint);
              

              I'm also trying to set windowHandle()->setTransientParent(MainWindowPtr);
              but it forces the dialog always to the center of the MainWindow when shown.

              I really would appreciate any advice on how I could better approach this use case.

              C Offline
              C Offline
              CroCo
              wrote on last edited by
              #9

              @Joe-Malik so you need two separate windows, right? One for OpenGL and second for control options.

              J 1 Reply Last reply
              0
              • SGaistS SGaist

                Ok, then let's simplify things a bit.

                You should have slots in your OpenGLWidget that allows to adjust whatever values you want.

                Then add signals to your ControlDialog that emits the values of the corresponding controls.

                Connect these to together and voilà, no need for passing events around and you can easily implement new controls without worrying about handling events.

                This also makes both widgets completely independent and thus easier to maintain.

                J Offline
                J Offline
                Joe Malik
                wrote on last edited by
                #10

                Hi @SGaist,
                I can surely agree on the general advantages of message passing and decoupling you outlined. And I also see it as a worthy idea to consider a generalized event based shader parameter passing mechanism.
                I really won't claim that my choosen way to handle reciprocal dependency of the two widgets is the best possible design neither for the general nor current case. So far I just judged it as good enough and IMHO all possible approaches on this come with their own pros and cons.
                But in the end I don't understand how this questions of software design (which is always a good topic to think and talk about) relates to my initial problem of making the second widget stay on top?

                SGaistS 1 Reply Last reply
                0
                • C CroCo

                  @Joe-Malik so you need two separate windows, right? One for OpenGL and second for control options.

                  J Offline
                  J Offline
                  Joe Malik
                  wrote on last edited by
                  #11

                  Hi @CroCo,
                  thanks a lot for your reply.
                  Yes, I would like to have two widgets. One for OpenGL and the second for some control widgets with the additional requirement that it should stay always on top of the first one even if it is shown in fullscreen mode.

                  1 Reply Last reply
                  0
                  • J Joe Malik

                    Hi @SGaist,
                    I can surely agree on the general advantages of message passing and decoupling you outlined. And I also see it as a worthy idea to consider a generalized event based shader parameter passing mechanism.
                    I really won't claim that my choosen way to handle reciprocal dependency of the two widgets is the best possible design neither for the general nor current case. So far I just judged it as good enough and IMHO all possible approaches on this come with their own pros and cons.
                    But in the end I don't understand how this questions of software design (which is always a good topic to think and talk about) relates to my initial problem of making the second widget stay on top?

                    SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    @Joe-Malik said in How to create a child-toolwindow for QOpenGLWindow:

                    But in the end I don't understand how this questions of software design (which is always a good topic to think and talk about) relates to my initial problem of making the second widget stay on top?

                    Mostly unrelated because I got sidetracked by the implementation.

                    What OS are you currently your application on ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    J 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      @Joe-Malik said in How to create a child-toolwindow for QOpenGLWindow:

                      But in the end I don't understand how this questions of software design (which is always a good topic to think and talk about) relates to my initial problem of making the second widget stay on top?

                      Mostly unrelated because I got sidetracked by the implementation.

                      What OS are you currently your application on ?

                      J Offline
                      J Offline
                      Joe Malik
                      wrote on last edited by
                      #13

                      Hi @SGaist,
                      thank you very much for staying tuned to this topic.
                      I'm running on Windows 10 x64 and builing with Qt 5.12.1, VS 2017 v141 and Win SDK 10.0.17763.0.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #14

                        What if you don't give your dialog any parent ?

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        J 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          What if you don't give your dialog any parent ?

                          J Offline
                          J Offline
                          Joe Malik
                          wrote on last edited by
                          #15

                          Setting no parent for the control dialog makes the behaviour even worse.

                          • If the control dialog is a child of the OpenGLWidget and I switch it to fullscreen the control dialog is shown on top as intended. When I now click somewhere in the viewport the control dialog is sent to the background. When I then click again in the viewport somewhere in the area where the control dialog was located it gets back in the foreground.

                          • If the control dialog has no parent and I switch to fullscreen mode it it is sent to background and stays there until I leave fullscreen mode no matter where I click. It is also not possible to switch to it via Alt+Tab or move it in front of the fullscreen viewport from a second monitor.

                          In both cases it seems to be the focused state of the OpenGLWidget which keeps the control dialog from getting back to top again.

                          1 Reply Last reply
                          0

                          • Login

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