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. [Solved] QFileDialog::getOpenFileName breaks message boxes etc.
Forum Updated to NodeBB v4.3 + New Features

[Solved] QFileDialog::getOpenFileName breaks message boxes etc.

Scheduled Pinned Locked Moved General and Desktop
27 Posts 3 Posters 17.2k Views 1 Watching
  • 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.
  • L Offline
    L Offline
    loladiro
    wrote on last edited by
    #5

    @ // call doMain of the main QObject or QWidget
    myMain->doMain();
    @
    Why do you need the event loop to run?

    EDIT: Another result: It doesn't matter where the filedialog is!
    EDIT2: This is a workaround:
    @
    QFileDialog FileDialog = new QFileDialog(pParent,"Open some file", QString(), tr("All files (.)"));
    FileDialog->exec();
    delete FileDialog;
    @
    EDIT3: This workd, too BTW:
    @ QFileDialog d(pParent,"Open some file", QString(), tr("All files (
    .*)"));
    d.exec();
    @
    EDIT4: I guess that means the problem lies in the code that executes platform-specific dialog. Looking through the sources now...

    1 Reply Last reply
    0
    • L Offline
      L Offline
      LinusA
      wrote on last edited by
      #6

      [quote author="loladiro" date="1308761399"]
      Why do you need the event loop to run?
      [/quote]
      At least I think I need it to run. Basically to have dialogs I occasionally pop up working. I don't really remember right now, but in my huge project I've always been using this main() routine and CMain class as boiler-plate code. IIRC then in the beginning I only needed QErrorMessage to work, but now I sometimes have a QGLWidget which needs to react on key-presses.

      Maybe you're right, and I don't need the event-loop, I'm a bit confused. But after all, isn't that what you do with an QApplication? I always thought that without the app.exec(), you couldn't use dialogs/GUI elements at all...

      Anyway, thanks very much for the workarounds, I'll try and gladly use them!

      1 Reply Last reply
      0
      • G Offline
        G Offline
        giesbert
        wrote on last edited by
        #7

        You need the event loop for non nmodal windows / dialogs. Modal dialogs spin an own event loop.

        Nokia Certified Qt Specialist.
        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

        1 Reply Last reply
        0
        • L Offline
          L Offline
          loladiro
          wrote on last edited by
          #8

          Ok, the problem is definitely in the platform specific file dialog if you use:
          @
          QFileDialog::getOpenFileName(pParent, "Open some file", QString(), tr("All files (.)"), nullptr, QFileDialog::ReadOnly | QFileDialog::DontUseNativeDialog);
          @
          There's no problem either. The only thing that's weird about that is that it occurs on both Linux and Windows.

          EDIT: This is getting more and more confusing!!!! If the main windows is visible there's no problem!

          1 Reply Last reply
          0
          • G Offline
            G Offline
            giesbert
            wrote on last edited by
            #9

            The problem is, that you give a modal window a parent window, which was never shown. If you call mainWnd.show() before, everything works fine.

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply
            0
            • L Offline
              L Offline
              loladiro
              wrote on last edited by
              #10

              [deleted original post myself because of stupid question ;]
              It does work. SO yeah problem solved.

              1 Reply Last reply
              0
              • L Offline
                L Offline
                LinusA
                wrote on last edited by
                #11

                [quote author="loladiro" date="1308761399"]
                EDIT3: This workd, too BTW:
                @ QFileDialog d(pParent,"Open some file", QString(), tr("All files (.)"));
                d.exec();
                @
                [/quote]
                While this does in fact work, it shows a different looking file dialog -- it feels "non-native". I'd like to show the platform-specific default thing, in this case the default Windows version.

                [quote author="loladiro" date="1308761399"]
                EDIT4: I guess that means the problem lies in the code that executes platform-specific dialog. Looking through the sources now...
                [/quote]
                Yes, that's what I suspect now, too.

                Especially, if you change the workaround to this,
                @ QFileDialog d(pParent,"Open some file", QString(), tr("All files (.)"));
                //d.exec();
                d.getOpenFileName();
                @
                then it's broken again right away.

                I get the feeling getOpenFileName() breaks something, or indeed I do something unallowed with my event loop, which I don't understand...

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  LinusA
                  wrote on last edited by
                  #12

                  [quote author="Gerolf" date="1308764209"]The problem is, that you give a modal window a parent window, which was never shown. If you call mainWnd.show() before, everything works fine.[/quote]

                  Well no, I don't give a parent window. Ideally, I'd like to pass nothing (NULL). Just during debugging, I introduced pParent and tried setting it to "this", as well as "nullptr". It doesn't make a difference.

                  My favourite case would be just to use an QObject, which I can't pass as parent anyway. I only tried deriving QMainWidget from QWidget, so that I could try passing "this" as parent for a test.

                  If you could explain what exactly I should do without a main window, than I'll gladly try this.

                  [quote author="loladiro" date="1308764395"]
                  It does work. SO yeah problem solved.[/quote]
                  Could you elaborate? Did you find something new? In my eyes, the problem is still not solved I'm afraid :-(. I'd like to somehow use "getOpenFileName()" while my event loop is running, and I still don't get how to show message boxes afterwards.

                  So I could either refrain from starting my QApplication's event loop (which I don't want), or I could just not use getOpenFileName(). That can't be it, right? I hope there's just something wrong I'm doing with my "concept"...?

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    loladiro
                    wrote on last edited by
                    #13

                    You're right it is a little odd that it only happens with native file dialogs.
                    The problem (at least the trivial one is that) the following code in QEventLoop is executed (q->threadData->quitNow is set) after using native file dialogs. I 'm trying to find out why (just out of interest):
                    qeventloop.cpp:178,179
                    @
                    if (d->threadData->quitNow)
                    return -1;
                    @

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      giesbert
                      wrote on last edited by
                      #14

                      For what do you need an event loop in your example?
                      You want to open fife modal dialogs, one after each other, no event loop is needed for that.
                      You need an event loop for mode less dialogs, mode less windows or if you have a system of objects, that react on signal/slot in a not synchronous way (no queued connection, no threads)

                      Nokia Certified Qt Specialist.
                      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                      1 Reply Last reply
                      0
                      • L Offline
                        L Offline
                        loladiro
                        wrote on last edited by
                        #15

                        [quote]For what do you need an event loop in your example?
                        You want to open fife modal dialogs, one after each other, no event loop is needed for that.
                        You need an event loop for mode less dialogs, mode less windows or if you have a system of objects, that react on signal/slot in a not synchronous way (no queued connection, no threads)[/quote]
                        I agree with Gerolf, however, I'm still interested in why it's happening and will report here if I find anything. In the meantime, just use a workaround.

                        EDIT: I found out why the problem doesn't occur with a visible window. Consider the following code from QApplication:
                        @
                        void QApplicationPrivate::emitLastWindowClosed()
                        {
                        if (qApp && qApp->d_func()->in_exec) {
                        if (QApplicationPrivate::quitOnLastWindowClosed) {
                        // get ready to quit, this event might be removed if the
                        // event loop is re-entered, however
                        QApplication::postEvent(qApp, new QEvent(QEvent::Quit));
                        }
                        emit qApp->lastWindowClosed();
                        }
                        }@
                        EDIT2: This also doesn't happen if native dialog aren't used (The event loop gets reentered immidiately, but native widgets don't use the Qt event loop, so the application has enough time to process the quit event - it is actually done explicitly in the function that calls the native widgets - very interesting).

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          giesbert
                          wrote on last edited by
                          #16

                          Hi,

                          I tried with no message loop, and it worked as expected:

                          @
                          void mydoMain() {
                          // check that the message box is working as expected!
                          QMessageBox::information(0, "Test Msgbox", QObject::tr("Qt Version: %1").arg(QT_VERSION_STR));

                              QFileDialog::getOpenFileName(0, "Open some file", QString(), QObject::tr("All files (*.*)"), nullptr, QFileDialog::ReadOnly);
                          
                              QInputDialog::getText(0, "Enter a text", "Blablabla:");
                          
                              // you'll hear the message box sound, but don't see anything
                              QMessageBox::warning(0, "Test Msgbox 2", "Hi, I'm another msg box");
                          
                              // the error msg will show up, but it will stay "unusable" in the background
                              // also the program will execute the following file dialog at the same time without waiting
                              QErrorMessage ErrMsg;
                              ErrMsg.setModal(true);
                              ErrMsg.showMessage(QObject::tr("This is some sort of error message"));
                              ErrMsg.exec();
                          
                              // this pops up too early
                              QFileDialog::getOpenFileName(0, "Open another file", QString(), QObject::tr("All files (*.*)"), nullptr, QFileDialog::ReadOnly);
                          
                              cout << "doMain() done. Time to quit()." << endl;
                          

                          }//end method

                          int main(int argc, char *argv[]) {
                          QApplication app(argc, argv);

                              mydoMain();
                              return 0;
                          

                          }//end main
                          @

                          Nokia Certified Qt Specialist.
                          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            loladiro
                            wrote on last edited by
                            #17

                            Yes you didn't start the event loop. Use QTimer. And consider replacing the FileDialog with QApplication::processEvents();.
                            I would say this qualifies as a bug.

                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              LinusA
                              wrote on last edited by
                              #18

                              [quote author="Gerolf" date="1308939653"]For what do you need an event loop in your example?
                              [/quote]
                              The example is a minimal stripped down version of my real project, just to demonstrate this problem (and to avoid the dependencies of including Boost and OpenCV).

                              In my project (a framework actually), I want to later have the option to compose everything into a big GUI. Certain parts of the system might get their parameters programmatically for batch processing, but if they don't, they show these dialogs to ask the user "on the fly". So I definitely want to have the option to use my classes in a Qt project where a global event loop is running!

                              Right now I have a modeless QGLWidget which reacts on key-presses, which probably needs an event-loop anyway. And I sometimes have multiple OpenCV Windows of their HighGUI subsystem with Qt elements, which also needs an event loop I think.

                              [quote author="Gerolf" date="1308939653"]
                              You want to open fife modal dialogs, one after each other, no event loop is needed for that.
                              You need an event loop for mode less dialogs, mode less windows or if you have a system of objects, that react on signal/slot in a not synchronous way (no queued connection, no threads)
                              [/quote]
                              Just to make absolute sure there is no misunderstanding: I want the full capabilities of a Qt GUI application, including a global event loop to have the freedom of later adding a main window or any other GUI element.

                              The big question to me is: Did I break thinks by using modal input/file dialogs in a strange unusual way, or might this really be some Qt bug or quirk? It just doesn't make any sense to me why this example code doesn't work the way it should...

                              Thanks for the comments.

                              1 Reply Last reply
                              0
                              • L Offline
                                L Offline
                                LinusA
                                wrote on last edited by
                                #19

                                [quote author="loladiro" date="1308942428"]Yes you didn't start the event loop. Use QTimer. And consider replacing the FileDialog with QApplication::processEvents();.
                                I would say this qualifies as a bug.[/quote]
                                During my tests, I tried to put "qApp->processEvents();" and "qApp->sendPostedEvents();" between the dialogs -- no luck.

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  giesbert
                                  wrote on last edited by
                                  #20

                                  I have an idea what could happen:

                                  I was playing around a bit more now. Without event loop, everything is fine. With a visible main window, everything is fine. with event loop and without main window, it does not work.

                                  why? QApplication has a signal lastWindowClosed, which is emitted, if the last top level widget is closed:

                                  bq. By default,

                                  • this attribute is set for all widgets except transient windows such as splash screens, tool windows, and popup menus
                                  • QApplication implicitly quits when this signal is emitted.

                                  so, to work around it, use a property: "QApplication::quitOnLastWindowClosed":http://doc.qt.nokia.com/4.7/qapplication.html#quitOnLastWindowClosed-prop and set it to false, and voila, it works :-)

                                  @
                                  int main(int argc, char *argv[]) {
                                  QApplication app(argc, argv);

                                      CMainWidget w;
                                      // w.show();
                                  
                                      app.setQuitOnLastWindowClosed(false);
                                      QTimer::singleShot(0, &w, SLOT(doMain()));
                                  
                                      return app.exec();
                                  

                                  }//end main
                                  @

                                  This means, it's not a bug, it's a feature :-)

                                  Nokia Certified Qt Specialist.
                                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                  1 Reply Last reply
                                  0
                                  • L Offline
                                    L Offline
                                    loladiro
                                    wrote on last edited by
                                    #21

                                    Yes, I meant QApplication::processEvent() is the problem here. Sorry if I was unclear. I'll reupload your example in two files, so that other people can see the problem.

                                    So: Problem with comment why (Please use this code for tests):
                                    http://dl.dropbox.com/u/32965023/bugTest/bugTest.pro
                                    http://dl.dropbox.com/u/32965023/bugTest/main.cpp
                                    http://dl.dropbox.com/u/32965023/bugTest/test.h

                                    EDIT: @Gerolf, yes see my previous comment as to why it happens
                                    EDIT2: Well yes, it might be a feature, but the problem is that QWidget removes that event again, as soon as another one gets created (If there's no processEvents in between. I think the same code should be added to native widgets

                                    1 Reply Last reply
                                    0
                                    • G Offline
                                      G Offline
                                      giesbert
                                      wrote on last edited by
                                      #22

                                      Hi loladrio,

                                      this solves the issue:

                                      @
                                      app.setQuitOnLastWindowClosed(false);
                                      @

                                      No processEvents needed

                                      Nokia Certified Qt Specialist.
                                      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                      1 Reply Last reply
                                      0
                                      • L Offline
                                        L Offline
                                        loladiro
                                        wrote on last edited by
                                        #23

                                        Yes I know. My problem with the issue is more conceptual not practical. IMO, Qt should behave the same way independent of whether QFileDialog uses a native window or not. But in this point it doesn't.

                                        1 Reply Last reply
                                        0
                                        • L Offline
                                          L Offline
                                          LinusA
                                          wrote on last edited by
                                          #24

                                          [quote author="Gerolf" date="1308943261"]
                                          This means, it's not a bug, it's a feature :-)[/quote]
                                          Wow, thank you so much!!! Best one-line-fix ever ;-)

                                          However, there is one strange thought left: Why do several standard dialogs show different behaviours? How come that message and input boxes will silently "go away", a QErrorMessage will "hang", and QFileDialogs won't be impressed at all by this QApplication::quitOnLastWindowClosed property (try it out, file dialogs are still working in that state).

                                          And then the differences in behaviour depending on which constructor you use and whether it's a native look or not -- that's just odd.

                                          But anyway, thanks again, huge relief for me. Solved!

                                          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