Сигнал Qt от QRunnable не получен/не подключается

Я пишу приложение Qt на С++. У меня есть QRunnable, работающий в QThreadPool, и он отправляет сигнал в основной поток. Проблема в том, что соединение не работает: сигнал никогда не принимается основным потоком, хотя я убедился, что код, выполняющий отправку, действительно вызывается. Вот мой код:

Мой класс QRunnable:

class OfflineAnalysisThread : public QObject, public QRunnable
{
Q_OBJECT

public:
void run();
void sendMessage(QString &qmsg)
{
    emit threadMessageCallback(qmsg);
}

signals:
void threadMessageCallback(QString &string);
};

И вызывающий класс (основной поток):

class OfflineAnalysisMain : public QObject
{
Q_OBJECT

public:

    (...)

public slots:
void threadMsg(QString &string);
};

Код, который создает новые экземпляры QRunnable и запускает их:

void OfflineAnalysisMain::myFunction()
{
    OfflineAnalysisThread *newTask = new OfflineAnalysisThread();

    QObject::connect(newTask, SIGNAL(threadMessageCallback(QString &)), this, SLOT(threadMsg(QString &)));

    QThreadPool::globalInstance()->start(newTask);
}

Итак, из функции запуска моего QRunnable я вызываю sendMessage, а затем выполняю QApplication::exec(). У меня есть точка останова в реализации слота threadMsg в OfflineAnalysisMain.cpp, и эта функция никогда не вызывается.

Что я делаю неправильно?

ОБНОВИТЬ:

Определение моей функции OfflineAnalysisThread::run():

void OfflineAnalysisThread::run()
{
    std::string myMsg("This is my message");
    sendMessage(myMsg);

    QApplication::exec();
}

Я также пробовал без QApplication::exec();, но безуспешно.


person Karl Arsenault    schedule 02.03.2013    source источник
comment
Покажите нам свое определение OfflineAnalysisThread::run(). Судя по тому, что вы написали, это неправильно. Вы не должны звонить QApplication::exec() из run().   -  person RA.    schedule 03.03.2013
comment
Я только что обновил свой пост своим определением run(). Пожалуйста, взгляните. Также я пробовал без exec() (на самом деле это был мой исходный код, я добавил exec(), чтобы посмотреть, сработает ли это).   -  person Karl Arsenault    schedule 03.03.2013


Ответы (1)


Удалите вызов QApplication::exec() из run(). В идеале это вызывается из вашей функции main.

Чтобы заставить ваш код работать, мне пришлось написать следующую функцию main:

#include <QApplication>
#include <QMetaType>

#include <offlineanalysismain.h>

int main(int argc, char* argv[])
{
   QApplication app(argc, argv);

   qRegisterMetaType<QString>("QString&");

   OfflineAnalysisMain* main = new OfflineAnalysisMain;
   main->myFunction();

   return app.exec();
}

Обратите внимание на вызов qRegisterMetaType, который позволяет Qt передавать QString через соединение сигнал-слот, пересекающее границы потоков.

person RA.    schedule 02.03.2013