QT5 Межпотоковая связь, слот не вызывается в контексте "this"

У меня есть объект MainWorker, запущенный как отдельный поток, благодаря методу moveToThread. MainWorker имеет член SubWorker, который также запускается как отдельный поток. Оба потока работают в бесконечных циклах.

Идея заключается в том, что MainWorker и SubWorker выполняют несколько отдельных вычислений. Всякий раз, когда SubWorker завершает вычисления, он должен уведомить MainWorker о результате.

Поэтому я интуитивно установил первое соединение между сигналом, излучаемым SubWorker, и слотом MainWorker, но он не работал, поэтому я сделал еще два соединения, чтобы исключить некоторые потенциальные проблемы:

connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)); //1
connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff); //2
connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf); //3

Кажется, что то, что не работает, это именно то, что мне нужно - кросс-потоковая связь, потому что соединения 2 и 3 работают как положено. У меня вопрос: как мне заставить работать соединение 1?

Редактировать: Очевидно, после объяснения Карстена, становится ясно, что бесконечный цикл блокирует цикл EventLoop. Итак, новый вопрос, как я могу отправлять сообщения (сигналы, что угодно) из потока бесконечного цикла в его родительский поток?

Я новичок в Qt, есть большая вероятность, что я все понял неправильно. Вот минимальный (не) рабочий пример:

MainWorker.h

class MainWorker : public QObject
{
Q_OBJECT

public:
    MainWorker() : run(false) {}

void doStuff()
{
    subWorker = new SubWorker;
    subWorkerThread = new QThread;
    subWorker->moveToThread(subWorkerThread);
    connect(subWorkerThread, &QThread::started, subWorker, &SubWorker::doStuff);
    if(!connect(subWorker, &SubWorker::stuffDid, this, &MainWorker::reportStuff)) qDebug() << "connect failed";
    connect(subWorker, &SubWorker::stuffDid, subWorker, &SubWorker::reportStuff);
    connect(this, &MainWorker::stuffDid, this, &MainWorker::reportStuffSelf);

    subWorkerThread->start();

    run = true;
    while(run)
    {
        QThread::currentThread()->msleep(200);
        emit stuffDid();
    }
}

private:
    bool run;
    QThread* subWorkerThread;
    SubWorker* subWorker;

signals:
    void stuffDid();

public slots:
    void reportStuff()
    {
        qDebug() << "MainWorker: SubWorker did stuff";
    }

    void reportStuffSelf()
    {
        qDebug() << "MainWorker: MainWorker did stuff (EventLoop is not blocked)";
    } 
};

SubWorker.h

class SubWorker : public QObject
{
    Q_OBJECT

public:
    SubWorker() : run(false) {}

    void doStuff()
    {
        run = true;
        while(run)
        {
            qDebug() << "SubWorker: Doing stuff...";
            QThread::currentThread()->msleep(1000);
            emit stuffDid();
        }
    }

private:
    bool run;

public slots:
    void reportStuff()
    {
        qDebug() << "SubWorker: SubWorker did stuff";
    }

signals:
    void stuffDid();
};

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MainWorker *mainWorker = new MainWorker;
    QThread *mainWorkerThread = new QThread;
    mainWorker->moveToThread(mainWorkerThread);
    QObject::connect(mainWorkerThread, &QThread::started, mainWorker, &MainWorker::doStuff);
    mainWorkerThread->start();

    return a.exec();
}

0 ответов

Другие вопросы по тегам