qt connect函数_Qt 如何 QObject::connect() 一个被重载的信号

为了测试Qt中的TCP通信,我用到了Qt里的 QTcpSocket,写了段非常简单的测试代码。

其中遇到了点麻烦。

在对 QTcpSocket 写测试代码时,想 connect QTcpSocket 的 error 信号时会出错。

如下:

4f7718fef8603e68f5f16ee4def9afbd.png

原因是 QTcpSocket 除了有一个信号叫 error(),还有一个 error() 的成员函数也叫这个。
它们是重载函数。

问题的关键是:QObject::connect() 函数无法根据后面 function 的参数类型来知晓 第二个参数中的 error 到底是指的这两个函数中的哪一个。

于是,我写了一个测试工程。

my_class.h

#ifndef MY_CLASS_H
#define MY_CLASS_H

#include <QDebug>

class Sender : public QObject {
   Q_OBJECT

  public:
  signals:
    void overloadEvent(int a);        //! 重载的信号
    void overloadEvent(QString a);    //! 重载的信号
    void normalEvent(int a);
};

class Receiver : public QObject {
  Q_OBJECT
  public slots:
    void onEvent(int a) {
      qDebug() << "event:" << a;
    }
    void onEvent(QString a) {
      qDebug() << "event:" << a;
    }
};

#endif // MY_CLASS_H

定义了两个类:一个是 Sender类,它有三个信号。其中 overloadEvent 信号是两个被重载的函数。而 normalEvent 则没有被重载。

另一个是 Receiver 类中只定义了两个 slots,分别对应 Sender 的两种信号。

main.cpp

#include "my_class.h"

int main()
{
  Sender s;
  Receiver r;

  QObject::connect(&s, SIGNAL(overloadEvent(int)), &r, SLOT(onEvent(int)));            //!(1)
  QObject::connect(&s, SIGNAL(overloadEvent(QString)), &r, SLOT(onEvent(QString)));    //!(2)

  QObject::connect(&s, &Sender::normalEvent, [](int a) {    //!(3)
    qDebug() << "lambda1:" << a;
  });

  QObject::connect(&s, &Sender::overloadEvent, [](int a) {    //!(4)
    qDebug() << "lambda2:" << a;
  });

  s.overloadEvent(12);
  s.overloadEvent("Hello world");
  return 0;
}

上述代码中,(1)(2)(3)处均正常。

唯有(4)红色部分代码是编译不过的,提示:

6bfda00f81a6bb5d0dbee726db8acc53.png

也就是,这么写是没有参数信息的。它不知道具体使用的是两个重载函数的哪一个。

为什么(1)(2)正常呢?因为它们是使用的这个 QObject::connect() 函数:

7386f3101d925fdc8feb931839c1dc18.png

因为 (1)(2)使用的是 第1个函数。而(4)是使用的 第2个函数。

为了指定具体是哪一个函数,可以曲线救国一下:

a76c19bacf7a46df9cfb5fd193eedd8c.png

在 L21,先定义一个函数指针 func,将 &Sender::overloadEvent 赋值给它。这个过程 func 得到的就是 overloadEvent(int),而不是 overloadEvent(QString)。

然后在 L22,使用 func 作为 QObject::connect() 的第二个参数。

我们可以进一步简化一下,直接使用强制转换:

7830db4e79ce4693de3df2434966dd44.png

这样一步到位。
测试结果符合我们的预期。

修改后的完整 main.cpp 代码:

#include "my_class.h"

int main()
{
  Sender s;
  Receiver r;

  QObject::connect(&s, SIGNAL(overloadEvent(int)), &r, SLOT(onEvent(int)));
  QObject::connect(&s, SIGNAL(overloadEvent(QString)), &r, SLOT(onEvent(QString)));

  QObject::connect(&s, &Sender::normalEvent, [](int a) {
    qDebug() << "lambda1:" << a;
  });

  QObject::connect(&s, (void(Sender::*)(int))(&Sender::overloadEvent), [](int a) {
    qDebug() << "lambda4:" << a;
  });

  QObject::connect(&s, (void(Sender::*)(QString))(&Sender::overloadEvent), [](QString a) {
    qDebug() << "lambda4:" << a;
  });

  s.overloadEvent(12);
  s.overloadEvent("Hello world");
  return 0;
}

运行结果:

7494cd37e37c9a066b8f53c3ef9ac075.png

所以最前面 QTcpSocket 的例子,应该写成:

ef9d879c457fcbc297dc6ff2437e64b8.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值