Se pierde la señal anterior al inicio del bucle del evento QThread

I have a case where a signal is being lost and I don't understand why -- normally signals sent prior to the event loop starting just get queued up and sent then.

This is what the code looks like (for a QThread object):

void OffloadHandler::run()
{
    cout << "Start" << endl;
    connect( this, SIGNAL(loopStarted()), SLOT(onLoopStarted()), Qt::QueuedConnection );
    emit loopStarted();
    exec();
}

void OffloadHandler::onLoopStarted()
{
    cout << "Here!" << endl;
}

The thread is started elsewhere and Start is written to the console but Here1 never is -- the signal is not received. I use the same pattern in my main message loop and it works, but in this threaded message loop it appears not to work.

Is there anything clearly wrong in my code here?

preguntado el 09 de marzo de 12 a las 17:03

Where is this "loopStarted" emitted? -

2 Respuestas

Your code is valid and it should run. Are you sure you have an event loop running in the thread that oh is created in?

Porque el emit loopStarted() should send an event to oh's event loop, which will be processed and will call onLoopStarted(). I've tested your code out, and it works for me.


Btw, It's generally recommended that you do not add slots to your QThread, and avoid using moveToThread( this );

Unfortunately, I don't really understand your use case, so I can't give a better solution. But aquí is some amazing documentation which has nice DOs and DONTs regarding QThreads.

respondido 09 mar '12, 20:03

+0.5 :) That's an interesting article but I wish it didn't give examples of suclassing QThread. I believe the suggestions there that center on putting work in a QObject subclass and moving that to a QThread instance is a better choice. - arnold spence

Okay, I've figured it out, I've been bitten by the QThread ownership oddity. One has to be really careful when connecting to the QThread object itself since that Object is not owned by the thread by default.

So at the point where the thread is created I must move the thread to the thread:

OffloadHandler * oh = new OffloadHandler();
oh->moveToThread( oh ); //MOVE TO SELF!
oh->start();

Once I do this the signals work as expected.

respondido 09 mar '12, 18:03

Although the Qt documentation recommends subclassing QThread, it is generally considered contrary to the intended use. Moving a thread to itself is definitely a common anti-pattern that continues to propagate :) It may solve your immediate problem but the problems it produces are more insidious. Do a search on SO for Qt and threads and you should find many mentions of this article: labs.qt.nokia.com/2010/06/17/lo-estás-haciendo-mal - arnold spence

While perhaps a nice idea not to subclass I don't see ho you'd be able to start the message loop in the thread then. exec is a protected member function -- and it seems rather silly to create a new QEventLoop for this purpose. - edA-qa mort-ora-y

I also don't buy the bit about not moving a thread to itself. The thread has no owner thread, what is so special about the thread which happened to create it -- it's now it's own independent entity. - edA-qa mort-ora-y

exec() is called automatically from run, you don't have to subclass for this to happen. - arnold spence

Well, then I guess there's no way to create a thread without a message loop without subclassing. - edA-qa mort-ora-y

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.