我非常了解在Qt 5中使用新语法连接插槽的好处和缺点。仅举几个例子:
优点:
- 编译时检查(插槽存在,兼容参数…(
- 可以使用lambdas(适用于非常短和特定的插槽(
- 保护私有/受保护的插槽不被从类外调用(ref(
对手:
- 在某些情况下更复杂的语法(特别是重载(
- 不支持参数为默认值的插槽
我也知道,在某些(极少数(情况下,(还(不可能使用新语法(QFileDialog::open
(。
现在,对于旧语法,我们必须在它们的定义中将这些方法标记为slots
,用Q_OBJECT
宏标记类,mocit,并从QObject
继承。如上所述,新语法不需要标记为slots的方法。
在使用(并且仅使用(新语法时,保留slots
说明符有什么好处吗?如果槽是一个类使用的唯一QMetaObject
的特征,那么我们就可以避免将该类标记为Q_OBJECT
的必要性,甚至可以避免从QObject
本身继承。
如果槽是类使用的唯一QMetaObject的特征,那么我们就可以避免将该类标记为Q_OBJECT,甚至从QObject本身继承。
您仍然需要从QObject
本身继承,因为您需要一个对象来调用上的函数。该对象必须从QObject
继承,以便Qt可以检测它所在的线程(插槽调用可能需要在不同的线程上排队(,并在接收器被破坏时处理自动断开连接。
但是,您可以通过将信令QObject
作为接收对象并使用lambda:来解决这个问题,而不会遇到太多麻烦
connect(qObjectInstance, &QObjectClass::signal, qObjectInstance, [&](){
notAQObject->slot();
});
但是,如果notAQObject
可能在信号QObject
之前被破坏,则您必须自己管理断开连接。
至于slots
宏:如果您严格使用C++,并且没有通过QMetaObject
查找插槽,那么slots
对您没有任何帮助。slots
或类似的东西(Q_INVOKABLE(通常是必要的,如果您与更多使用Qt元对象系统的东西(如QML(进行交互操作。