Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Proper way to open a QDialog

    General and Desktop
    3
    6
    2016
    Loading More Posts
    • 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.
    • C
      casperbear last edited by

      Hello! I'm trying to figure out a way to properly open a QDialog immediately after QMainWindow is shown. In examples below

      class WMain : public QMainWindow
      ...
      class WNew : public QDialog
      

      So far I've tried three approaches:
      1)

      void WMain::showEvent(QShowEvent *event)
      {
          QMainWindow::showEvent(event);
      
          WNew window(this);
          window.exec();
      }
      

      QMainWindow is not shown before QDialog is shown. Internet says it's because QDialog::exec is a synchronous call. Changing showEvent to the first paintEvent doesn't solve the problem (QMainWindow is shown before QDialog is shown, but some QMainWindow controls may be black). Using timer-based solutions doesn't look right.
      2)

      void WMain::showEvent(QShowEvent *event)
      {
          QMainWindow::showEvent(event);
      
          WNew window(this);
          window.open();
      }
      

      QDialog is not shown at all. I assume it's because QDialog::open is an asynchronous call and WNew destructor is called when code exits showEvent function.
      3)

      void WMain::showEvent(QShowEvent *event)
      {
          QMainWindow::showEvent(event);
      
          WNew *window = new WNew(this);
          window->open();
      }
      

      This seems to work, but there is a memory leak. WNew destructor is not called when the dialog is closed. Can you suggest please where I should call the destructor? Or some different approach?

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        Can you explain your use case ?

        As for the memory leak, you can set the ”WA_DeleteOnClose” widget attribute.

        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 Reply Quote 4
        • M
          mpergand last edited by

          You can use show() :

          void show()
                  {
                  QMainWindow::show();
                  WNew dlg(this);
                  dlg.exec();
                  }
          
          1 Reply Last reply Reply Quote 0
          • C
            casperbear last edited by

            My use case is that I have a dialog for creating a new document. This dialog should be initiated by a user click and also opened on application start.
            WA_DeleteOnClose worked for me. Thank you. I would have never guessed this attribute.

            It's particularly convenient that I can programmatically control when to use it. (Use it when dialog object is created in heap and don't use it when dialog object is created in stack)

            // on application start
            void WMain::showEvent(QShowEvent *event)
            {
                QMainWindow::showEvent(event);
            
                WNew *window = new WNew(this);
                window->setAttribute(Qt::WA_DeleteOnClose);
                window->open();
            }
            
            // on user click
            void WMain::on_actionNew_triggered()
            {
                WNew window(this);
                window.exec();
            }
            
            1 Reply Last reply Reply Quote 1
            • SGaist
              SGaist Lifetime Qt Champion last edited by

              The you should rather use a single shot QTimer with 0 as timeout value at the end of your constructor to call a slot that will show your dialog. This way the event loop will have started properly and your WMain object should be visible.

              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 Reply Quote 2
              • C
                casperbear last edited by

                SGaist, yes this approach is even better. It solved problem with dialog centering (alignment relative to parent) and initial dialog 'active' status. I wouldn't come up with '0' argument in a lifetime. I thought about very small numbers but not '0'. :) I guess '0' works because (if I recall) timer events are processed in event loop only when there are no other events (in win32 at least).

                void WMain::showEvent(QShowEvent *event)
                {
                    QMainWindow::showEvent(event);
                
                    QTimer::singleShot(0, [this]() {
                        WNew window(this);
                        window.exec();
                    });
                }
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post