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] QApplication not finishing after MainWindow closed
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QApplication not finishing after MainWindow closed

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 9.1k 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.
  • D Offline
    D Offline
    Danielc
    wrote on last edited by
    #1

    Hi everybody!

    I just had a problem that I managed to solve, but I still don't understand why it was not working.
    I need to perform some checks in my class constructor, and if one fails, the application should finish. First I tried to call close() in the constructor, but it not worked because the event loop had not started (as far I understand), and anyway I call show() after in main.cpp. Then I tried to perform the tests before calling show() but, although the MainWindow is never shown, the application does not end. I also tried to call show() first and then call the test function (from main.cpp), but my application never ends (although the window is closed).

    I attach some parts of the code:

    @void ArmyEditor::initialize() {
    // This function makes sure an Army File is opened/created before we can work with the MainWindow

    StartDialog dialog(this); // Just a class that inherits from QDialog
    QFileDialog fileDialog(this, tr("Select Game File"), QString(), tr("yALB Game File (*.ygf)"));
    fileDialog.setFileMode(QFileDialog::ExistingFile);
    bool getAction = true;
    
    
    while(getAction) {
        if(dialog.exec() == StartDialog::Accepted) {
            if(dialog.getResult() == StartDialog::CreateFile) {
                if(fileDialog.exec() == QFileDialog::Accepted) {
                    QString gameFile = fileDialog.selectedFiles().at(0);
                    if(gameFile.isEmpty() == false && newArmyFile(gameFile)) {
                        getAction = false;
                        break;
                    }
                }
            } else {
                if(fileDialog.exec() == QFileDialog::Accepted) {
                    QString gameFile = fileDialog.selectedFiles().at(0);
                    fileDialog.setFilter(tr("yALB Army File (*.yaf)"));
                    if(gameFile.isEmpty() == false && fileDialog.exec() == QFileDialog::Accepted) {
                        QString armyFile = fileDialog.selectedFiles().at(0);
                        if(armyFile.isEmpty() == false && openArmyFile(armyFile, gameFile)) {
                            getAction = false;
                        } else
                            fileDialog.setFilter(tr("yALB Game File (*.ygf)"));
                    }
                }
            }
        } else {
            // User clicked exited from Start Dialog, finish app
            this->close();
            return;
        }
    }
    

    }@

    @#include <QtGui/QApplication>
    #include "armyeditor.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    ArmyEditor w;
    w.show();
    w.initialize();

    return a.exec&#40;&#41;;
    

    }
    @

    I managed to solve it by declaring initialize() as a slot and adding this line at the end of ArmyEditor's constructor:
    @QTimer::singleShot(0, this, SLOT(initialize()));@

    I understand the previous line calls the slot when the event loop starts, but the same should happen in the first case, shouldn't it?

    Thanks and greetings!

    1 Reply Last reply
    0
    • V Offline
      V Offline
      veeeee_d
      wrote on last edited by
      #2

      I believe it is wrong to do anything but loading the widgets you'll use before you call exec(), since the events won't be processed and something might lock your widget "opened" (which may be the reason your program is not closing).

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #3

        Instead of calling "this->close()" in your class, do it like that:
        @
        qApp->quit();
        @

        This will tell the global application object to finish.

        You could also move "w.initialize();" before "w.show();".

        (Z(:^

        1 Reply Last reply
        0
        • D Offline
          D Offline
          Danielc
          wrote on last edited by
          #4

          Thanks for the replies..

          @veeeee_d: But if I call exec() then the next line (w.initialize()) won't be called until the MainWindow is closed.

          @sierdzio: I had already tried with qApp->quit(), but it does not even close the MainWindow. I tried writing w.initialize() before w.show() also.

          Thanks again!

          1 Reply Last reply
          0
          • K Offline
            K Offline
            koahnig
            wrote on last edited by
            #5

            I am wondering why you are not having a return value for your initialisation method?
            If you want to use it as a slot, this is certainly a reason, but so far, it looks like to want to call it only once and even prior to exec(). If the routine would return a bool, you can mark with a false, that something is definitely wrong. This allows you to exit immediately the main part prior to calling show() and exec().

            Vote the answer(s) that helped you to solve your issue(s)

            1 Reply Last reply
            0
            • D Offline
              D Offline
              Danielc
              wrote on last edited by
              #6

              Thanks for your answer.

              Yes, I was using like that before.. I had something like this:

              @#include <QtGui/QApplication>
              #include "armyeditor.h"

              int main(int argc, char *argv[])
              {
              QApplication a(argc, argv);
              ArmyEditor w;
              if(w.initialize())
              w.show();

              return a.exec&#40;&#41;;
              

              }@

              Should I call a.exec() only when w.initialize() is true?

              Thanks!

              1 Reply Last reply
              0
              • K Offline
                K Offline
                koahnig
                wrote on last edited by
                #7

                I would do like this:

                @#include <QtGui/QApplication>
                #include "armyeditor.h"

                int main(int argc, char *argv[])
                {
                QApplication a(argc, argv);
                ArmyEditor w;
                if(!w.initialize())
                return 10; // choose a return value you like

                w.show();
                
                return a.exec(&#41;;
                

                }@

                This assumes certainly that it does not make sense to continue the execution with such a failure in initialization. I do not see a reason to start the exec loop for nothing.

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  Danielc
                  wrote on last edited by
                  #8

                  Yes, it works.. Anyway, I still don't understand why it was not working.. Shouldn't the exec loop finish automatically if there are no windows opened? Maybe the app never recieves the "message" to close, but doesn't the fact that close() effectively closes the MainWindow means that the event loop has started?

                  Thanks!

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #9

                    exec method is not part of "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html but of "QCoreApplication":http://doc.qt.nokia.com/4.7/qcoreapplication.html The latter one is for console applications without windows. So, it cannot rely on windows to be open and closed.

                    [Edit] I have just noticed that exec() may be different for QApplication and QCoreApplication since it is listed in the documentation for both. Since it is a static method it is listed in a different section.

                    Vote the answer(s) that helped you to solve your issue(s)

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      Danielc
                      wrote on last edited by
                      #10

                      Thanks! I will mark this as solved.

                      For this application I will use QTimer::singleShot(0, this, SLOT(initialize())); because I want the MainWindow is visible before I show StartDialog, but I will take your suggestion for another application of my package that need to perform this tests before anything is shown.

                      Thanks again!

                      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