qt ui设计界面 创建信号与槽 原理,

简介: 在ui设计界面,设计信号和槽时,会把信息存在ui文件中,在编译时会在成成的头文件**.h 中把连接代码加上。 ui界面添加信号和槽有两种方法 第一种: 在界面选择操作对象-》右键-》转到槽-》选择信号-》qtCreator 自动生成 槽方法-》编写槽方法。此方法在ui文件中并不会保存响应信号与槽信息,因为它生成的槽格式固定,如on_countBtn_clicked。在编译时加入QMet

在ui设计界面,设计信号和槽时,会把信息存在ui文件中,在编译时会在成成的头文件**.h 中把连接代码加上。

ui界面添加信号和槽有两种方法

第一种: 在界面选择操作对象-》右键-》转到槽-》选择信号-》qtCreator 自动生成 槽方法-》编写槽方法。此方法在ui文件中并不会保存响应信号与槽信息,因为它生成的槽格式固定,如on_countBtn_clicked。在编译时加入QMetaObject::connectSlotsByName(MainWindow);方法就可以自动按照 方法名 映射为相应的connect。

第二种 :在编辑界面下方


此方法会在ui文件中生成 相应的connect 信息,在编译时,会在**.h头文件中加入

 connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea()));方法。
 
 
 
以下为第一种方法原理说明

查看Qt5的一些示例项目的时候,使用设计器打开其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();
  
  当切换这个菜单时,会自动执行上面的成员函数。
目录
相关文章
|
19天前
|
安全 Linux Nacos
如何使用公网地址远程访问内网Nacos UI界面查看注册服务
如何使用公网地址远程访问内网Nacos UI界面查看注册服务
45 0
|
2天前
|
安全 C++ Windows
Qt信号与槽机制
Qt信号与槽机制
10 1
|
5天前
|
搜索推荐
【qt】自定义界面类
【qt】自定义界面类
8 0
|
6天前
|
JavaScript API
鸿蒙开发接口UI界面:【@ohos.mediaquery (媒体查询)】
鸿蒙开发接口UI界面:【@ohos.mediaquery (媒体查询)】
11 1
|
19天前
|
Web App开发 开发框架 前端开发
Open UI5 前端开发框架配套的 Mock Server 工作原理解析
Open UI5 前端开发框架配套的 Mock Server 工作原理解析
33 0
Qt 窗口常用位置API函数 & 绘图原理 & 双缓冲机制 总结
Qt 窗口常用位置API函数 & 绘图原理 & 双缓冲机制 总结
|
19天前
|
区块链
【qt】最快的开发界面效率——混合编程3
【qt】最快的开发界面效率——混合编程
25 1
|
19天前
【qt】最快的开发界面效率——混合编程2
【qt】最快的开发界面效率——混合编程
25 1
|
19天前
【qt】最快的开发界面效率——混合编程1
【qt】最快的开发界面效率——混合编程
30 0
|
19天前
【qt】设计器实现界面
【qt】设计器实现界面
12 1