QThread получава сигнали към GUI, но отговорът не е асинхронен

Имам тежко изчисление под произхождащ от QObject клас. Премествам го в моя нов qthread чрез бутон в GUI и той е създаден само за целите на изпълнението на това изчисление.

Предполага се, че GUI чака съобщения от работната нишка в цикъл (тъй като след изпълнение на слота за бутон, той просто отива там).

Излъчвам съобщенията чрез механизъм за сигнал и слот, както следва. Имам общ контролер на клас, който изпълнява създаването на нишката и я свързва с 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();

За класа Raytracer:

class Raytracer : public QObject
{
Q_OBJECT

По време на изчисленията той излъчва неща като това:

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

И GUI получава сигнала тук:

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

Сигналите се получават и правилно се добавят към текстово поле в GUI. Но те се появяват веднага след приключване на нишката. Не по време на изчислението, независимо колко дълго е то.

И всички съобщения бяха получени. Така че някак си ги държи в някакъв буфер и актуализира текста в края.

Какво правя грешно и в какви ситуации може да се случи това? Как може да го тества?


person Darkgaze    schedule 23.02.2014    source източник
comment
Малко съм объркан защо използвате изрично връзка на опашка. По подразбиране би било добре, мисля. Също така, можете ли да покажете изчислителния код в нишката на вашия Raytracer, особено по отношение на излъчването на сигнала?   -  person lpapp    schedule 24.02.2014


Отговори (1)


Нишката на GUI е блокирана от нещо друго или другата ви нишка не излъчва сигналите, докато работи, а само в самия край. Не показвате достатъчно код, за да диагностицирате какво не е наред.

Имам самостоятелен пример, който прави почти това, което се опитвате да направите. Единствената необходима промяна е да добавите QThread::msleep(1000); в края на runTest (след emit). Това би било приблизително тест, който отнема 1 секунда за изпълнение.

person Kuba hasn't forgotten Monica    schedule 23.02.2014