PDA

View Full Version : Posting custom events to a subclass of QThread



jpn
4th July 2006, 12:42
Is it not possible to post custom events (across thread) to a QThread descendant? Or am I doing something wrong? Should I create a child for the thread and post events to the child object to get events delivered to the correct thread?

The code below illustrates the problem:


#include <QtGui>
#include <QtDebug>

class MyThread : public QThread
{
public:
MyThread(QObject* parent = 0) : QThread(parent)
{
}

protected:
void run()
{
qDebug() << "MyThread::run()" << QThread::currentThread() << this->thread();
exec();
}

void customEvent(QEvent* event)
{
qDebug() << "MyThread::customEvent()" << QThread::currentThread() << this->thread();
// a long loop here will naturally block GUI
qDebug() << "LOOP BEGIN";
for (uint i = 0; i < -1; ++i);
qDebug() << "LOOP END";
}
};

class EventButton : public QPushButton
{
Q_OBJECT

public:
EventButton() : QPushButton("Post an event")
{
mythread = new MyThread(this); // creating without parent has no effect
mythread->start();
connect(this, SIGNAL(clicked()), this, SLOT(postEvent()));
}

private slots:
void postEvent()
{
qDebug() << "EventButton::postEvent()" << QThread::currentThread() << this->thread();
QApplication::postEvent(mythread, new QEvent(QEvent::User));
}

private:
MyThread* mythread;
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug() << "main()" << QThread::currentThread();
EventButton b;
b.show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
return a.exec();
}

#include "main.moc"


Please, spot a mistake there.. ;)

high_flyer
4th July 2006, 14:21
Is it not possible to post custom events (across thread) to a QThread descendant?
Sure it is.
Do you get the debug message in your postEvent() slot?

jpn
4th July 2006, 14:55
Sure it is.
Do you get the debug message in your postEvent() slot?
I don't mean that the event wouldn't get delivered at all. Sure it does. But it will get sent directly and processed in the main thread, meaning the it will steal main thread's execution time and so the GUI will get blocked. The point with the debug message in MyThread::customEvent() is that it will show you the current executing thread, which is the main thread.

I somewhy would have expected that posting a custom event to a QThread object would have got processed in it's own event loop. But it will get processed in it's owner's event loop instead (the main GUI thread in this case).

high_flyer
4th July 2006, 15:49
I somewhy would have expected that posting a custom event to a QThread object would have got processed in it's own event loop.
I am not sure 100%, but I think this was the case in Qt3.
At least thats is the way I worked with threads in Qt3 and it did work for me.
But you are working now with Qt4.
And here the docs say:

A QObject instance is said to live in the thread in which it is created. Events to that object are dispatched by that thread's event loop.
And since your button was created in the main loop, and the QThread in it is its child, the events get posted in the main event loop.