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
QtWS25 Last Chance

How to create a child-toolwindow for QOpenGLWindow

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 3 Posters 1.7k Views
  • 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.
  • J Offline
    J Offline
    Joe Malik
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      What about using a QOpenGLWidget so that you use the same technology for both ?

      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
        #3

        Hi SGaist,
        thank you very much for your response.
        Changing the base class to QOpenGLWidget helped to solve some of the issues like the ignored ToolWindow style and using the same technology for both sure is the better fit.
        One remaining issue is that when switching to fullscreen mode the second window still is moved to back when clicking somewhere in the mainwindow. In this situation the secondary window can be brought back to front when the user clicks in the first window in the area where the secondary window is located in the background. And it even reacts to this clicks not only by becoming active/focused/visible again. So if the user hits an area where it has e.g. a button it performs what ever action is connected to it.

        1 Reply Last reply
        0
        • 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