Qt向对象发出信号移动到线程

时间:2013-01-25 15:51:13

标签: c++ qt signals-slots qthread

为了通过设置标志(然后从线程内返回)来启动线程停止,我需要与它通信。

线程就像这样实现

MyClass* obj = new MyClass(0);
connect( this,SIGNAL( stop() ),obj, SLOT(stop()));
emit stop();    // slot is called (qDebug output)

MyThread = new QThread;
obj->moveToThread(MyThread);
connect( ... started() ... quit() ... finished() ... deleteLater() ...
....

emit stop();    // slot isn't called (qDebug output)

插槽还没有任何逻辑,它只使用qDebug()输出。 对象创建和连接在主窗口方法中进行。

不幸的是,我无法弄清楚我做错了什么:一旦将对象移动到线程,插槽就不再运行了。

2 个答案:

答案 0 :(得分:1)

也许你只是忘了复制/粘贴它,但是你错过了MyThread->start()电话。另外,声明线程的行应该是QThread * MyThread = new QThread();,但这可能只是一个错字。

现在,在您的回答中,您说使用Qt::DirectConnection似乎解决了您的问题。但是,使用直接连接调用的插槽只是直接调用slot方法。 slot方法正在运行,但它正在从调用线程(发出stop()信号的位置)运行。即使您的线程未启动,这也会有效。你真正想要的是通过Qt::QueuedConnection调用插槽。这将在工作线程的事件循环中放置一个事件,然后调用该插槽。请注意,如果您未指定,Qt将处理连接类型。

如果排队连接不起作用,那么您可能会阻止线程的事件循环与您的工作。在您的工作方法中,您是否将控制权传递回事件循环以允许其处理事件?或者它只是在while循环中运行,等待标志改变状态?

此外,您的代码不会按原样编译/运行。我假设您已经处理了QApplication内容 - 即在QApplication::exec()函数中设置完所有内容后调用main。如果您不调用exec(),则永远不会启动主事件循环。

答案 1 :(得分:-1)

调试输出实际上是在线程完成其工作之后发生的。 使用

connect( this, SIGNAL(stop()), obj, SLOT(stop()), Qt::DirectConnection);

解决了这个问题。