未调用 Qt moveToThread 插槽
Posted
技术标签:
【中文标题】未调用 Qt moveToThread 插槽【英文标题】:Qt moveToThread slot not called 【发布时间】:2014-08-14 12:24:54 【问题描述】:我有一堂课Manager
class Manager : public QThread Q_OBJECT public: Manager(); void run() taskB = new TaskB(); taskA = new TaskA(); connect(taskA, SIGNAL(signalOk()), taskB, SLOT(onSignalOk())); connect(taskA, SIGNAL(moveOk()), taskB, SLOT(onMoveOk())); connect(taskB, SIGNAL(signal()), taskA, SLOT(onSignal())); connect(taskB, SIGNAL(moveToThreadSignal(QThread*)), taskA, SLOT(onMoveToThread(QThread*))); connect(this, SIGNAL(runSignal()), taskB, SLOT(onRun())); emit runSignal(); TaskA* taskA; TaskB * taskB; signals: void runSignal(); ;
我也有这样的课程TaskA
:
class TaskA : public QObject Q_OBJECT public: TaskA(); void run() std::cout << "[INFO] : Task run: " << QThread::currentThreadId() << std::endl; emit signalOk(); public slots: void onSignal() run(); void onMoveToThread(QThread * t) std::cout << "[INFO] : Task A after move to thread: " << QThread::currentThreadId() << std::endl; this->moveToThread(t); std::cout << "[INFO] : Task A after move to thread: " << QThread::currentThreadId() << std::endl; emit moveOk(); signals: void signalOk(); void moveOk(); ;
我也有这样的课程TaskB
class TaskB : public QObject Q_OBJECT public: TaskB(); void run() std::cout << "[INFO] : TaskB run: " << QThread::currentThreadId() << std::endl; emit signal(); signals: void signal(); void moveToThreadSignal(QThread* t); public slots: void onSignalOk() std::cout << "[INFO] : TaskB onSignalOk : " << QThread::currentThreadId() << std::endl; void onMoveOk() std::cout << "[INFO] : TaskB onMoveOk: " << QThread::currentThreadId() << std::endl; run(); void onRun() std::cout << "[INFO] : TaskB emit MoveToThreadSignal: " << QThread::currentThreadId() << std::endl; thread = new QThread(); thread->start(); emit moveToThreadSignal(thread); private: QThread * thread; ;
当我启动管理器时:
经理 *_manager = 新经理();
_manager->start();
TaskB
的槽 onSignalOk()
未被调用。
我认为问题原因是我连接信号时的默认参数Qt::AutoConnection
,但我不明白。
【问题讨论】:
这里还有其他问题,需要考虑线程亲和性。我建议你从阅读这篇文章开始:mayaposch.wordpress.com/2011/11/01/… 这个标题具有误导性。 Qt 中有一个 movetoThread 和一个名为 movetoThreadSignal 的函数。大不同。 让我们退后一步。你最终想做什么?上面的代码有很多缺陷。特别是thread = new QThread();thread->start();
。您对这段代码有什么期望?
这段代码只是一个板凳。我的项目是任务管理器。 TaskB 是并行运行其他任务(如 TaskA)的任务。
感谢@Merlin069 的评论。通过这篇文章,我更正了我的经理,它现在可以工作了。 Manager 继承 QObject 而不是 QThread,然后我使用 moveToThread。
【参考方案1】:
我建议从不继承 QThread 开始;它的名称具有误导性,因为它更像是一个线程管理器。在我看来,从 QThread 继承的唯一原因是如果你想改变 Qt 管理线程的方式。
相反,只需从 QObject 继承并将对象移动到新线程。这样做的好处是能够将多个对象移动到一个新线程,而不是在继承 QThread 时为每个对象创建一个单独的线程。
【讨论】:
以上是关于未调用 Qt moveToThread 插槽的主要内容,如果未能解决你的问题,请参考以下文章