QMetaObject::connectSlotsByName 分析

查看Qt4的一些示例项目的时候,使用设计器打开其UI文件,在文件中竟然找不到signal和slot的连接。但是最终的程序,slot却又能准确的响应信号。打开通过ui文件自动生成的c++文件,其中也找不到connect语句,到底是怎么一回事?
  
  经过逐语句的分析。终于发现连接的原因就在于setUi函数的最后一句
  
  QMetaObject::connectSlotsByName(MainWindow);
  
   找到该静态函数
  
  void QMetaObject::connectSlotsByName(QObject *o)
  {
   if (!o)
   return;
   const QMetaObject *mo = o->metaObject();
   Q_ASSERT(mo);
   const QObjectList list = qFindChildren(o, QString());
   for (int i = 0; i < mo->methodCount(); ++i) {
  
  
   const char *slot = mo->method(i).signature();
   Q_ASSERT(slot);
  
  //以下一行用来判断slot的前三位是否是on_,如果不是,就跳过这个方法。
   if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
   continue;
   bool foundIt = false;
  
  //遍历子对象。
   for(int j = 0; j < list.count(); ++j) {
   const QObject *co = list.at(j);
  
  //得到子对象名。
   QByteArray objName = co->objectName().toAscii();
   int len = objName.length();
  
  //要求slot跳过前3位(on_)后,接下来的子字符串和子对象名相同,并且接着该子字符串又是一个_
  
  //如果达不到这个要求,continue
   if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
   continue;
   const QMetaObject *smo = co->metaObject();
   int sigIndex = smo->indexOfMethod(slot + len + 4);
   if (sigIndex < 0) { // search for compatible signals
   int slotlen = qstrlen(slot + len + 4) - 1;
  
  //搜索该子对象所能引发的信号
   for (int k = 0; k < co->metaObject()->methodCount(); ++k) {
  //方法类型如果符合要求
  
   if (smo->method(k).methodType() != QMetaMethod::Signal)
   continue;
  
  //如果slot最后的子字符串和信号名相同
  
   if (!qstrncmp(smo->method(k).signature(), slot + len + 4, slotlen)) {
   sigIndex = k;
   break;
   }
   }
   }
   if (sigIndex < 0)
   continue;
  
  //连接操作
   if (QMetaObject::connect(co, sigIndex, o, i)) {
   foundIt = true;
   break;
   }
   }
  
  //连接成功
   if (foundIt) {
   // we found our slot, now skip all overloads
   while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
   ++i;
   }
  
  //连接失败
  
  else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
   qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
   }
   }
  }
  
  得出此结论:自动生成的文件中,该函数总会存在setUi函数的最后一句。
  
  该函数的作用就是寻找setUi的唯一指针参数MainWindow所指向对象的成员函数,
  
  该成员函数的名字如果满足以下条件,就做连接操作。
  
  函数名规则:on_子对象名_信号名
  
  函数签名(即返回值与参数要符合slot要求)
  
  所以,我们可以这样做:在qt设计器中添加按纽或者菜单项或者按纽项后,不用在设计器中手动做连接操作。
  
  我们只要在主窗口类中添加符合条件的成员函数即可。
  
  函数名规则:on_子对象名_信号名
  
  函数签名(即返回值与参数要符合slot要求)
  
  例如:
  
  在设计器中添加一个菜单项,其对应的action为actionNew
  
  那么在主窗口类中添加以下的函数
  
  public slots:
  
   void on_actionNew_triggered();
  
  当切换这个菜单时,会自动执行上面的成员函数。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: qmetaobject::connectslotsbyname: 找不到匹配的信号 这是Qt框架中的一个错误提示,通常是因为在使用connect函数连接信号和槽时,信号的名称拼写错误或者信号不存在。需要检查代码中的信号名称是否正确,或者是否在相应的类中定义了该信号。 ### 回答2: qmetaobject::connectslotsbyname: no matching signal for是Qt框架中的一个错误信息,通常在连接信号和槽的时候出现。这个错误信息表示无法找到与要连接的槽对应的信号。 在使用Qt框架进行信号与槽的连接时,首先我们需要明确信号和槽的名称和参数类型。当使用QMetaObject::connectSlotsByName函数连接信号和槽时,框架会通过名称进行匹配。 如果出现no matching signal for的错误,可能是以下几个原因导致的: 1. 信号或槽的名称拼写错误:请检查信号和槽的名称拼写是否一致,包括大小写。 2. 信号或槽的参数不匹配:在信号和槽的定义中,参数的类型和顺序必须一致。如果参数类型或顺序不匹配,会导致连接失败。 3. 信号或槽的定义未在moc中注册:Qt使用元对象编译器(moc)来处理信号和槽的连接,如果信号或槽的定义未在moc中注册,连接会失败。请确保信号和槽的定义在宏的作用域内,并且相应的头文件已包含了Q_OBJECT宏。 解决此问题的方法是: 1. 仔细检查信号和槽的名称和参数,确保拼写和类型一致。 2. 检查信号和槽的定义是否在moc中注册。 3. 使用新的语法进行信号和槽的连接。新的Qt语法使用函数指针而非字符串进行连接,可以避免一些连接错误。 总之,qmetaobject::connectslotsbyname: no matching signal for表示无法找到与要连接的槽对应的信号。检查信号和槽的名称、参数和定义是否正确,并确保已正确注册到moc中,可以解决此问题。 ### 回答3: QMetaObject::connectSlotsByName: no matching signal for 在Qt中,QMetaObject::connectSlotsByName是一个用于自动连接信号和槽的功能。该错误提示表示在使用该功能时,没有找到与所连接的槽函数对应的信号函数。 通常情况下,这个错误有以下几个可能的原因: 1. 信号函数名称拼写错误:请检查信号函数的名称是否拼写正确。信号和槽函数的名称必须完全一致,包括大小写。 2. 信号函数没有声明在QObject的派生类中:请确保信号函数是在QObject的派生类中声明的。只有QObject的派生类才能包含信号函数和槽函数。 3. 在信号函数中需要添加Q_INVOKABLE宏:如果信号函数是在QObject的派生类的private或protected部分中声明的,那么需要添加Q_INVOKABLE宏来标记该函数为可调用的。 4. 在Q_OBJECT宏中声明了信号函数,但是没有重新生成moc文件:如果在信号函数中使用了Q_OBJECT宏并且编译器没有重新生成moc文件,那么信号函数将无法被识别。这种情况下,需要清理并重新生成工程。 总之,QMetaObject::connectSlotsByName: no matching signal for错误提示表示在使用QMetaObject::connectSlotsByName连接信号和槽时,没有找到与要连接的槽函数对应的信号函数。根据具体情况,可以通过检查函数的名称拼写、所在类的声明、添加Q_INVOKABLE宏或重新生成moc文件等方式来解决该问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值