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. Modal from a modal (Mac)

Modal from a modal (Mac)

Scheduled Pinned Locked Moved Unsolved General and Desktop
macdialogmodal dialogdesktop
5 Posts 3 Posters 4.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.
  • K Offline
    K Offline
    KevinD
    wrote on last edited by
    #1

    [This is a cross-post from StackOverflow].

    I have a Qt modal dialog (a complex form) that needs to itself pop up a modal dialog (a QMessageBox with setModal(true)). This modal should be on top of the parent modal form, and prevent interaction.

    This all works swimmingly up to a point - the second modal appears, and prevents interaction with the widgets in the parent. However, the parent form can still receive focus - that is, I can click in it, and the window receives focus (even if I can't interact with the widgets). This becomes a problem if you task away to another application at this point - when you task back the QMessageBox is behind the parent which has focus (and you can't interact with the parent). Basically, you have to move the parent to reveal the QMessageBox before dismissing it.

    Is there a way to have a modal on top of a modal on prevent this problem on Mac OS with window focus and tasking away? (Not tested other OS BTW).

    Example code to reproduce the problem (pushButton is just a standard pushbutton):

    Dialog.cpp

    #include "dialog.h"
    #include "ui_dialog.h"
    
    #include <QMessageBox>
    
    Dialog::Dialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    
        QObject::connect(ui->pushButton, &QPushButton::clicked, this, &Dialog::showMeAModal);
    }
    
    Dialog::~Dialog()
    {
        delete ui;
    }
    void Dialog::showMeAModal()
    {
        QMessageBox box(this);
        box.setText(tr("modal"));
        box.setModal(true);
        box.setWindowFlags(box.windowFlags() | Qt::Popup);
        box.exec();
    }
    

    Dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include <QDialog>
    
    namespace Ui {
    class Dialog;
    }
    
    class Dialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit Dialog(QWidget *parent = 0);
        ~Dialog();
    public slots:
        void showMeAModal();
    
    private:
        Ui::Dialog *ui;
    };
    
    #endif // DIALOG_H
    

    MainWindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    #include "dialog.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        Dialog dialog(&w);
        dialog.setModal(true);
        dialog.show();
    
        return a.exec();
    }
    

    I've tried:

    • Qt::Popup on the Message Box
    • Changing parent to MainWindow
    • Qt::WindowStaysOnTopHint on the Message Box

    ...to no avail.

    kshegunovK 1 Reply Last reply
    0
    • R Offline
      R Offline
      Rondog
      wrote on last edited by Rondog
      #2

      I tried your sample code and saw the problem you described only with a specific sequence of events. Your sample code is incomplete but enough was there where I could fill in the rest so I don't think this is critical.

      I am currently running OSX 10.10.5, XCode 7.2.1, Qt 5.6.0.

      The sequence of events that creates this problem is as follows:

      • Click on the button to create the message box.

      • Click focus on the dialog below the message box so this has focus. The mainwindow cannot get focus in this program.

      • Click focus to some other program (i.e. a finder window).

      • Click back to the program (anything other than the messagebox). The messagebox is now behind the dialog (wrong Z order).

      My first thought to solving this would be related to keeping focus on the messagebox when it is visible or maybe tap into the QFocus events and use some combination of raise() or lower() to make sure the messagebox is always on top (these functions change the Z order). I didn't try any of this but it is just an idea.

      1 Reply Last reply
      1
      • R Offline
        R Offline
        Rondog
        wrote on last edited by
        #3

        I think I found a solution to this problem. Try this:

        void Dialog::showMeAModal()
        {
            QMessageBox box(this);
            box.setText(tr("modal"));
            box.setModal(true);
            box.setWindowFlags(box.windowFlags() | Qt::Popup);
            box.setWindowModality(Qt::WindowModal);
            box.exec();
        }
        

        It looks a little different that a regular message box (quite cool actually) and your problem no longer exists.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          KevinD
          wrote on last edited by
          #4

          Thanks, this is similar to the solution we came up with. The crucial line is

          box.setWindowModality(Qt::WindowModal);
          

          This causes the QMessageBox to be shown as a Mac window drop-down. setModal and setWindowFlags seem to have no additional affect.

          That said, this is a workaround with user interface impact - there does appear to be a bug in Qt that is causing this situation.

          1 Reply Last reply
          2
          • K KevinD

            [This is a cross-post from StackOverflow].

            I have a Qt modal dialog (a complex form) that needs to itself pop up a modal dialog (a QMessageBox with setModal(true)). This modal should be on top of the parent modal form, and prevent interaction.

            This all works swimmingly up to a point - the second modal appears, and prevents interaction with the widgets in the parent. However, the parent form can still receive focus - that is, I can click in it, and the window receives focus (even if I can't interact with the widgets). This becomes a problem if you task away to another application at this point - when you task back the QMessageBox is behind the parent which has focus (and you can't interact with the parent). Basically, you have to move the parent to reveal the QMessageBox before dismissing it.

            Is there a way to have a modal on top of a modal on prevent this problem on Mac OS with window focus and tasking away? (Not tested other OS BTW).

            Example code to reproduce the problem (pushButton is just a standard pushbutton):

            Dialog.cpp

            #include "dialog.h"
            #include "ui_dialog.h"
            
            #include <QMessageBox>
            
            Dialog::Dialog(QWidget *parent) :
                QDialog(parent),
                ui(new Ui::Dialog)
            {
                ui->setupUi(this);
            
                QObject::connect(ui->pushButton, &QPushButton::clicked, this, &Dialog::showMeAModal);
            }
            
            Dialog::~Dialog()
            {
                delete ui;
            }
            void Dialog::showMeAModal()
            {
                QMessageBox box(this);
                box.setText(tr("modal"));
                box.setModal(true);
                box.setWindowFlags(box.windowFlags() | Qt::Popup);
                box.exec();
            }
            

            Dialog.h

            #ifndef DIALOG_H
            #define DIALOG_H
            
            #include <QDialog>
            
            namespace Ui {
            class Dialog;
            }
            
            class Dialog : public QDialog
            {
                Q_OBJECT
            
            public:
                explicit Dialog(QWidget *parent = 0);
                ~Dialog();
            public slots:
                void showMeAModal();
            
            private:
                Ui::Dialog *ui;
            };
            
            #endif // DIALOG_H
            

            MainWindow.cpp

            #include "mainwindow.h"
            #include "ui_mainwindow.h"
            
            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            
            }
            
            MainWindow::~MainWindow()
            {
                delete ui;
            }
            

            main.cpp

            #include "mainwindow.h"
            #include <QApplication>
            
            #include "dialog.h"
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                MainWindow w;
                w.show();
            
                Dialog dialog(&w);
                dialog.setModal(true);
                dialog.show();
            
                return a.exec();
            }
            

            I've tried:

            • Qt::Popup on the Message Box
            • Changing parent to MainWindow
            • Qt::WindowStaysOnTopHint on the Message Box

            ...to no avail.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @KevinD said in Modal from a modal (Mac):
            Hi,
            Don't use these two:

            box.setModal(true);
            box.setWindowFlags(box.windowFlags() | Qt::Popup);
            

            You're calling QDialog::exec which is for modal-only dialogs, and Qt::Popup isn't for dialogs, leave the window flags be. If you prepare a MWE (the download-and-build type) I can test on Linux (I have no Mac, sorry). Also you might consider filing a bug report if everything else fails.

            Kind regards.

            Read and abide by the Qt Code of Conduct

            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