gpt4 book ai didi

c++ - 为什么我不能在信号上启动QThread?

转载 作者:行者123 更新时间:2023-12-02 09:48:14 25 4
gpt4 key购买 nike

我想在另一个启动时启动QThread,但是它不起作用。
main.cpp片段

Worker stat_worker;
stat_worker.moveToThread(stat_worker.stat_thread);

Worker some;
some.moveToThread(some.somethread);
QObject::connect(stat_worker.stat_thread, SIGNAL(started()), some.somethread, SLOT(start()));
QObject::connect(some.somethread, SIGNAL(started()), &some, SLOT(print_some()));
stat_worker.stat_thread->start();
worker
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker();

QThread *stat_thread = new QThread;
QThread *somethread = new QThread;
signals:
//some signals
void start_thread();
public slots:
//some slots
void print_some();
void somethread_starter();
};

#endif // WORKER_H
worker.cpp相关功能
void Worker::print_some()
{
qInfo() << "-somethread started() signal arrived!";
}
当我尝试通过单击按钮启动线程时,也没有用。
甚至创建一个启动线程的插槽:
QObject::connect(stat_worker.stat_thread, &QThread::started, &some, &Worker::somethread_starter);

void Worker::somethread_starter()
{
qInfo() << "-I got started by another thread!";
somethread->start();
}
或在启动另一个线程时发出的信号:
void Worker::wip_status(){
emit start_thread();
}

QObject::connect(stat_worker.stat_thread, &QThread::started, &stat_worker, &Worker::wip_status);
QObject::connect(&stat_worker, &Worker::start_thread, &some, &Worker::somethread_starter);
工作。
在此先感谢您回复我的帖子。

最佳答案

我试图用自己的MCVE(只是短一点)重现OP的问题。

#include <QtWidgets>

struct Worker: QObject {
QString name;
QThread qThread;

Worker(const QString &name): name(name)
{
moveToThread(&qThread);
connect(&qThread, &QThread::finished, this, &Worker::reportFinished);
}

void start()
{
qDebug() << "Start" << name;
qThread.start();
}

void reportFinished()
{
qDebug() << "Exit" << name;
}
};

// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QCoreApplication app(argc, argv);
Worker worker1("worker 1");
Worker worker2("worker 2");
// install signal handlers
QObject::connect(&worker1.qThread, &QThread::started, &worker2, &Worker::start);
worker1.start();
// runtime loop
return app.exec();
}
输出:
Qt Version: 5.13.0
Start "worker 1"
这是OP观察到的。所以呢?
  • worker1.qThread.started信号连接到worker2.start插槽
  • worker1已启动
  • worker2似乎没有开始。

  • 是什么让我感到怀疑: moveToThread()
    目的是将 Worker对象与其成员 QThread相关联。
    我不确定的是:在启动 QThread之前有可能吗?
    为了检查这一点,我评论了 moveToThread():
      Worker(const QString &name): name(name)
    {
    //moveToThread(&qThread);
    connect(&qThread, &QThread::finished, this, &Worker::reportFinished);
    }
    输出:
    Qt Version: 5.13.0
    Start "worker 1"
    Start "worker 2"
    我之所以评论 moveToThread()的原因: qThread::start()的调用应在主应用程序(线程)的上下文中进行。
    因此,将 worker2移至其 QThread意味着该信号已发送到 worker2.qThread的事件循环-实际上尚未启动。
    因此,该事件无法处理。 moveToThread()应该稍后执行-例如在 started()信号的 react 中:
    #include <QtWidgets>

    struct Worker: QObject {
    QString name;
    QThread qThread;

    Worker(const QString &name): name(name)
    {
    connect(&qThread, &QThread::started, this, &Worker::moveThisToThread);
    connect(&qThread, &QThread::finished, this, &Worker::reportFinished);
    }

    void start()
    {
    qDebug() << "Start" << name;
    qThread.start();
    }

    void moveThisToThread()
    {
    moveToThread(&qThread);
    qDebug() << name << "associated to its thread, from now.";
    }

    void reportFinished()
    {
    qDebug() << "Exit" << name;
    }
    };

    // main application
    int main(int argc, char **argv)
    {
    qDebug() << "Qt Version:" << QT_VERSION_STR;
    QCoreApplication app(argc, argv);
    Worker worker1("worker 1");
    Worker worker2("worker 2");
    // install signal handlers
    QObject::connect(&worker1.qThread, &QThread::started, &worker2, &Worker::start);
    worker1.start();
    // runtime loop
    return app.exec();
    }
    输出:
    Qt Version: 5.13.0
    Start "worker 1"
    "worker 1" associated to its thread, from now.
    Start "worker 2"
    "worker 2" associated to its thread, from now.

    奖励问题:

    So does that mean "QThread::start" is useless as receiver of a signal?


    不,这不对。即使不存在带有该签名的信号(我知道),应用程序开发人员也可以“发明”一个信号。
    但是,请记住,Qt5实际上并不需要显式标记的 SLOT来将它们用于信号,过去可能会找到一个更明显的答案:
    对于Qt4信号,可以将 QThread::start插槽直接连接到 QThread::started信号。 (然后 QThread::start中唯一的一个参数的默认值生效。)
    由于我没有使用Qt4信号的经验(我从Qt5开始),因此我修改了示例代码以证明自己是正确的:
      QObject::connect(&worker1.qThread, SIGNAL(started()), &worker2.qThread, SLOT(start()));
    输出:
    Qt Version: 5.13.0
    Start "worker 1"
    "worker 1" associated to its thread, from now.
    "worker 2" associated to its thread, from now.
    由于 Start "worker 2"现在直接调用 worker1.started(),因此不再发出 worker2.qThread.start()
    因此,使用Qt4信号可能已经运行了OP的原始代码。
    引起问题的不是信号和插槽的不兼容(有人猜到了),但上述 moveToThread()问题(也可能)并没有使它令人满意地工作。

    关于c++ - 为什么我不能在信号上启动QThread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63067960/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com