信号与槽的作用
Qt提供了信号和槽的机制用于完成界面操作的响应,是完成任意两个Qt对象之间的通信机制。
信号与槽的原理
信号会在某个特定的情况和动作下被触发,比如Click一个按钮操作,就会使这个按钮的click信号触发,而槽是接收并处理这些信号的函数,click信号会被传递到所有“注册”(在这里使用注册这个词语来描述来自于C#)了这个信号的控件,然后由这个控件的函数进行响应,按钮本身不会关心谁“注册”了这个信号,这个信号传递给了谁。
信号和槽可以继承,也可以自定义。关键字是signals和slots,必须私有。
信号和槽的连接方式
- 一个信号与另一个信号相连
connect(Object1.SIGNAL(signal1),Object2,SIGNAL(signal2));
表示Object1的信号signal1可以触发Object2的信号signal2; - 同一个信号可以与多个槽相连
connect(Object1.SIGNAL(signal1),Object2,SLOT(slot1));
connect(Object1.SIGNAL(signal1),Object3,SLOT(slot2));
- 同一个槽可以响应多个信号
connect(Object1.SIGNAL(signal1),Object3,SLOT(slot1));
connect(Object2.SIGNAL(signal2),Object3,SLOT(slot1));
注意
-
SIGNAL()和()SLOT()是Qt定义的两个宏,他们返回其参数的C语言风格的字符串(const *char),因此下面的两个语句是相同的:
connect(Object2.SIGNAL(clicked()),Object3,SLOT(functionA()));
connect(Object2."clicked()",Object3,"functionA()");
-
在connect()函数的的官方帮助文档这样写道:
Note that the signal and slots parameters must not contain any variable names, only the type. E.g. the following would not work and return false:
//WRONG QObject::connect(scrollBar,SIGNAL(valueChanged(int value)),label, SLOT(setNum(int value)));
也就是说,不论是信号还是槽函数,在SIGNAL()和SLOT()中使用时,参数只能包含变量类型,不能包含变量名,上面的写法是错误的。
-
需要关联的信号和槽的签名必须是等同的
函数签名在C#中是这样定义的:通过函数的名称和参数定义函数的签名1;但是在C++中,应该是函数名称、函数参数类型、参数个数定义函数签名。
也就是说,信号的参数类型和参数个数与接收该信号的槽函数的参数类型和个数相同。不过,一个槽的参数个数是可以少于信号的参数个数的,但缺少的参数必须是信号参数的最后一个或几个参数,如果签名不符,编译器就会报错。
《C#入门经典》清华大学出版社(第5版)p115 ↩︎