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 make a modal dialog stay on top of an existing modal dialog?
QtWS25 Last Chance

How to make a modal dialog stay on top of an existing modal dialog?

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

    Hi,
    I need to create a modal dialog on top of another modal dialog. Following code shows how I am creating the dialogs.

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {    
        auto mainWidget = new QWidget(this);    
        auto button = new QPushButton("Click", mainWidget);
    
        QVBoxLayout* layout = new QVBoxLayout;
        layout->addWidget(button, Qt::AlignCenter);
        
        mainWidget->setLayout(layout);
        
        setCentralWidget(mainWidget);
    
        connect(button, SIGNAL(clicked()), this, SLOT(buttonClick()));
    }
    
    void MainWindow::buttonClick1() {
        m_dialog2 = new QDialog(m_dialog1);
        m_dialog2->exec();
    }
    
    void MainWindow::buttonClick()
    {
        m_dialog1 = new QDialog(this);
        auto layout = new QVBoxLayout;
    
        auto button = new QPushButton("Click", m_dialog1);
        connect(button, SIGNAL(clicked()), this, SLOT(buttonClick1()));
    
        layout->addWidget(button);
    
        m_dialog1->setLayout(layout);
        m_dialog1->exec();
    }
    

    The problem is that the second dialog (m_dialog2) is modal with respect to the main window, but loses focus and moves to the background if the first dialog is clicked (m_dialog1). Although the first dialog accepts focus, it doesn't accept any click events, which makes it feel like the app is frozen.
    How can I make the second dialog modal with respect to the first dialog as well?

    Thanks!

    EDIT: I am testing this on MacOS 10.14.6/Qt 5.12.4.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      schrute
      wrote on last edited by
      #7

      This turned out to be a bug in Qt 5.12.4 and was fixed on upgrading to 5.15.

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

        Hi,

        AFAIK, you did set the modality correctly however you are chaining blocking event loops when calling exec and IIRC, you can have issues with that. I would recommend moving to the use of QDialog::open which changes how you handle the dialog slightly but avoids nested event loops.

        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
        1
        • S Offline
          S Offline
          schrute
          wrote on last edited by
          #3

          @SGaist Unfortunately I am working on a legacy codebase, so I would like to avoid changing the QDialog::exec calls to QDialog::open (to avoid code restructuring at this point).

          Though I did change exec to open in the sample code that I shared. It does work but converts both the dialogs to sheets even though I am not specifying Qt::Sheet window flag. In fact, if I explicitly remove the Qt::Sheet window flag from the dialog (after calling open), it disappears/closes.

          I also tried changing the window modality to Qt::WindowModal while using exec, but it also presents the dialogs as sheets.

          JonBJ 1 Reply Last reply
          0
          • S schrute

            @SGaist Unfortunately I am working on a legacy codebase, so I would like to avoid changing the QDialog::exec calls to QDialog::open (to avoid code restructuring at this point).

            Though I did change exec to open in the sample code that I shared. It does work but converts both the dialogs to sheets even though I am not specifying Qt::Sheet window flag. In fact, if I explicitly remove the Qt::Sheet window flag from the dialog (after calling open), it disappears/closes.

            I also tried changing the window modality to Qt::WindowModal while using exec, but it also presents the dialogs as sheets.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #4

            @schrute

            The problem is that the second dialog (m_dialog2) is modal with respect to the main window, but loses focus and moves to the background if the first dialog is clicked (m_dialog1).

            Does it? It doesn't help that you didn't think it relevant to state what platform you are on. I am Qt 5.12.2 under Ubuntu 19.04, GNOME desktop. All works as expected. m_dialog1 is modal wrt MainWindow, m_dialog2 is modal wrt m_dialog1 (not sure what you meant by your "The problem is that the second dialog (m_dialog2) is modal with respect to the main window,", it isn't, unless you mean "indirectly" via grand-parentage), and in all cases the correct dialog remains up-front and no back-dalog can be clicked/focussed while it's there.....

            I believe, but admit I am not sure, that in the past I had an application which did this under Windows too, and the behaviour was the same as under Linux, with the modal hierarchy being perfectly respected.

            Furthermore, the default for QDialog::exec() is already Qt::WindowModal for a dialog with a parent [EDIT incorrect, as per @schrute reply below], so setting m_dialog[12]->setWindowModality(Qt::WindowModal) had no different effect, and I did not get any "but it also presents the dialogs as sheets". Nor did I find changing exec() to open() caused any "sheet-ness".

            S 1 Reply Last reply
            0
            • JonBJ JonB

              @schrute

              The problem is that the second dialog (m_dialog2) is modal with respect to the main window, but loses focus and moves to the background if the first dialog is clicked (m_dialog1).

              Does it? It doesn't help that you didn't think it relevant to state what platform you are on. I am Qt 5.12.2 under Ubuntu 19.04, GNOME desktop. All works as expected. m_dialog1 is modal wrt MainWindow, m_dialog2 is modal wrt m_dialog1 (not sure what you meant by your "The problem is that the second dialog (m_dialog2) is modal with respect to the main window,", it isn't, unless you mean "indirectly" via grand-parentage), and in all cases the correct dialog remains up-front and no back-dalog can be clicked/focussed while it's there.....

              I believe, but admit I am not sure, that in the past I had an application which did this under Windows too, and the behaviour was the same as under Linux, with the modal hierarchy being perfectly respected.

              Furthermore, the default for QDialog::exec() is already Qt::WindowModal for a dialog with a parent [EDIT incorrect, as per @schrute reply below], so setting m_dialog[12]->setWindowModality(Qt::WindowModal) had no different effect, and I did not get any "but it also presents the dialogs as sheets". Nor did I find changing exec() to open() caused any "sheet-ness".

              S Offline
              S Offline
              schrute
              wrote on last edited by schrute
              #5

              @JonB

              It doesn't help that you didn't think it relevant to state what platform you are on.

              I am testing this on MacOS 10.14.6 with Qt 5.12.4.

              Furthermore, the default for QDialog::exec() is already Qt::WindowModal for a dialog with a parent

              As per the documentation, by default the dialog is Qt::ApplicationModal.

              JonBJ 1 Reply Last reply
              1
              • S schrute

                @JonB

                It doesn't help that you didn't think it relevant to state what platform you are on.

                I am testing this on MacOS 10.14.6 with Qt 5.12.4.

                Furthermore, the default for QDialog::exec() is already Qt::WindowModal for a dialog with a parent

                As per the documentation, by default the dialog is Qt::ApplicationModal.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #6

                @schrute said in How to make a modal dialog stay on top of an existing modal dialog?:

                I am testing this on MacOS 10.14.6 with Qt 5.12.4.

                Maybe that is the difference in behaviour, I cannot say.

                As per the documentation, by default, the dialog is Qt::ApplicationModal.

                Damn, you are right! I could have sworn that the default was application modal when parent = nullptr but window modal when parent = something.... So for a QDialog the relevance of parent is just

                but if it has a parent, its default location is centered on top of the parent

                Right?

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  schrute
                  wrote on last edited by
                  #7

                  This turned out to be a bug in Qt 5.12.4 and was fixed on upgrading to 5.15.

                  1 Reply Last reply
                  1

                  • Login

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