在connect中使用lambda实现高效的信号/槽关联

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 11:19   4007   0

在Qt中,使用QCoreApplication::connect()函数连接信号(signal)与槽(slots)的功能。
以下是connect函数的三种重载形式:

static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);

static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,const QObject *receiver, const QMetaMethod &method,Qt::ConnectionType type = Qt::AutoConnection);

inline QMetaObject::Connection connect(const QObject *sender, const char *signal,const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;

可以在函数声明中明显看出各个形参对应的意义,分别是[信号发送者,信号,接收者,槽],比如需要实现一个widget中点击button关闭窗口的功能,在Qt4这等老版本中,connect的写法是这样的:

connect(button,SIGNAL(QPushButton::cliked()),widget,SLOT(QWidget::close()));

每次都要添加SIGNAL/SLOT修饰符就显得很麻烦,所以在Qt5中,改进了connect的写法,可以直接用&代替修饰符

connect(button,&QPushButton::cliked,widget,&QWidget::close);

这样的写法更简洁但是有一个问题就是无法向signal/slot函数传参,只能对无参版本的信号/槽生效,所以在有参数的情况下,只能选用第一种写法。

connect函数中,还有一个重要的限制!在传参的情况下,slot函数的参数个数一定要小于等于signal函数的参数个数,这样当signal函数是clicked()这样的无参形式时,我们不能与带参数的slot函数进行关联,这就意味着:如果我们想通过点击一个按钮实现一个较为复杂的功能,而这个功能的实现必须按需将实参传入slot函数,那么用传统的connect方法时行不通的。

在Qt5的新版本中,connect函数添加了对lambda的支持!——可以用lambda替代signal/slot函数。

这一feature的引进大大简化了slot函数的实现,更自由地扩充其功能,并且可以不受signal参数的影响(因为lambda可以捕获参数)而且connect的形式也进一步精简了。

比如我希望在点击一个button时,实现数据库的更新,页面的跳转,然后页面的关闭,那么只需要这么写:

connect(button,&QPushButton::cliked,[this,new_data,new_page]{
  UpdateDatabase(new_data);
  OpenNewPage(new_page);
  close();
});

甚至连信号的接受者都不用指定了。

lambda is powerful!!!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP