对QT信号与槽机制的进一步理解
在QT中信号与槽用得十分广泛,比如单击窗口上一个按钮然后弹出一个对话框,那么就可以将这个按钮的单击信号和自定义的槽关联起来,信号是按钮的单击信号,槽实现了创建一个对话框并显示的功能。
从另一个角度来看,信号与槽就是实现对象之间通信的一种机制,但是在其他语言中也曾学到过通过回调机制来实现对象之间的通信,那么同样是为了实现对象之间通信的功能,这两种机制有何不同呢?
首先来理解一下回调的概念,所谓回调,就是把一个指向函数的指针传递给调用方,但是主要存在两个缺陷:第一,不是类型安全的,不能保证在调用回调函数时可以使用正确的参数;第二,是强耦合的,调用方必须知道调用哪个回调函数。
Qt引入了信号和槽机制来取代回调函数。凡是继承自QObject的类都可以具有信号和槽成员,并可以使用它们。信号和槽的使用可以有效地减少函数指针的使用,使程序代码清晰简洁,对于事件响应管理更加容易。此外,信号和槽没有严格规定函数的类型,因此在调用过程中是安全的。
信号和槽的使用可以实现信息封装,增加程序的灵活性。信号和槽都采用函数作为存在形式。在Qt程序初始化或运行的过程中,可以静态或动态地将信号和槽相关联。当某一事件到来时,会发射信号,但是发射后,它并不需要关心信号的处理者是谁。当触发槽函数时,说明与其关联的信号被接收,但它不需要了解谁发出了信号,它只需要负责进行相应的处理即可。
接下来是通过一些例子来对信号与槽这一知识的应用,首先在mywiget.h文件中加入槽的声明,在mywiget.cpp文件中写具体函数的实现,之后利用connect(sender, SIGNAL(signal), receiver, SLOT(slot))函数将信号与槽关联起来,其中sender和receiver是对象的指针,SIGNAL和SLOT是信号和槽相应的函数。
(1)mywidget.h文件中
(2)mywidget.cpp
(3)main.cpp
运行结果如下所示:
关于信号与槽的连接还可以通过自动连接的方法,将槽重命名为on_myButton_clicke()即可。
同时可以通过disconnect函数来断开信号与槽的关联。断开通常用于以下三种方式:
(1)断开所有连接到该对象的信号
disconnect(myObject, 0, 0, 0);
(2)断开一切连接到特定信号:
disconnect(myObject, &MyObject::mySignal(), 0, 0);
(3)断开一个特定的接收者:
disconnect(myObject, 0, myReceiver, 0);
(4)断开一个特定信号到特定槽的连接:
QObject::disconnect(lineEdit, &QLineEdit::textChanged, label, &QLabel::setText);
总之,QT信号与槽具有其自己特有的优越性主要体现在:
(1)信号与槽机制是类型安全的,相关联的信号与槽的参数必须匹配。
(2)信号与槽是松耦合的,信号发送者不知道也不需要知道接收者的信息。
(3)信号与槽可以使用任意类型的任意数量的参数。