But just to get myself wet with Qt, here I create a Qt console application for displaying "Hello World".
Steps to Create The App
From Qt Creator, create a Qt Console application.
Right click the project, create a new class. Name the class HelloWorld and inherit from QObject.
Add sayHello() and done() methods so helloworld.h now looks like this:
helloworld.h :
#ifndef HELLOWORLD_H #define HELLOWORLD_H #include <QObject> class HelloWorld : public QObject { Q_OBJECT public: explicit HelloWorld(QObject *parent = 0); signals: void done(); public slots: void sayHello(); }; #endif // HELLOWORLD_H
Implement the sayHello() method:
helloworld.cpp :
#include "helloworld.h" #include <stdio.h> HelloWorld::HelloWorld(QObject *parent) : QObject(parent) { } void HelloWorld::sayHello() { printf("Hello World!\n"); done(); }
In main.cpp, add some plumbing to use the HelloWorld class.
main.cpp :
#include <QObject> #include <QtCore/QCoreApplication> #include <QTimer> #include <helloworld.h> #include <stdio.h> int main(int argc, char *argv[]) { fprintf(stderr, "Starting up...\n"); QCoreApplication a(argc, argv); HelloWorld helloWorld; QObject::connect(&helloWorld, SIGNAL( done() ), &a, SLOT( quit() ), Qt::QueuedConnection); QTimer::singleShot(0, &helloWorld, SLOT( sayHello() )); return a.exec(); }
Running the App
To run the app, click the Run button or press Ctrl+R.
Qt Creator should build the application, and show the output in the Application Output panel.
Starting /home/ceefour/Sandbox/helloworld-console/helloworld-console... Starting up... Hello World! /home/ceefour/Sandbox/helloworld-console/helloworld-console exited with code 0
Application Logic
The main entry point deserves some explanation.
- It creates a Qt Core application (QCoreApplication) in variable a.
- Connects helloWorld's done() signal to the app's quit() slot/method, with a connection type of Qt::QueuedConnection.
- Creates a single shot timer (QTimer) with 0 ms delay that triggers helloWorld's sayHello() slot/method.
a.exec() will run Qt's event loop, which will process incoming events:
- The timer event will be processed, therefore executing helloWorld.sayHello().
- sayHello() does its job (printing "Hello World!"), then it will call its done() signal.
- helloWorld.done() signal was connected to a.quit(), therefore telling Qt application to stop the event loop and quit the application.
A default connection calls the slot directly. However, I use Qt::QueuedConnection here so that the call is queued until the slot processes the message.
In this case it's actually not needed.
It's possible to:
- Run helloWorld.sayHello() directly (without using QTimer), and it can still exit the application because the event is queued.
- Leave out the Qt::QueuedConnection, and it can still exit the application because the direct a.quit() call happens after the event loop is started.
The app will not quit immediately, because the event loop will not have started when a.quit() is called, therefore having no effect. Which is incorrect logic.
Why Separate Header (.h) and Implementation (.cpp) Files?
In this example I separated helloworld.h from helloworld.cpp. You may be wondering if it's possible to merge them into just one helloworld.cpp implementation file.
The answer is No. At least not if you use Q_OBJECT or other Qt macros. Snippet from C++ GUI Programming with Qt 4:
For moc to work correctly, we must put the class definition in a header file, separate from the implementation file. The code generated by moc includes this header file and adds some C++ boilerplate code of its own.So, don't fight it. Besides, that's the convention in C++ world anyway.
Reference: qt-interest thread: QCoreApplication won't quit
No comments:
Post a Comment
Be the first to comment!