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. Proper way to open a QDialog
QtWS25 Last Chance

Proper way to open a QDialog

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 2.9k 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.
  • C Offline
    C Offline
    casperbear
    wrote on last edited by
    #1

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

      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
      4
      • M Offline
        M Offline
        mpergand
        wrote on last edited by
        #3

        You can use show() :

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

          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
          1
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            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
            2
            • C Offline
              C Offline
              casperbear
              wrote on last edited by
              #6

              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
              0

              • Login

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