成员函数
需在类中显式声明槽函数(public slots:
或 Qt 5 后的任意成员函数),并在连接时指定接收对象。
class Receiver : public QObject {
Q_OBJECT
public slots:
void handleSignal(int value) { /* ... */ }
};
// 连接信号与槽
QObject::connect(sender, &Sender::valueChanged, &receiver, &Receiver::handleSignal);
Lambda 表达式
无需预定义槽函数,直接在连接时内联实现逻辑:
QObject::connect(sender, &Sender::valueChanged, [](int value) {
qDebug() << "Lambda received:" << value;
});
成员函数
可直接访问类的成员变量(通过 this
),但无法直接捕获局部变量。
Lambda 表达式
通过捕获列表([]
)访问局部变量或 this
:
int localVar = 10;
QObject::connect(sender, &Sender::signal, [this, localVar] {
this->memberVar = localVar; // 捕获 this 和局部变量
});
注意:若 Lambda 异步执行(如跨线程),需确保捕获的变量生命周期有效(避免悬空引用)。
成员函数
若指定接收对象(receiver
),Qt 自动在 receiver
析构时断开连接,避免野指针。
Lambda 表达式
默认无接收对象:Lambda 可能访问已销毁的对象(如捕获 this
后对象被删除)。
解决方案:显式传递接收对象作为上下文:
QObject::connect(sender, &Sender::signal, receiver, [this] {
// receiver 析构时自动断开连接
});
成员函数
槽函数必须声明与信号匹配的参数列表(类型和数量需兼容)。
Lambda 表达式
可灵活忽略或自定义参数:
// 忽略信号参数
connect(sender, &Sender::dataReady, [] { /* 无需参数 */ });
// 仅使用部分参数
connect(sender, &Sender::multiParamSignal, [](int a) { /* 只使用第一个参数 */ });
成员函数
需用 static_cast
区分重载信号:
connect(sender, static_cast(&Sender::overloaded), /* ... */);
Lambda 表达式
直接关联具体重载版本,无需转换:
connect(sender, qOverload(&Sender::overloaded), [](int value) { /* ... */ });
场景 | 成员函数 | Lambda 表达式 |
---|---|---|
复杂逻辑 | ✅ 更清晰 | ❌ 代码膨胀 |
访问类成员 | ✅ 直接访问 | ✅ 需捕获 this |
使用局部变量 | ❌ 困难 | ✅ 灵活捕获 |
一次性简单操作 | ❌ 冗余 | ✅ 简洁内联 |
跨线程安全 | ✅ 自动管理生命周期 | ⚠️ 需手动确保对象安全 |
优先用成员函数:
当槽函数需要重用、逻辑复杂或需严格管理对象生命周期时。
慎用 Lambda:
适合简单、一次性操作,但需确保:
捕获的变量/对象生命周期安全(尤其跨线程)。
通过传递 receiver
对象管理连接生命周期。
避免在 Lambda 中执行耗时操作(阻塞事件循环)。
关键区别:Lambda 提供灵活性和简洁性,但牺牲了显式的生命周期管理;成员函数更安全规范,适合复杂场景。