所以我有以下设置:
|---- Device[1]
Controller ---+---- Device[2]
|---- Device[3]
| :
|---- Device[x]
每个对象都在自己的线程中。
对于从Deivce [x]到控制器的通信,这是相对简单的,我只是将所有设备信号连接到控制器中的插槽,并将设备索引作为参数传递,以便控制器可以识别哪个设备。
但是,我不确定如何在另一个方向(控制器到设备)上做同样的事情。我提出的最好的是一个类似的方案,我将控制器中的信号连接到每个设备的插槽。我仍然可以传递索引,因此如果消息指向Device [1],则Device [2]和Device [3]可以忽略它。但是,这在数据重复方面是一个巨大的开销吗? - 即数据是否已发送三次?
有更好的方法吗?
编辑1 我编辑了这个例子,表明我可以拥有任意数量的设备..它不是硬编码的数字,所以如果我需要为每个设备提供信号/插槽,则需要动态创建信号。
编辑2
看来你可以直接用以下方法调用方法:
QMetaObject::invokeMethod(devices[x], "handleMessage", Qt::QueuedConnection, Q_ARG(QByteArray msgData)));
这允许我在任何对象上调用一个插槽(排队,所以它的线程安全)并传递我的数据....但是如果我这样做,感觉就像我打破了基本的Qt插槽/信号方法。
答案 0 :(得分:1)
所以我在互联网上找不到这个问题。我看到有些人可能会尝试使用/回答问题:
<强> 1。 QSignalMapper 强>
这有其局限性,我在ram的回答中已经评论过。
<强> 2。直接调用目标槽
你可以直接调用目标插槽(跨线程边界是!),这可以如下所示完成(只显示完整性):
QMetaObject::invokeMethod(devices[x], "handleMessage", Qt::QueuedConnection, Q_ARG(QByteArray msgData)));
其中:
这很好用,但它打破了插槽/信号的整个方法,因为我们在没有信号或连接的情况下调用异物中的插槽...有效地在墙上打孔并抓住我们想要的东西 - 所以它也打破了封装原则(不提及线程边界)。
第3。动态插槽创建
我在qt文档here, about halfway down中看到了这一点,但是看起来像是一个糟糕的代码需要编写/维护所以我甚至都没有尝试过。
我建议的解决方案
所以最后我决定要做些什么。因为我只知道运行时会有多少设备,所以每个设备注册时动态创建信号都很吸引人,但如上所述,不是很好。
但是我们可以动态地实例化对象,其中对象包含可用于将一对一映射到设备的信号。有效地创建一个&#34;邮箱&#34;对象,其信号可以在运行时连接到等效设备。设置如下所示:
|-------------------------|
| |
| Postbox[1]--+------Device[1]
| Controller Postbox[2]--+------Device[2]
| Postbox[3]--+------Device[3]
| | :
| Postbox[x]--+------Device[x]
| |
|-------------------------|
控制器对象包含邮箱对象的数组(或向量)。对于向控制器注册的每个设备,它会创建一个新的邮箱实例,将其信号连接到设备插槽,然后将邮箱添加到阵列。然后,为了向例如设备[3]发布消息,控制器只调用类似postboxes[3].postmessage(msgData);
的函数,postmessage函数发出连接到设备的信号[3]。
据我所知,这是唯一的&#34;正确/简单&#34;这样做的方法是因为qt slot / signals似乎没有设置为进行消息路由。如果我错了,请有人纠正我!
答案 1 :(得分:0)
使用QSignalMapper
。
Controller::Controller()
{
QSignalMapper* signalMapper = new QSignalMapper(this);
for (int i = 0; i < deviceCount; ++i) {
Device* d = new Device(...);
connect(d, SIGNAL(somethingHappened)), signalMapper, SLOT(map()));
signalMapper->setMapping(d, i);
}
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleDevice(int)));
}
void Controller::handleDevice(int id)
{
.....
}