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. QDialog Non-modal Behaves as Modal for Parent Window
QtWS25 Last Chance

QDialog Non-modal Behaves as Modal for Parent Window

Scheduled Pinned Locked Moved General and Desktop
11 Posts 2 Posters 10.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.
  • J Offline
    J Offline
    jzuber
    wrote on 27 Nov 2014, 18:36 last edited by
    #1

    Hi,

    I recently changed over from Qt 4.7.something to Qt 5.3.2, and I am experiencing some difficulties due to changes in how Qt works.

    I have a QMainWindow which spawns some QDialogs. The QMainWindow is passed in as the parent widget to the QDialogs. Then, the QDialogs are made available to the user via dialog->setVisible(true); I can launch multiple QDialogs and they aren't modal to each other, however they all overlap the parent widget, ie: the QMainWindow.

    I have googled the issue and attempted to set flags to resolve this but currently nothing works. If I create the dialogs with no parent, then they no longer overlap the QMainWindow, but then they create their own entry in the taskbar.

    Is anyone else seeing this? Am I missing something easy?

    Thanks!

    1 Reply Last reply
    0
    • B Offline
      B Offline
      Binary91
      wrote on 27 Nov 2014, 19:37 last edited by
      #2

      Hi,

      passing a parent to QDialog (like your QMainWindow) does exactly what you want to avoid. QDialogs are used to "arrest" processing until user makes some input. By default, QDialogs are application modal, what means you even can't interact with other QDialogs, so you really have to close the QDialog before doing anything else. By passing a parent to the QDialog (in your case the QMainWindow), the QDialog becomes window modal mode, what means only interaction with your QMainWindow is stopped until QDialog is closed again..

      To avoid blocking other stuff, you call the QDialogs with show() command, so focus goes immediately back to QMainWindow after showing it. If you do that and QDialog still blocks your QMainWindow, you should check modality via QDialog::modal(), if that is true, you should set it to false (setModal(false))..
      If you want to avoid the taskbar button, just create the QDialog with a new QWidget as parent:
      @QDialog myIndependendDialog(new QWidget);@
      But note that you will have to free memory manually...

      EDIT:
      Documentation says QDialog::setVisible() does the same as QDialog::show(), so I'm really wondering why your QDialog is window modal... But it also says there is no need to use setVisible(), instead you should use show()... maybe you try it with show() and QMainWindow as parent and if it is still blocked... then I don't know what's going on..

      Hope that helps you ;-)

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jzuber
        wrote on 27 Nov 2014, 20:26 last edited by
        #3

        Thanks for your reply,

        I have looked at the Qt::WindowsFlags of each window, and have the following:

        MainWindow = 0x8800F001;
        Qt::WindowFullscreenButtonHint 0x80000000
        Qt::WindowCloseButtonHint 0x08000000
        Qt::WindowMaximizeButtonHint 0x00008000
        Qt::WindowMinimizeButtonHint 0x00004000
        Qt::WindowSystemMenuHint 0x00002000
        Qt::WindowTitleHint 0x00001000
        Qt::Window 0x00000001

        Dialogs = 0x08013003
        Qt::WindowCloseButtonHint 0x08000000
        Qt::WindowContextHelpButtonHint 0x00010000
        Qt::WindowSystemMenuHint 0x00002000
        Qt::WindowTitleHint 0x00001000
        Qt::Dialog 0x00000002
        Qt::Window 0x00000001

        And the dialog.isModal() returns false.

        I have tried replacing dialog->show() / dialog->hide() and they have the same effect as dialog->setVisible(true). I use setVisible because there is a function with a bool input to toggle the dialog visibility.

        This did work as expected in Qt 4.7... It would give me non-modal dialog windows which would not generate a new entry on the taskbar.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          Binary91
          wrote on 27 Nov 2014, 21:50 last edited by
          #4

          Can you show some code? There problem might be anywhere else, because this is not a normal behaviour of QDialogs when calling them via show()...

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jzuber
            wrote on 28 Nov 2014, 14:13 last edited by
            #5

            Here is an example, not my exact code but essentially the same. The function "showDialog" is called from intermediate functions which are connected to button "toggled(bool)" signals, 1:1. In my version the "showDialog" does more than just show the dialogs so it was implemented in a common function.
            @
            // Main Window Header:

            MyMainWindow : public QMainWindow
            {
            Q_OBJECT
            public:
            // constructors, functions I need, etc..
            ....

            private:
            void showDialog(QWidget * window, bool show);
            std::vector<std::shared_ptr<MyDialog>> m_myDialogs;
            }

            // Main Window Cpp
            namespace
            {
            const int numberOfDialogs = 10;
            };

            MyMainWindow::MyMainWindow(...)
            {
            for (int i = 0; i < numberOfDialogs; ++i)
            {
            std::shared_ptr<MyDialog> tempDialog;
            tempDialog.reset(new MyDialog(this));
            m_myDialogs.push_back(tempDialog);
            }
            }

            void MyMainWindow::showDialog(QWidget * dialog, bool show)
            {
            dialog->setVisible(show);

            // I have also tried:
            // if (show)
            // {
            // dialog->show();
            // }
            // else
            // {
            // dialog->hide();
            // }
            }
            @

            1 Reply Last reply
            0
            • B Offline
              B Offline
              Binary91
              wrote on 28 Nov 2014, 14:33 last edited by
              #6

              Is there any reason why you use QWidget ptr in your parameter list of MyMainWindow::showDialog(..) ?
              Have you tried to use QDialog ptr instead? Or if not (for reasons like you also have to pass QWidgets to this function), maybe downcast before handling the dialog as a QDialog?
              Try the following first:
              @ // Main Window Header:

              MyMainWindow : public QMainWindow
              {
              Q_OBJECT
              public:
                 // constructors, functions I need, etc..
                 ....
               
              private:
                 void showDialog(QDialog*, bool show);
                 std::vector<std::shared_ptr<MyDialog>> m_myDialogs;
              }
               
               
              //  Main Window Cpp
              namespace
              {
                 const int numberOfDialogs = 10;
              };
               
              MyMainWindow::MyMainWindow(...)
              {
                 for (int i = 0; i < numberOfDialogs; ++i)
                 {
                    std::shared_ptr<MyDialog> tempDialog;
                    tempDialog.reset(new MyDialog(this));
                    m_myDialogs.push_back(tempDialog);
                 }
              }
               
              void MyMainWindow::showDialog(QDialog* dialog, bool show)
              {
                 dialog->setVisible(show);
               
                 // I have also tried:
                 // if (show)
                 // {
                 //     dialog->show();
                 // }
                 // else
                 // {
                 //     dialog->hide();
                 // }
              }@
              

              If that still doesn't work, maybe you can show how you call the function?

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jzuber
                wrote on 28 Nov 2014, 15:30 last edited by
                #7

                Yeah I have other window types I pass in as well, of type QMainWindow. These other MainWindows don't seem to have the problem (ie: they don't hide the parent). Maybe I will change all my dialogs to MainWindows.

                It just seems like this is not the expected behaviour for a Dialog, given the way I am using it, though maybe I am wrong.

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  Binary91
                  wrote on 28 Nov 2014, 15:42 last edited by
                  #8

                  The problem must be anywhere else in the code. Normally, a QDialog shouldn't behave like that. You do downcasting to QDialog in your function body, right?
                  It won't be the best solution to give up and go away from QDialogs, but If you want to do so, you don't have to use QMainWindows, you can simply use QWidgets as windows...

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jzuber
                    wrote on 28 Nov 2014, 16:24 last edited by
                    #9

                    I have tried to use straight up "QDialog *" instead of "QWidget *", and it made no difference. I know you are saying that the problem is in my code, but have you tried to do the same thing I have done and had different results?? I would be glad if I was simply making a mistake with how I was using dialogs, because it means I can fix the way I am using them, without replacing them with something else.

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      Binary91
                      wrote on 29 Nov 2014, 11:28 last edited by
                      #10

                      The problem is, I can't really test your code in the way you do it, because obviously you are using a subclass of QDialog with new functionallity which I can't see, also I don't know where in your code you ever call the function showDialog.

                      Tipp:
                      Try always to use Qt's class system when working with Qt stuff, it avoids problems and in most cases, it is faster and more powerful.
                      Take a look at "QSharedPointer":http://qt-project.org/doc/qt-5/qsharedpointer.html or "QVector":http://qt-project.org/doc/qt-5/qvector.html, there is no need to use the std stuff I think..

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        jzuber
                        wrote on 1 Dec 2014, 14:00 last edited by
                        #11

                        I changed my windows to inherit from QWidget instead of QDialog. This has seemed to fix the issues I was seeing. Maybe that is the intended behaviour of QDialog?

                        I am using a subclass of QDialog. All it is doing was connecting signals from controls (two QPushButton(s), and a QTableView) to some private slots. I was not overriding any specialized control of QDialog anywhere. The showDialog() function was being called by X different slots, each of which was connected to a different QPushButton::toggled() signal. The main window was used as a "launcher" of these other windows. So picture 10 buttons, each with their own slot, which when the button is clicked, it calls "showDialog" with a very specific *Widget passed in, and the "show" set true if toggled on, and false if toggled off.

                        Anyway, mixing std:: and Qt:: should not have any issues. A shared_ptr or a vector are not going to change the behaviour of a QDialog.

                        Thank you everyone for your suggestions, this can be considered closed.

                        1 Reply Last reply
                        0

                        3/11

                        27 Nov 2014, 20:26

                        topic:navigator.unread, 8
                        • Login

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