如何编写监听传入信号的第二个线程?

时间:2014-10-25 15:23:53

标签: c++ multithreading qt

我对Qt中的Slot- / Signal-architecture有疑问。对于我的项目,我有以下功能:

a)GUI
b)控制外部设备

现在我希望功能b)不断监听a)在特定插槽上发送的信号。但是这种监听不应该影响GUI线程,例如我想继续在那里工作。

因此我有了将函数b)移动到单独的线程的想法。但我的问题是我不知道如何在这个线程中创建run - 函数。它应该从我的程序开始(没问题),它应该不断地监听输入信号,然后运行连接到该信号的功能。

一个简单的while(1)是否足够?

1 个答案:

答案 0 :(得分:3)

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,否则默认情况下不是。{/ p>