如何向 Qt 中 QThread 类的特定对象发出信号?

Posted

技术标签:

【中文标题】如何向 Qt 中 QThread 类的特定对象发出信号?【英文标题】:How to emit signal to a specific object of a QThread class in Qt? 【发布时间】:2017-02-14 07:26:38 【问题描述】:

假设我们已经从一个 QThread 类创建了几个实例。考虑到所有线程对象都是从同一个 Qthread 类实例化的,我需要将消息从一个线程对象发送到另一个线程对象。通过发出信号,所有线程对象都将接收到发出的信号。但我只希望一个特定的对象(例如具有特定线程 id 的对象)接收信号。我如何在 Qt 中做到这一点?

谢谢。

【问题讨论】:

听起来你是从 QThread 继承的,在这种情况下,我建议你阅读this article。 QThread 更像是一个线程控制器而不是一个实际的线程,所以除非你想改变 Qt 管理线程的方式,否则最好不要从 QThread 继承。 【参考方案1】:

信号和槽在您的类中定义,但是您将特定对象的信号连接到特定对象的槽。当您在一个线程中发出信号时,只有连接到它的插槽的对象才能接收到该信号。

【讨论】:

是的,我将信号连接到课堂上的插槽。我的类继承自 QThread 类。我需要的是,当我发出信号时,我不希望从同一类实例化的所有对象都接收到信号。我想向特定对象而不是所有对象发出信号。 @m.taheri 你connect 特定对象,而不是类。只有连接的对象才会接收到信号。否则没有任何意义。 是的,我将对象连接在一起。但我需要向连接对象集中的特定对象发出信号。 你可以使用QMetaObject::invokeMethod,但我不明白为什么你连接所有对象而不是你想要接收信号的对象。 我将所有对象连接在一起,因为每次消息都会在任何一对对象之间交换。所以我应该为每对对象之间的消息交换准备条件。【参考方案2】:

如果我理解正确,您可能需要QSignalMapper:

该类收集一组无参数信号,并使用与发送信号的对象相对应的整数、字符串或小部件参数重新发出它们。

查看示例了解更多信息,如果您不喜欢使用信号映射器,您可以随时在您的插槽中使用自定义过滤器。所以所有其他插槽(对信号不感兴趣)可以忽略它。无法使用emit 过滤信号以将其直接发送到指定的连接插槽。

【讨论】:

谢谢@xander,但是因为我的对象是线程并且每个线程都有其唯一标识符,所以我怀疑 QSignalMapper 是否对我的目的有用。因为我们应该在创建和删除线程之前填充映射。在我的应用程序中,线程数不是固定的,线程是动态添加和删除的。但我认为你的第二个提议会很有用,而且是我唯一能做的。非常感谢。【参考方案3】:

信号的发送者无法确定谁接收了信号,并且每个连接到此类信号的实例都会接收到它。这是信号/槽机制实现的观察者模式所固有的。

我会创建一个中介,派生线程(比如 A(1,..,N))在此注册自己。在中介中,您需要实现来自 A(i) 的消息必须到达 A(j) 的逻辑。优点是 A 实例不需要相互了解。交互可以通过发布事件来完成,根据 qt 是线程安全的。

【讨论】:

以上是关于如何向 Qt 中 QThread 类的特定对象发出信号?的主要内容,如果未能解决你的问题,请参考以下文章

Qt信号发射和QThread执行流程

如何向另一个线程发出带有数组参数的信号

如何在 QT 中停止 qThread [重复]

不能发出 QThread 的信号

QT事件循环与QThread类的关闭quit(),wait()

QT多线程操作