Qt信号与槽如何给槽函数传参

省流:Lambda表达式

    connect(按钮,&QPushButton::clicked,接收器的地址,[=](){接收器的地址->函数(参数);});
	//例子
    connect(B_life,&QPushButton::clicked,player_info_,[=](){player_info_->life_change(1);});

正文:

本人作为初学Qt的小白,想要做个简单的小游戏,游戏中要设置两个按钮,一个是“疗伤”:生命值+1;一个是“攻击”:生命值-1;
于是我先声明了一个“玩家信息”类,定义了一个“生命值改变”的函数:

#include <QObject>
class Player_Info:public QObject{
    Q_OBJECT
public:
    Player_Info(QObject* parent,int* life);
    int* life;		//设置初始生命值
    void life_change(int a);		//“生命值改变”的函数
};

void life_change(int a);的具体实现如下:若传入a=1,则生命值+1,若传入a=-1,则生命值-1

void Player_Info::life_change(int a){
    *life+=a;		//若传入a=1,则生命值+1,若传入a=-1,则生命值-1
}

然后天真的小白用信号与槽写下了这行代码

Player_Model::Player_Model(QWidget* parent){
B_life=new QPushButton("疗伤",this);	//创建一个"疗伤"的按钮
connect(B_life,&QPushButton::clicked,player_info_,player_info_->life_change(1));	//错误写法
}

我的想法是,点击按钮后,触发life_change()函数,并给它传入参数1,使生命值+1。问题就出在传入参数。
connect()的参数只能是地址,也就是这样:
connect(触发器的地址,信号函数的地址,接收器的地址,槽函数的地址)
也就是说你只能往槽函数的位置放一个函数地址,程序也只能识别到地址,识别不到参数,那么参数放哪呢?不好意思放不了。
也就是说我的life_change(1)根本没法直接实现,唯一的办法就是再定义一个函数

void Player_Info::life_increate(){ life_change(1); }

然后把这个函数的地址放在connect()槽函数的位置
然而这样极其的麻烦,如果我要让生命值+1,生命值+2,生命值+3,每实现一个功能我就要多写一个函数。
如何解决呢?有一个快捷新建函数的办法:Lambda函数表达式
于是有了下面的写法:

    connect(B_life,&QPushButton::clicked,player_info_,[=](){player_info_->life_change(1);});

虽然说还是创建了一个新函数,但是工作量明显少了很多,半完美解决!


但注意,这个方法有个巨坑,或者说是Lambda表达式的坑

就是不要在Lambda表达式里修改临时变量
比如这样写:

Player_Model::Player_Model(QWidget* parent){
B_life=new QPushButton("疗伤",this);	//创建一个"疗伤"的按钮
int life=3;
connect(B_life,&QPushButton::clicked,player_info_,[=](){life+=1;});
}

因为当这段代码执行完后,B_life按钮与[=](){life+=1;}函数的连接会被创建,但life作为一个局部变量会被销毁,此时如果你点击按钮,就会报错。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白草遥遥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值