Qt 重载槽函数后connect如何避免二义性——使用函数指针

众所周知,Qt中的信号与相应的槽函数,它们的参数列表和返回值需要完全对应。信号是没有返回值的,所以槽函数也一定没有返回值。在使用Qt的时候,可以使用重载的方法来定义信号和槽函数的多个版本,此时就会有一些冲突需要引起我们注意。

// 信号
signals:
void my_sgn();
void my_sgn(int, char*);
// 对应的槽函数
// 无参数版本槽函数
void MyWidget::mySlotFun()
{
	qDebug("no arguments");
}
// 有参数版本槽函数
void MyWidget::mySlotFun(int num, char *str)
{
	qDebug() << num << str << endl;
}

在使用connect关联重载多个版本的信号与槽函数时,如果不加以区别,编译器将无法确定该使用哪一个版本的槽函数,产生二义性,这是编译器不允许的。

// 这里的my_sgn时指mySlotFun()还是mySlotFun(int, char*)呢?
connect(&btn, &SubWidget::my_sgn, this, &MyWidget::mySlotFun);
方法一

为了解决这个问题,可以利用函数指针显式地指出信号版本(注意是指向信号,函数指针同时也要指明作用域),具体用法如下:

// 无参数版本
void (SubWidget::*pt_no_arg)() = &SubWidget::my_sgn;
connect(&btn, pt_no_arg, this, &MyWidget::mySlotFun);
//有参数版本
void (SubWidget::*ptr_have_arg)(int, char*) = &SubWidget::mySlotFun;
connect(&btn, ptr_have_arg, this, &MyWidget::mySlotFun);

如此一来,编译器就能知道信号的使用的重载版本,也就能调用相应版本的槽函数了。

方法二

Qt 4以上的版本可以使用宏SIGNAL()和SLOT()来解决这个问题,使用这种方法,注意在声明槽函数时要加上修饰符slots

class MyWidget{
  ...
public slots:
  mySlotFun();
  mySlotFun(int num, char *str);
  ...
};

class SubWidget{
  ...
signals:
  void my_sgn();
  void my_sgn(int, char*);
};
// 无参版本
connect(&btn, SIGNAL(my_sgn()), this, SLOT(mySlotFun()));
// 有参版本
connect(&btn, SIGNAL(my_sgn(int, char*)), this, SLOT(mySlotFun(int, char*)));

这一方法有一点缺陷,就是即使你写错了函数名字,在编译的时候也不会报错,而会在运行时才报错(因为该宏是将函数转换为符合C++函数名规格的字符串),而使用方法一不会有这种问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值