从多个发送器到单个插槽的Qt映射信号
我相信这是可以做到的,如果以前有人问过我,我很抱歉,但我想不出来 我有一个指向从多个发送器到单个插槽的Qt映射信号,qt,Qt,我相信这是可以做到的,如果以前有人问过我,我很抱歉,但我想不出来 我有一个指向device\u连接类的QList指针:QList` QList归我的设备管理器类所有 我希望得到的是: QObject::connect(此处放置的内容、信号(已连接())、此、插槽(设备已连接()) i、 例如,我希望将任何device\u连接发出的所有信号映射到device\u manager类的device\u connected插槽,同时知道是哪个device\u连接发出了信号 这能做到吗? 如果是这样的话,
device\u连接类的QList指针:
QList`
QList归我的设备管理器类所有
我希望得到的是:
QObject::connect(此处放置的内容、信号(已连接())、此、插槽(设备已连接())
i、 例如,我希望将任何device\u连接发出的所有信号映射到device\u manager
类的device\u connected
插槽,同时知道是哪个device\u连接发出了信号
这能做到吗?
如果是这样的话,我如何制定QObject::connect
?您不能一次连接整个列表。但是您可以在列表上执行循环,以单独连接所有元素。然后,您可以在插槽中使用QObject::sender()
来确定哪个对象发出了信号
或者使用C++11及更高版本,您可以使用lambda扩展连接,并使用指向发送方的指针。您的插槽将有一个额外的参数:
void device_connected(device_connection* connection);
然后你像这样连接:
connect(elem, &device_connection::connected, this, [this,elem] {
device_connected(elem);
});
请注意,当连接到lambda时,虽然指定接收方对象(第三个参数,this
)不是必需的,但您仍然应该这样做。它将确保在删除(隐式)接收对象时清除连接。您可以向信号和插槽添加额外参数,并在QList
上循环,将每个元素连接到设备连接(设备连接类*)
设备管理器的插槽:
for (int i = 0; i < list.size(); i++)
connect(list.at(i), SIGNAL(connected(device_connection class *)),
this, SLOT(device_connected(device_connection class *)));
for(int i=0;i
从这里,您可以通过emit connected(this)
从device\u connection class
将设备与传递到插槽的指针值区分开来
根据您在device\u connect
插槽中需要执行的操作,您只需将任何参数传递给插槽(包含设备名称的QString
字符串?aQ\u ENUM
?…)谢谢,我将如何发出信号?我会在设备连接类中发出connected(this)吗?是的,我忘了提到这一点,所以我编辑了我的答案。如果在对插槽的第一次调用完成之前发出第二个信号,我会遇到问题吗?或者事件循环会保护我不受此影响吗?您的应用程序是多线程的吗?在单个线程中,您描述的内容不应该发生。在单个线程中,如果不明确使用排队连接,信号将导致直接插槽调用(不涉及事件循环)。在插槽中调用新信号的唯一方法是插槽本身触发信号(例如,使发送方对象再次发出信号)。在多线程场景中,可以通过事件循环传递信号。在这种情况下,插槽也不会被新信号中断;新的信号在接收方的线程事件队列中排队,并在线程空闲或显式处理事件循环时进行处理。在Qt中,每个对象都分配给一个线程,该线程单独以串行方式处理传入的信号。感谢您的详细回答。我的每个设备连接都运行一个单独的线程,因为与它们的通信可能涉及阻塞操作。QT信号/插槽是线程之间方便而安全的通信方式。典型的方法是将设备连接对象显式地移动到它们相应的QThread。正如我指出的,在将信号连接到lambda插槽时,应始终指定接收对象;这还确保在接收对象的线程中调用插槽。