信号槽

38 篇文章 1 订阅
32 篇文章 0 订阅

信号槽是 Qt 框架引以为豪的机制之一。熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力。

所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,用自己的一个函数(成为槽(slot))来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。(这里提一句,Qt 的信号槽使用了额外的处理来实现,并不是 GoF 经典的观察者模式的实现方式。

简单的按钮代码:

#include "qttest.h"
#include <QtWidgets/QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QPushButton  button("Quit"); 
QObject::connect(&button,&QPushButton::clicked,&QApplication::quit);
button.show();
return app.exec();
}

按钮在 Qt 中被称为QPushButton。对它的创建和显示,同前文类似,这里不做过多的讲解。我们这里要仔细分析QObject::connect()这个函数。

在 Qt 5 中,QObject::connect()有五个重载:

 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);

QT4 的三个Connect重载函数 

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


#include <QApplication>
#include <QPushButton>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
#ifdef DEBUG
// QT5
QPushButton button("Quit");
QObject::connect(&button, &QPushButton::clicked, [](bool) {
qDebug() << "You clicked me!";
});
button.show();
#else
// QT4 
QPushButton button("Quit");
QObject::connect(&button, SIGNAL(clicked()),
&app,    SLOT(quit()));
button.show();
#endif

return app.exec();
}

在QT4中使用了SIGNALSLOT这两个宏,将两个函数名转换成了字符串。注意,即使quit()QApplication的 static 函数,也必须传入一个对象指针。这也是 Qt 4 的信号槽语法的局限之处。另外,注意到connect()函数的 signal 和 slot 都是接受字符串,因此,不能将全局函数或者 Lambda 表达式传入connect()。一旦出现连接不成功的情况,Qt 4 是没有编译错误的(因为一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值