Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

二 简要介绍:

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

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

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


三 connect()函数:

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

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

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可以在编译期进行错误检查,及早发现问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值