QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点。
信号和槽
信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言。
我感觉QT的信号和槽机制和JAVA里面的事件监听,只不过这个更简单一些,只需要一个connect函数就可以实现两个对象之间的连接。
所有从 QObject 或其子类 ( 例如 Qwidget) 派生的类都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射 (emit) 出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且,对象并不了解具体的通信机制。
我们可以把多个信号和一个槽连接,也可以把一个信号和多个槽连接,甚至可以把一个信号和另一个信号连接(这时无论第一个信号什么时候发射系统都将立刻发射第二个信号)。
槽是普通的 C++ 成员函数,可以被正常调用,它们唯一的特殊性就是很多信号可以与其相关联。当与其关联的信号被发射时,这个槽就会被调用。槽可以有参数,但槽的参数不能有缺省值。它们可以是虚函数(virtual),也可被重载(overload),可以是公有的(public),保护的(protective),也可是私有的(private)。
connect
connect函数语法如下:
connect(sender, SIGNAL(signal) , receiver, SLOT(slot) ) ;
sender和receiver是QObject对象指针,signal和slot是不带参数的函数原型。SIGNALE()和SLOT()宏的作用是把他们的参数转换成const char*类型 。
我们看看信号和槽之间连接的实现:
一个信号可以连接到多个槽:
connect(slider, SIGNAL(valueChanged(int) ) , spinBox, SLOT(setValue(int) ) ) ;
connect(slider, SIGNAL(valueChanged(int) ) , this, SLOT(updateStatusBarIndicator(int) ) ) ;
将滑块值改变的信号连接到微调框设置值大小的槽和当前对象更新状态栏的槽。
当信号发出后,槽函数都会被调用,但是调用的顺序是随机的,不确定的。
多个信号可以连接到同一个槽:
connect(lcd, SIGNAL(overflow() ) , this, SLOT(handleMathError() ) ) ;
connect(calculator, SIGNAL(divisionByZero() ) , this, SLOT(handleMathError() ) ) ;
将lcd的over()信号和计算器的divisionError()信号与当前对象的handleError()的槽连接。
任何一个信号发出,槽函数都会执行。
一个信号可以和另一个信号相连:
connect(lineEdit, SIGNAL(textChanged(const QString &) ) , this, SIGNAL(updateRecord(const QString &) ) ) ;
第一个信号发出后,第二个信号也同时发送。
信号和槽函数必须有着相同的参数类型及顺序,这样信号和槽函数才能成功连接:
connect(ftp, SIGNAL(rawCommandReply(int , const QString &)), this , SLOT(processReply(int , const QString &)));
如果信号里的参数个数多于槽函数的参数,多余的参数被忽略:
connect(ftp, SIGNAL(rawCommandReply(int, const QString &) ) ,this, SLOT(checkErrorCode(int) ) ) ;
如果参速类型不匹配,或者信号和槽不存在,应用程序在debug状态下时,Qt会在运行期间给出警告。如果信号和槽连接时包含了参数的名字,Qt也将会给出警告。