Qtsignal函数使用类内部类型作为参数导致connect不成功的原因是什么

这篇文章主要介绍“Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么”,在日常操作中,相信很多人在Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于网站建设、网站设计、鲤城网络推广、重庆小程序开发公司、鲤城网络营销、鲤城企业策划、鲤城品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联公司为所有大学生创业者提供鲤城建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com

问题代码:

sender.h

class Sender : public QObject
{
  Q_OBJECT
  public:
    explicit Sender(QObject *parent = nullptr);
    enum eResult {
      kSuccess,
      kFail,
    };
  signals:
    void loginResult(eResult result);
    void otherSignal(QString str);
};

定义了两个信号:

  • loginResult() 这个信号采用 eResult 作为参数,而 eResult 是 Sender 类内部定义的类型;

  • otherSignal() 作为参照,使用Qt所定义的类型的信号。

receiver.h

class Receiver : public QObject
{
    Q_OBJECT
  public:
    explicit Receiver(QObject *parent = nullptr);

  signals:
  public slots:
    void onLoginResult(Sender::eResult result);
    void onOtherSignal(QString str);

  private:
    Sender *sender_;
};

在 Receiver 中定义了两个slot分别接收 Sender 的两个信号。

在 Receiver 的构造函数中:

Receiver::Receiver(QObject *parent)
  : QObject(parent)
  , sender_(new Sender())
{
  connect(sender_, SIGNAL(loginResult(Sender::eResult)), this, SLOT(onLoginResult(Sender::eResult)));
  connect(sender_, SIGNAL(otherSignal(QString)), this, SLOT(onOtherSignal(QString)));
}

结果在运行时报错:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

提示信号没有连接上。

如果我们将 eResult 放到 Sender 类外面,则没有这个问题。

这是为什么呢?

是不是只要是类内部的类型都会出错?

为了排除是我们自定义的枚举的原因,我们把自己定义的 eResult 改成 MyString,其它也对应改过来。

再试:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

结果还是报错:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

这也证定了我的猜想。为是什么呢?

打开自动生成的 moc_sender.cpp 文件看看里面的内容:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

如果我们再加一个signal:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

moc_sender.cpp 中会发生什么样的变化呢?

(1)字面量里多出两个新的字面量。

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

(2)在 qt_meta_data_Sender 中也多出些新的描述:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

可以看出,qt_meta_data_Sender 中可以描述出一个 QObject 类有哪些信号函数。每个信号函数的返回类型与参数各为什么。

从上可以看到,qt_meta_data_Sender 中记录的信号自定义的参数类型idx指向的是 MyString。我们在 Receiver 中 connect() 使用的是 Sender::MyString。会不会是两者对不上号导致的呢?

如果我们改成这样:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

把 Sender:: 前缀加上。

看看会不会成功了呢?结果没有再报错了。

我们再来看看 moc_sender.cpp 的变化:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

猜想:

在下面的 connect() 代码中:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

SIGNAL() 宏把  Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么 预编译成 "loginResult(Sender::MyString)" 的字符串。在执行时,就会拿着该字串去 Sender 对象中找信号名为 "loginResult" 参数个数只有一个,参数类型名为 "Sender::MyString" 的信号进行连接。

如果我们在 Sender 中将 loginResult 信号的参数类型写成 MyString 而不是写全 Sender::MyString,那么在 connect() 时,它就不能在 Sender 的 qt_meta_data_Sender 中找到这个信号,所以就失败了。

如果我们还是采用原来的做法:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

而在 connect() 的地方,直接写 MyString,而不写成 Sender::MyString,如下:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

执行报错:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

说是不兼容的参数类型。

可能 connect() 函数在入口处,就对参数signal与slot的参数类型字串进行比较,如果不一致,那么就会认为错误。

那反过来,我们在 connect() 时将 slot 的参数写成:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

执行结果:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

如果我们把 Receive::onLoginResult() 的参数类型改成 MyString 呢?

如下:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么 

编译通过,运行时 connect() 正常。

是不是它只认类型的名称,不做类型推导呢?

我们大胆地做一个尝试:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

我们给 MyString 乱指定一个类型。

结果编译通过,运行时 connect() 正常。

从本质上 MyString 就是 QString 的别名。

如果在 Receive 端使用 QString 替代 MyString 是不是就不能 connect() 成功了呢?

如下修改:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

编译正常,运行结果:

Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么

这个实验足于证明,connect() 只管类型名称的比效,完全不做任何的类型推导。

综上结论:

在执行 QObject::connect() 时,它会对signal与slot参数的名称进行对比,只有名称完会一致的才能连接上,否会不失败。

值得注意的是:它只管对类型的名称进行比较,完全不会做任何的类型推导与类型检查。

到此,关于“Qt signal函数使用类内部类型作为参数导致connect不成功的原因是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!

网页名称:Qtsignal函数使用类内部类型作为参数导致connect不成功的原因是什么
文章源于:https://www.cdcxhl.com/article16/jjgedg.html

成都网站建设公司_创新互联,为您提供品牌网站建设做网站网站维护关键词优化品牌网站设计企业网站制作

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

h5响应式网站建设