DEK*_*KER 4 c++ lambda qt signals-slots c++11
我有一个带有此签名信号的类:
// CLASS A
signals:
void requestToChangeRange(voltage_range_e vr, current_range_e cr, uint16_t bits);
Run Code Online (Sandbox Code Playgroud)
还有另一个类具有这样的插槽(请注意额外的参数)
// CLASS C
public slots:
void handleRequestRangeChange(voltage_range_e vr, current_range_e cr, uint16_t bits, uint16_t limiter);
Run Code Online (Sandbox Code Playgroud)
然后我有一个班级“ 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);
Run Code Online (Sandbox Code Playgroud)
但是显然,由于函数签名,这是行不通的。我想做的是这样的:
// 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);
});
Run Code Online (Sandbox Code Playgroud)
那么如何在lambda中访问那些传递的参数呢?这有可能吗?
您的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) {
//...
});
Run Code Online (Sandbox Code Playgroud)
关于connect()语句中的“接收器”:
连接到lambda时实际上不需要指向QObject的指针,但是它的目的是在发送方或接收方被破坏时,将删除信号插槽连接。
使用this意味着您必须确保删除其中一个后pClassX,pClassC不再发出信号。另外,您也可以将其pClassC用作接收器,然后必须确保它pClassX一直有效pClassC并pClassA一直存在。...理想情况下,您将pClassXAND 指定pClassC为接收器,但这是不可能的。您可以QPointer为此使用a的保护功能。