Qt与其他编程语言或则软件开发套间在线程上的使用上有很大的不同。
Qt使用了一种叫信号与槽的机制(技术),拓展了程序块之间的事件触发方式。
一种典型的使用方式是用于子窗口和父窗口的信息传递。假设主窗口W1和它的一个子窗口W2,如果说W2中发生了某件事,而根据逻辑需要改变主窗口的某些属性,一种典型的处理方式是获取父窗口指针进行修改,那如果要修改爷爷窗口呢?如果要修改叔叔窗口呢?这个时候就凸显出信号与槽机制的优势了。
信号与槽有3个要素,信号、槽函数、连接。
信号:一种特殊的函数,没有函数实现,只需要定义,定义的区域有要求,需要定义在类的signal区域表示这是一个信号,比如signal:void start();void end(int);。
槽函数:一种特殊的函数,就是应该做的这件事,是信号的处理函数。同时也可以当做普通函数来使用。需要定义在slots函数区域,表示这是一个槽函数。
连接:为一个对象的一个信号分配一个对象的一个槽函数,一旦执行了连接操作那信号和槽函数之间就绑定在了一起,发送对象无论在哪里发出这个信号,接收者的响应槽函数就是会被执行。注意绑定是两个对象之间的事情,而不是类之间。格式是connect(发送对象的指针,信号,接收对象的指针,槽函数);如果在前面加dis就变成了接除连接的指令。
信号和槽的机制可以理解为一种事件的使用,是非常有用的,对于窗口你还可以调用父指针来调整,但是如果是比较基础的类,还用这种方法就得写个新的派生类,非常麻烦。而如果使用信号和槽的机制,一个类只需要定义一些信号行为,至于这个发生了这件事的时候要做什么,我不管,不干我事。而对于槽函数,你那边发生了什么我干嘛要知道,who care?你只要告诉我我应该执行了就行。而它们之间的逻辑关系则由连接函数实现。
注1:在使用信号和槽函数的时候不需要考虑时间错的问题,当然逻辑上可能发生的时间错还是得自己解决。
注2:信号的使用,在适当的位置emit 信号函数名(参数);emit是发送信号的关键字。
注3:连接的信号和槽的参数类型和个数需要相同才能进行连接,一般是槽函数迎合信号。
注4:连接的机制应该是发送者和接收者对象都存在的时候,在需要这个逻辑的时候,越早越好,并且在相应对象被销毁之前应该断开连接。
注5:连接函数定义在QObject里的,需要其派生类才能使用。
就先写一个简单的例子吧。
我们使用QTimer来展示信号和槽的机制,顺便学习QTimer的使用。
QTimer是Qt定义的计时器类型。
核心的函数有3个QTimer::start(int);QTimer::stop():QTimer::timeout();timeout函数为信号。
设计一个时钟类,利用QTimer计时,链接timer的timeout信号和whenTimeOut函数。当timer使用start函数以后会以你传递的数值为间隔重复产生timeout信号。
然后再窗口类中添加好刚刚写好的Clock类变量,定义槽函数等等。
添加好实现,在构造的时候启动计时器,然后将它画在窗口中。
刚刚的链接函数的信号和槽的传递使用了两种写法:
第一种:使用关键字 SIGNAL 和 SLOT对函数进行转化;
第二种:使用&,格式为&类名::信号名,注意信号名就行,不带括号。