0
votes

I have a heavy calculation under a QObject derived class. I move it to my new qthread through a button in the GUI and it is created just for the purpose of executing that calculation.

The GUI is supposed to be waiting for messages from the worker thread in a loop (because after executing the button slot, it just goes there).

I emit the messages through a signal and slot mechanism as follows. I have a generic class Controller that executes the creation of the thread and connects it with the GUI (MainWindow):

QThread* thread = new QThread;
Raytracer* worker = new Raytracer();
worker->moveToThread(thread);

QObject::connect(thread, &QThread::started, worker, &Raytracer::execute);//, Qt::QueuedConnection);
QObject::connect(worker, &Raytracer::textEmitted, gui_, &MainWindow::addText, Qt::QueuedConnection);
QObject::connect(worker, &Raytracer::hitEmitted, gui_, &MainWindow::hitReceived, Qt::QueuedConnection);
QObject::connect(worker, &Raytracer::finished, worker, &Raytracer::deleteLater, Qt::QueuedConnection);
QObject::connect(worker, &Raytracer::finished, thread, &QThread::quit, Qt::QueuedConnection);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater, Qt::QueuedConnection);
QObject::connect(thread, &QThread::finished, this, &MainController::finishedCalculation, Qt::QueuedConnection);


thread->start();

About the class Raytracer:

class Raytracer : public QObject
{
Q_OBJECT

During the calculations it emits things like this:

emit textEmitted(QString("Number %1\n").arg(number));

And the GUI receives the signal here:

void addText(const QString& text) { outputBox_->append( text ); }

The signals are received and properly added to a text box in the GUI. But they appear just after the thread finished. Not during the calculation, no matter how long it is.

And all messages were received. So it is kind of keeping them in some buffer and updates the text at the end.

What am i doing wrong and in which situations this could happen? How could it test it?

1
I am a little confused as to why you are using queued connection explicitly. The default would be alright, I think. Also, can you show the computation code in your Raytracer's thread, particularly with regards to the signal emission?lpapp

1 Answers

1
votes

The GUI thread is blocked by something else, or your other thread is not emitting the signals while it's working, but only at the very end. You're not showing enough code to diagnose what's wrong.

I have a stand-alone example that does pretty much what you're trying to do. The only change needed is to add QThread::msleep(1000); at the end of runTest (after the emit). That would approximate a test that takes 1 second to execute.