I am not calling exec() yet my timer and QUdpSocket work just fine. Is exec used to wait for an event to continue?
views:
1090answers:
3Your timer and socket are probably using the main event loop that is started when you call QCoreApplication::exec()
. Although I'm sure there's a good reason to run an event loop within a thread, I can't come up with one.
The QThread documentation states:
Each QThread can have its own event loop. You can start the event loop by calling exec(); you can stop it by calling exit() or quit(). Having an event loop in a thread makes it possible to connect signals from other threads to slots in this thread, using a mechanism called queued connections. It also makes it possible to use classes that require the event loop, such as QTimer and QTcpSocket, in the thread. Note, however, that it is not possible to use any widget classes in the thread.
Without an event loop, it's possible to emit signals which are processed by the GUI thread, or a different thread containing an event loop. This implies that a thread must have an event loop in order for its slots to be effectual. Per the documentation above, some classes, like QTimer, require a running event loop for which you must call QThread::exec()
. Other classes, like QTCPSocket have capabilities to run with with or without an event loop, depending on the functions used. The documentation for the classes should indicate what, if any, requirements they have.
In order to actually use your thread, instead of the QApplication execution loop, you have to call moveToThread(this)
within the thread constructor AND place an execution loop within the protected run()
method of your QThread derived class.
Seperate threads execution loop prevents the QApplication loop getting cluttered with non-ui related signals and slots, and therefore delaying for .e.g button click's slot execution, making your application "lag".
Note: Normally you always subclass QThread, see Qt doc for more information
It depend on your programs. Here is an example:
void MyThread::run(){
Curl * curl = new Curl();
connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
connect( curl, SIGNAL(OnDone()), curl, SLOTS(deleteLater()) );
curl->Download("http://google.com");
exec(); // this is an event loop in this thread, it will wait until you command quit()
}
void MyThread::OnTransfer(QString data){
qDebug() << data;
}
Without exec(), OnTransfer will never be called. BUT if your create curl outside run with this (assume MyThread parent is main thread) as parent :
MyThread::MyThread(){
curl = new Curl(this);
connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
start();
}
void MyThread::run(){
curl->Download("http://google.com");
}
This one will work as you expected. OnTransfer will be called.