Qt学习记录--02 Qt的信号槽机制介绍(含Qt5与Qt4的差别对比)

一 闲谈:编程

        熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说:一切皆消息。它能够很方便实现不一样窗体之间的通讯,然而MFC库将不少底层的消息都屏蔽了,尽管使用户更加方便、简易地处理消息,但也让人特别是没有Win32编程基的人感到迷茫,不是为什么,笔者也是深受其害的。设计模式

        详细描述就不在此展开,感兴趣的请查阅浩瀚如海的资料。。。多线程

 

二 简要介绍:函数

        基于Qt开发,信号槽是确保正常通讯的主要机制,特别是在多线程开发中,线程函数与界面的通讯是没法直接进行的,会存在程序崩溃的问题,笔者在实际开发过程当中也遇到过此问题,利用Qt的信号槽机制能够避免。this

        所谓信号槽,相似于设计模式中的观察者模式。当某一事件发生以后,好比,点击了一下PushButton,它就会发出一个信号(signal)。需注意,这种发出是没有目的的,相似广播。若是有对象对这个信号感兴趣,可使用链接(connect)函数进行二者之间的关联,即:发送者发送信号(signal),接收者(感兴趣对象)用本身的一个函数(称之为槽(slot))来处理这个信号。同观察者同样,一个signal能够关联(注册)多个slot,当信号发出时,被链接的槽函数会自动被回调。spa

        connect()函数是信号槽机制的关键,下面介绍。线程

 

三 connect()函数:设计

        Qt5与Qt4中对connect()函数的实现有所差别。指针

        首先,看Qt4对其实现的定义:code

bool connect(const QObject *, const char *,
             const QObject *, const char *,
             Qt::ConnectionType);
 
bool connect(const QObject *, const QMetaMethod &,
             const QObject *, const QMetaMethod &,
             Qt::ConnectionType);
 
bool connect(const QObject *, const char *,
             const char *,
             Qt::ConnectionType) const

介绍定义1,参数分别为:发送者sender信号signal接收者receiver槽slot,最后一个基本不用。sender 类型是const QObject *,signal 的类型是const char *,receiver 类型是const QObject *,slot 类型是const char *。这个函数将 signal 和 slot 做为字符串处理。

        Qt4使用了SIGNAL和SLOT这两个宏,将信号和槽的函数名转换成了字符串。注意,不能将全局函数或者 Lambda 表达式传入connect()。使用字符串致使了Qt4有如下缺点:一旦出现链接不成功的状况,Qt 4 是没有编译错误的(由于一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增长程序的不稳定性。

        下面,看Qt5对其实现的定义:

QMetaObject::Connection connect(const QObject *, const char *,
                                const QObject *, const char *,
                                Qt::ConnectionType);
 
QMetaObject::Connection connect(const QObject *, const QMetaMethod &,
                                const QObject *, const QMetaMethod &,
                                Qt::ConnectionType);
 
QMetaObject::Connection connect(const QObject *, const char *,
                                const char *,
                                Qt::ConnectionType) const;
 
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
                                const QObject *, PointerToMemberFunction,
                                Qt::ConnectionType)
 
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
                                Functor);

第一个,sender 类型是const QObject *,signal 的类型是const char *,receiver 类型是const QObject *,slot 类型是const char *。这个函数将 signal 和 slot 做为字符串处理,与Qt4相同,应该是为了兼容性而予以保留的。

        第二个,sender 和 receiver 一样是const QObject *,可是 signal 和 slot 都是const QMetaMethod &。咱们能够将每一个函数看作是QMetaMethod的子类。所以,这种写法可使用QMetaMethod进行类型比对。

        第三个,sender 一样是const QObject *,signal 和 slot 一样是const char *,可是却缺乏了 receiver。这个函数实际上是将 this 指针做为 receiver,与Qt4相同,应该是为了兼容性而予以保留的。

        第四个,sender 和 receiver 也都存在,都是const QObject *,可是 signal 和 slot 类型则是PointerToMemberFunction。看这个名字就应该知道,这是指向成员函数的指针。

       第五个,前面两个参数没有什么不一样,最后一个参数是Functor类型。这个类型能够接受static 函数、全局函数以及 Lambda 表达式。

       Qt5相比较于Qt4的优点是添加了第4和第5种的重载形式,使得Qt能够在编译期进行错误检查,及早发现问题。

相关文章
相关标签/搜索