我有一个带有此签名信号的类:
// CLASS A
signals:
void requestToChangeRange(voltage_range_e vr, current_range_e cr, uint16_t bits);
还有另一个类具有这样的插槽(请注意额外的参数)
// CLASS C
public slots:
void handleRequestRangeChange(voltage_range_e vr, current_range_e cr, uint16_t bits, uint16_t limiter);
然后我有一个班级“ B”,它是所有其他班级的集合点。当类“ A”发出信号时,类“ C”应将其重定向到类“ B”。但是,在类“ B”的插槽上的那个额外的参数是问题所在,因为那个额外的参数来自另一个类“ X”。
因此,如果“ A”和“ C”类的信号和插槽匹配,我将在“ B”类中执行以下操作:
// somewhere in CLASS B (the manager of all other classes)
connect(pClassA, &ClassA::requestToChangeRange,
pClassC, &ClassC::handleRequestRangeChange);
但是显然,由于函数签名,这不起作用。我想做的是这样的:
// somewhere in CLASS B (the manager of all other classes)
connect(pClassA, &ClassA::requestToChangeRange,
this /* class B */, []() {
// Get that last required parameter from class X
uint16_t limiter = pClassX->getValue();
// Call slot of class C
pClassC->handleRequestRangeChange(vr, cr, bits, limiter);
});
那么我如何在lambda中访问那些传递的参数?这有可能吗?
答案 0 :(得分:5)
您的lambda应该知道两个对象:[pClassX, pClassC]
,并接受信号的原始参数:(voltage_range_e vr, current_range_e cr, uint16_t bits)
。
所以您的连接应该这样开始:
connect(pClassA, &ClassA::requestToChangeRange, this,
[pClassX, pClassC](voltage_range_e vr, current_range_e cr, uint16_t bits) {
//...
});
关于connect()语句中的“接收器”:
连接到lambda时实际上并不需要指向QObject的指针,但它的目的是在发送方或接收方被破坏时,将删除信号插槽连接。
使用this
意味着您必须确保删除pClassX
,pClassC
中的任何一个后不再发出信号。或者,您可以使用pClassC
作为接收者,然后必须确保pClassX
保持有效,只要pClassC
和pClassA
仍然存在...理想情况下,您应该指定pClassX
和pClassC
作为接收者,但这是不可能的。为此,您可以利用QPointer
的防护功能。
答案 1 :(得分:1)
在这种情况下值得一提的一个技巧是,如果您掌握了指向QObjects的指针,我建议您首先创建QPointer变量,然后在lambda中掌握THOSE。这样,您可以检查它们是否已删除。如果使用正常的信号和插槽,则可以解决此问题,但是使用lambda时,您可能需要自己处理参考的生命周期。
希望我们很快会获得更多方便的C ++捕获构造对象的方法。