Сигналы QThread для графического интерфейса получены, но ответ не асинхронный

У меня есть тяжелые вычисления в производном классе QObject. Я перемещаю его в свой новый qthread с помощью кнопки в графическом интерфейсе, и он создается только для выполнения этого вычисления.

Предполагается, что графический интерфейс ожидает сообщений от рабочего потока в цикле (потому что после выполнения слота кнопки он просто попадает туда).

Я отправляю сообщения через механизм сигналов и слотов следующим образом. У меня есть общий класс Controller, который выполняет создание потока и соединяет его с графическим интерфейсом пользователя (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));

И вот здесь графический интерфейс получает сигнал:

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

Сигналы принимаются и правильно добавляются в текстовое поле в графическом интерфейсе. Но они появляются сразу после завершения цепочки. Не при расчете, сколько бы он ни длился.

И все сообщения были получены. Так что это своего рода сохранение их в каком-то буфере и обновление текста в конце.

Что я делаю не так и в каких ситуациях это могло произойти? Как он мог это проверить?


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