首先看一个简单的用到信号与槽的程序。
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton *button = new QPushButton("Quit");
QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
button->show();
return app.exec();
}
关于此程序的几点解析:
1、关于头文件
和普通的C++程序没有什么两样,如果要使用某个组件,就必须要引入相应的头文件,这类似于Java的import机制。值得说明的是,Qt中头文件和类名是一致的。也就是说,如果你要使用某个类的话,它的类名就是它的头文件名。
2、创建对象
创建一个QApplication对象。这个对象用于管理应用程序级别的资源。QApplication的构造函数要求两个参数,分别来自main的那两个参数,因此,Qt在一定程度上是支持命令行参数的。
创建一个QPushButton 对象,并且能够显示字符串。和其他库的控件一样,这是用来接受用户动作并可以显示文本的。在Qt中,这被称为一个widget,它等同于Windows技术里面的控件(controls)和容器(containers)。也就是说,widget可以放置其他的widget,就像Swing的组件。大多数Qt程序使用QMainWindow或者QDialog作为顶级组件,但Qt并不强制要求这点。
提醒:在一个Qt源代码中,一下两条语句是必不可少的:
QApplication app(argc, argv);
//...
return app.exec();
Then,开始正文,signal和slot
QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
这句话通过connect()语句实现了信号和槽的连接。其应该是如下样子:
connect( sender, SIGNAL(signal), receiver, SLOT(slot) );
这里的sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名。
关于信号和槽的机制:
当一个特定的事件发生时,一个或几个被指定的信号就被发射(emit),槽就是一个返回值为void的函数,如果存在一个或几个槽和该信号相连接,那在该信号被发射后,这个(些)槽(函数)就会立刻被执行。
通俗的讲信号是用户的动作,对应的槽就是程序的相应的响应动作。
而上个程序中的语句就相当于button被用户按(clicked)了一下,然后button就向周围的组件发出呐喊:我被击中了。。。
然后周围的组件一般都不会理他,除非有个和他关系(connect)的,而至于和他有关系的要做什么,没有直接要求,而是直接让他执行了一个函数quit,就这样,通过组件与函数就完成信号与槽的简单机制。
然后,关于信号和槽的联系接收:
上面的示例是单个信号和槽的连接,而其实也可以
把几个信号连接在同一个槽上,这样任何一个信号被发射都会使得该槽被执行;
把一个信号和多个槽连接在一起,这样该信号一旦被发射,与之相连接的槽都会马上执行,但执行的顺序不确定,也不可以指定;把一个信号和另一个信号进行连接,这样,只要第一个信号被发射,第二个信号立刻 就被发射。
还可以移除连接disconnect。(但是很少用,因为在删除对象的时候,Qt会自动取消与之相关的所有连接)
信号和槽的机制是类型安全的:一个信号的签名必须与它的接收槽的签名相匹配。
(实际上一个槽的签名可以比它接收的信号的签名少,因为它可以忽略额外的签名。)所谓的签名就是指他们的参数(类型与数量)
ok,暂时领会的就这么多。。。