如何编写监听传入信号的第二个线程
How to write a second thread which listens to incoming signals?
我有一个关于Qt中Slot-/Signal架构的问题。对于我的项目,我有单独的功能:
a) GUI
b) 控制外部设备
现在我想让函数b)不断地监听从a)在特定插槽上发送的信号。但是这种监听不应该影响GUI线程,例如,我想继续我在那里的工作。
因此,我有了将函数b)移动到一个单独线程的想法。但我的问题是,我不知道如何在这个线程中创建run
-函数。它应该从我的程序开始(没有问题),它应该不断地监听传入的信号,然后运行连接到这个信号的函数。
一个简单的while(1)
就足够了吗?
Qt让这变得非常简单。我不建议为此重写run()
,因为它没有必要——而且它也不那么灵活或易于实现,并且在对象创建方面有一些注意事项。
相反,只需创建一个线程,然后将侦听对象移动到它。例如:
// 'this' as parent means thread will terminate automatically when 'this'
// is deleted, you have other options here, of course.
QThread *thread = new QThread(this);
// Create your object (or just use an existing one). Note new object initially
// lives on current thread. Note also it does not have a parent. Objects with
// parents cannot be moved to other threads explicitly.
MyObject *object = new MyObject(); // Assuming MyObject is a QObject.
// Now move the object to the new thread.
object->moveToThread(thread);
// And, you'll want to make sure the object is deleted when the thread ends.
connect(thread, SIGNAL(finished()), object, SLOT(deleteLater()));
connect(thread, SIGNAL(terminated()), object, SLOT(deleteLater())); // just in case
// Finally, start the thread:
thread->start();
这就是你所需要做的!现在线程正在运行,它有自己的事件循环,连接到对象插槽的信号将排队并在该线程上运行†。
请注意,如果对象的构造函数创建了自己的任何QObject,那么它应该相应地将自己设置为这些对象的父对象。当您执行object->moveToThread()
时,Qt也会自动将对象的所有子对象移动到线程中。
您可以将任意多个对象移动到给定的QThread
,但不限于一个。
要显式结束线程并清理对象,请调用thread->exit()
或删除线程。不过,由于我们在上面的示例中将this
作为QThread
的父级,所以实际上根本不需要进行任何清理。
顺便说一句,如果你有一些初始化或其他任务,当线程启动时,你的对象应该在线程上执行,你也可以使用线程的started()
信号:
connect(thread, SIGNAL(started()), object, SLOT(initializeWhatever()));
当然,请注意,以上述方式使用的任何对象都必须是QObject
的子类。这是例如moveToThread()
和deleteLater()
所在的位置,也是正确处理时隙所必需的:
class MyObject : public QObject {
Q_OBJECT
public:
MyObject (QObject *parent = 0);
signals:
...
public slots:
...
};
实际上,最简单的设置方法是在QtCreator中,右键单击,添加一个新类,然后选择QObject
作为基础。Qt将为您设置一个模板头和源文件。
†除非连接类型为DirectConnection
,但默认情况下不是。
- 用于矢量处理的多个线程
- 如何在多个线程中创建 QSql数据库连接时防止名称冲突
- 如何声明由多个线程调用的 C++ DLL 的内部类,而无需导出类
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- 将 10 个线程与原子布尔值同步
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- 一个线程等待多个线程事件
- 如果在 2 个线程中使用,是否值得将size_t声明为 std::atomic?
- 餐饮哲学家问题 - 只有 2 个线程工作
- 如果两个线程相互依赖,则 cpp 线程连接应使用连接导致死锁
- 如何使用 SIGINT 在第二个线程中断 getchar
- 从第二个线程调用Qt信号有效 - >对连接的插槽没有影响
- 从第二个线程访问主线程中的变量
- 使用第二个线程快速更新 GUI 窗口会通过调整窗口大小或移动窗口而崩溃
- 2个线程 - 一个带有OpenGL窗口的线程,第二个带有WXWIDGETS的窗口
- OpenGL 在第二个线程中,在类中启动
- 使用 Mongoose 服务器在第二个线程中发送数据
- 如何编写监听传入信号的第二个线程
- 如何在第二个线程从映射中删除值时恢复线程