Qt 信号与槽
在GUI编程中,常常碰到触发控件,引发事件的情况。比如Android中的监听器 listener 和 callback 回调函数。
在Qt中,相似地,将一个信号发射到一个槽中,就可以做相应的操作。
信号与槽简介:
信号(SIGNALS):
信号是一个特殊的函数,你只用定义它的形參列表,不用提供实现,因为Qt的moc工具会帮你实现。信号都不用自己实现。
槽(SLOTS):
槽是一个普通的成员函数,唯一“不普通”的地方就是 它的调用方法除了像普通函数那样直接调用它以外,如果相应的信号发射过来了,它也会自动执行。自定义的槽需要自己实现。
信号与槽的连接:
信号和槽的参数列表中的参数要一一对应,参数类型也不能写错。允许槽的参数个数少于信号的。这样一来,槽就会相应地忽略掉其他参数。一个信号可以连接多个槽,多个信号可以连接一个槽,一个信号还能和另外一个信号连接(发射一个信号时,另外一个也跟着发射),连接是可以用disconnect来移除的。
更多:
对于所有定义了信号与槽的类,在类定义的开始处需要添加Q_OBJECT宏,moc工具看到这个就会去解析,把信号和槽的实现解析成标准的C++代码。(包括实现信号函数和connect函数等等) 更详细地可以去了解Qt的“元对象系统”,阅读有关QMetaObject类的文档,看看由moc生成的C++ 源代码文件 (在你的project目录中,文件名通常为moc_xxx。xxx是你定义了信号和槽的类文件名)。
信号和槽的机制,不仅仅局限于GUI编程中,可以用于任何QObject的子类中 ! 当然,为达到这个地步,必须要高度封装。刚学那会儿,发现标准库中的string类在Qt中竟然有一个对应的QString类,真是满头黑线。
对使用Qt Designer设计的界面,加入信号和槽:
1. 使用自带的功能:
点击控件,右键“加到槽”并选择信号。然后,Qt就会自动在你的界面头文件中加入私有槽定义。并且在界面源文件处提供空函数体的槽函数,自己实现便可。
2. 自己编写代码:
在界面的头文件声明槽,在源文件处实现槽。注意槽函数的命名最好遵循规范,像这样: on_objectName_SIGNAL(parameter list)。这样做,有一个好处,就是moc工具会根据你的命名确定 sender、signal、receiver、slot,从而会帮你生成一个connect函数。这样一来,就避免了你忘记调用connect函数,导致该触发的事件没触发的现象了。少写点代码也少点错误。当然了,你可以不这样命名,但是就要自己写好connect调用了 !
一个例子,其中定义为我的界面类 gotocell 中的一个按钮“cancelButton”的clicked信号绑定了一个槽--on_cancelButton_clicked()
#include "gotocell.h" #include "ui_gotocell.h" gotocell::gotocell(QWidget *parent) : QMainWindow(parent), ui(new Ui::gotocell) { ui->setupUi(this); //connect(Ui_gotocell::cancelButton,SIGNAL(clicked()),this,SLOT(close())); } gotocell::~gotocell() { delete ui; } void gotocell::on_cancelButton_clicked() { this->close(); }
也可以自己定义信号,这个就自己摸索吧。
下面有两个链接,可以进一步了解更深入的东西: