Writing a console application with QT

I like QT, its a nice tool kit. I typically write GUI applications with it, and qtcreator does a great job of setting it up. However, on the occasion I need to write a console application and the first time I did it, it wasn’t very obvious to me how.

In many examples I’ve googled, I see something like this:

class CSomeClass
{
public:
    CSomeClass() {}
    ~CSomeClass() {}
    void Run() { cerr << "Hello World!" << endl; }
};

int main( int argc, char ** argv )
{
    QCoreApplication cApp( argc, argv );
    CSomeClass cFoo;
    cFoo.Run();
    return( 0 );
}

This just isn’t right. Sure you are initiating a QCoreApplication, but this code never calls QCoreApplication::exec(), meaning it can’t process events. Lame!

In other examples, I’ve seen:

class CSomeClass
{
public:
    CSomeClass() {}
    ~CSomeClass() {}
    void Run() { cerr << "Hello World!" << endl; }
};

int main( int argc, char ** argv )
{
    QCoreApplication cApp( argc, argv );
    CSomeClass cFoo;
    cFoo.Run();
    return( cApp.exec() );
}

This is a nice attempt, but its still wrong. Events are now being processed, but its after the code has been run 🙂

The Correct Method …

// Derive from QObject so you can connect it to QCoreApplication
class CSomeClass : public QObject
{
Q_OBJECT
public:
    explicit CSomeClass(QObject *parent = 0) : QObject( parent ) {}
public slots:
    void Run() { cerr << "Hello World!" << endl; }
};

int main( int argc, char ** argv )
{
    QApplication cApp( argc, argv );
    CSomeClass cFoo;
    // connect the Run method of CSomeClass to our application
    QMetaObject::invokeMethod( &cFoo, "Run", Qt::QueuedConnection );
    return( cApp.exec() );
}

There it is. Calling invokeMethod with Qt::QueuedConnection tells cApp to call CSomeClass::Run soon as it enters the main event loop. Now you are able to process events in your main class.

This entry was posted in Software. Bookmark the permalink.