个人使用过的信号槽的连接方式有三种,需要产生信号的类需要在类定义中加入Q_OBJECT,并且重新执行qmake

1.QT4信号槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
connect(sender,SIGNAL(),receiver,SLOT());
分别为发送信号的类,对应的信号,接收信号的类,处理信号的槽

关于SIGNAL和SLOT,其实是qt的两个宏定义

Q_CORE_EXPORT const char *qFlagLocation(const char *method);

#ifndef QT_NO_META_MACROS
#ifndef QT_NO_DEBUG
# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
# ifndef QT_NO_KEYWORDS
# define METHOD(a) qFlagLocation("0"#a QLOCATION)
# endif
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else
# ifndef QT_NO_KEYWORDS
# define METHOD(a) "0"#a
# endif
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif

2.QT5信号槽

1
2
3
4
connect(sender,&senderClassName::functionName,receiver,&receiverClassName::function);
因为会进行错误检查,而qt4不会,从上面可以得知,qt4信号槽的参数只是字符串。
但是对于信号重载的处理比较麻烦,qt4只需要在signals里面使用()括上参数即可,而qt5需要进行强制转换。
static_cast<void (className::*)(parameter)>(&className::functionName)

3.信号与Lamda表达式结合

1
2
3
4
5
6
7
8
9
10
11
connect(sender,&senderClassName::functionName,[=]( //parameter ){ //slove });

[] 捕捉列表
[] 不捕获任何值
[var1,var2...] 在函数里,捕获var1,var2的值
[&var1,&var2...] 捕获var1,var2的引用对象
[=] 捕获所有外部变量的值
[&] 捕获所有外部变量的引用
() 参数
mutable 可以修改捕捉值,但是值本身不会发生改变
{} 处理

4.隐藏的第五个参数

Constant Value Description
Qt::AutoConnection 0 (默认)如果发送和接收都在同一个线程,使用Qt::DirectConnection,否则使用Qt::QueuedConnection。类型是在信号发送时才确定的
Qt::DirectConnection 1 收到信号后,马上即行
Qt::QueuedConnection 2 保存在一个队列中,当接收事件循环启动时,执行槽函数
Qt::BlockingQueuedConnection 3 与Qt::QueuedConnection类似,但是运行槽函数时,会阻塞信号线程。发送与接收不可以在同一线程,会造成死锁
Qt::UniqueConnection 0x80 可以使用OR实现多种参数连接,但是如果已经存在相同的connect时,会失败。

注意,使用连接时,需要考虑之前是否有连接,因为重新连接了相同的信号与槽,发出一个信号后,会多次触发槽函数,非常浪费资源!!

补充介绍disconnec的使用

1
2
3
4
5
disconnect(sender,信号,receiver,槽);
其中,信号、receiver、槽都可以为0(0表示任意所有) sender不能为0
1、sender多个不同的信号与receiver的一个槽绑定,参数可以这样写,(sender,0,receiver,槽)
2、sender多个信号与receiver的多个槽绑定了,(sender,0,receiver,0
3、sender多个信号与多个receiver的多个槽绑定了,(sender,0,0,0