1

I'm new to this but am wanting to write a Qt console app which uses Qt's features including signals and slots and therefore want an application event loop. Following this question How do I create a simple Qt console application in C++? I seem to be heading in the right direction but why does anything get executed after emitting finished in the following code:

// main.cpp
#include <QtCore>
#include <QDebug>

class Task : public QObject
{
    Q_OBJECT
public:
    Task(QObject *parent = 0) : QObject(parent) {}

public slots:
    void run()
    {
        // Do processing here
        qDebug() << "Hello World";
        emit finished();
        qDebug() << "I thought I'd finished!";
    }

signals:
    void finished();
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Task parented to the application so that it
    // will be deleted by the application.
    Task *task = new Task(&a);

    // This will cause the application to exit when
    // the task signals finished.
    QObject::connect(task, SIGNAL(finished()), &a, SLOT(quit()));

    // This will run the task from the application event loop.
    QTimer::singleShot(0, task, SLOT(run()));

    return a.exec();
}
Community
  • 1
  • 1
StuReeks
  • 316
  • 2
  • 8
  • 1
    > why does anything get executed after emitting finished in the following code: Can you be more precise? What exactly is the output? – Geier Apr 05 '14 at 07:27
  • 1
    It outputs 'Hello World' and 'I thought I'd finished'. I was expecting the Hello World but thought that the finished signal's connection to the application's quit slot would cause the application to terminate before 'I thought I'd finished'. – StuReeks Apr 05 '14 at 07:38

1 Answers1

3

Try to subclass the QCoreApplication and reimplement the quit() signal with inserting a debug print in.

You will see that the quit function is called immediately before your second print in the "run" slot, provided you are using DirectConnection.

Also, worth nothing that quit() is slightly different to the GNU C exit() as per documentation:

Note that unlike the C library function of the same name, this function does return to the caller -- it is event processing that stops.

This means quit() dos not mean that application quits right away without terminating gracefully in the middle of your method execution.

László Papp
  • 51,870
  • 39
  • 111
  • 135
  • OK, so the quit slot is being called and I've now read the documentation about the event processing stopping, but that comes from the slot Qeventloop::quit() and I thought I was using QCoreApplication::quit() which tells the application to exit with return code 0. The question becomes how to drop out of the 'run' slot and return control back to the application to get it to stop. – StuReeks Apr 05 '14 at 09:14
  • return from the run slot instead of printing? Furthermore, you are misreading something. It is QEventLoop::exit(), and not QEventLoop::quit() which gets called by QCoreApplication::quit(). – László Papp Apr 05 '14 at 09:17
  • If I've got this right then: to use Qt's features/event loop in a console app I need both a QCoreApplication and a 'worker' class with a 'run' slot. A timer is used to put a call to the 'run' slot onto the application's event loop. When the worker class is finished, it signals the application's quit slot which stops it's event loop and then returns program flow back to the worker object which then returns from the 'run' slot and everything stops. Is there no simpler way of doing this? – StuReeks Apr 05 '14 at 09:57
  • 2
    I am not sure what you mean. The thing is that quit() is not equal to exit() in GNU C. It will stop processing the events, but it does not interrupt the application all of a suddent hence the print statement. As for the fix of your application, we cannot really tell. There are too many scenarios out there with different approaches. It is your call. – László Papp Apr 05 '14 at 12:05