转载自【http://blog.csdn.net/liang19890820/article/details/52118210

简述

在Qt编程过程中,通常会有多个部件嵌套,而大多数部件都有父子依赖关系,但是有些情况下不能直接引用子部件,这时我们可以通过父部件来findChild -“查找孩子”。

查找选项

  • 枚举Qt::FindChildOption:

Qt::FindChildOptions是一个QFlags<FindChildOption>类型定义,它存储一个或FindChildOption的组合值。

常量 描述
Qt::FindDirectChildrenOnly 0x0 查找object的直接孩子
Qt::FindChildrenRecursively 0x1 查找object的所有孩子(递归搜索)

findChild

描述

返回对象中类型可以转换为T,并且名为name的孩子。如果不满足条件,则返回0。默认执行递归搜索,除非指定选FindDirectChildrenOnly。

T QObject::findChild(const QString & name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
  • 1

如果有一个以上的孩子匹配搜索,返回最直接的祖先。如果有几个直系祖先,没有定义哪一个将被返回。这种情况下,应该使用findChildren()。

示例

这个示例,返回parentWidget中一个名为“button1”的QPushButton孩子,即使按钮不是父亲的直接孩子:

QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
  • 1

这个示例,返回parentWidget中的一个QListWidget孩子:

QListWidget *list = parentWidget->findChild<QListWidget *>();
  • 1

这个示例,返回parentWidget(它的直接父亲)中一个名为“button1”的QPushButton孩子:

QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildrenOnly);
  • 1

这个示例,返回parentWidget(它的直接父亲)中的一个QListWidget孩子:

QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildrenOnly);
  • 1

我们不妨来分析一下!

分析

假如我们有一个主界面,主界面上有一个文本为“Parent”的QGroupBox,“Parent”中包含了两个部件及另外一个文本为“Child”的QGroupBox,“Child”中包含了另外两个部件,它们之间的关系如下:

用程序实现一下,大概就是下面这个效果。

效果

源码

// 构建部件
QGroupBox *parentWidget = new QGroupBox(this);
QGroupBox *subWidget = new QGroupBox(this); QCheckBox *pCheckBox1 = new QCheckBox(parentWidget);
QCheckBox *pCheckBox2 = new QCheckBox(parentWidget);
QCheckBox *pCheckBox3 = new QCheckBox(subWidget);
QCheckBox *pCheckBox4 = new QCheckBox(subWidget); //设置标题
parentWidget->setTitle("Parent");
subWidget->setTitle("Child"); // 设置文本
pCheckBox1->setText("CheckBox1");
pCheckBox2->setText("CheckBox2");
pCheckBox3->setText("CheckBox3");
pCheckBox4->setText("CheckBox4"); // 设置objectName
pCheckBox1->setObjectName("name");
pCheckBox2->setObjectName("name1");
pCheckBox3->setObjectName("name");
pCheckBox4->setObjectName("name2"); // 为subWidget设置布局,这时pCheckBox3、pCheckBox4均为它的孩子
QVBoxLayout *pSubLayout = new QVBoxLayout();
pSubLayout->addWidget(pCheckBox3);
pSubLayout->addWidget(pCheckBox4);
pSubLayout->setSpacing(10);
pSubLayout->setContentsMargins(10, 10, 10, 10);
subWidget->setLayout(pSubLayout); // 为parentWidget设置布局,这时pCheckBox1、pCheckBox2、以及subWidget均为它的孩子。
QVBoxLayout *pLayout = new QVBoxLayout();
pLayout->addWidget(pCheckBox1);
pLayout->addWidget(pCheckBox2);
pLayout->addWidget(subWidget);
pLayout->setSpacing(10);
pLayout->setContentsMargins(10, 10, 10, 10);
parentWidget->setLayout(pLayout);

到这里,如果对父子级联关系还有问题,你不妨可以调试一下看看:

qDebug() << parentWidget;
qDebug() << checkBox1->parent();
qDebug() << checkBox2->parent();
qDebug() << subWidget->parent(); qDebug() << "******************"; qDebug() << subWidget;
qDebug() << checkBox3->parentWidget();
qDebug() << checkBox4->parentWidget();

输出如下:

QGroupBox(0x802778)
QGroupBox(0x802778)
QGroupBox(0x802778)
QGroupBox(0x802778)
******************
QGroupBox(0x802a90)
QGroupBox(0x802a90)
QGroupBox(0x802a90)

这说明什么情况?很显然:

  • checkBox3、checkBox4的直接父亲是subWidget。
  • checkBox1、checkBox2、subWidget的直接父亲是parentWidget。

由此可以确定,parentWidget是checkBox3、checkBox4的爷爷(祖先),O(∩_∩)O~。

可能情况

  • 返回NULL

    • 不能转换为类型T - 与Qt::FindChildOption取值无关。
    QPushButton *button = parentWidget->findChild<QPushButton *>();
    • 1

    parentWidget所有子孙部件中包含QGroupBox和QCheckBox,但是并没有QPushButton,所以无论是否递归搜索,均返回NULL。

    • 可以转换为类型T,但是对应的name不存在 - 与Qt::FindChildOption取值无关。
    QCheckBox *checkBox = parentWidget->findChild<QCheckBox *>("Qt");
    • 1

    parentWidget上有QCheckBox,但是没有名为“Qt”的,所以无论是否递归搜索,均返回NULL。

    • 可以转换为类型T,对应的name也存在(非直接孩子) - Qt::FindChildOption取值为Qt::FindDirectChildrenOnly。
    QCheckBox *checkBox = parentWidget->findChild<QCheckBox *>("name2", Qt::FindDirectChildrenOnly);
    • 1

    parentWidget上有名为“name2”的QCheckBox,但是由于采用了Qt::FindDirectChildrenOnly,只会查找直接孩子,而直接孩子中只有名为“name”和“name1”的QCheckBox,所以返回NULL。

  • 返回非NULL

    硬性条件:

    1.可以转换为类型T。 
    2.对应的name存在(如果name为空字符串,此条件可忽略,只需要参考1)。

    • Qt::FindChildOption取值为Qt::FindChildrenRecursively。
    QCheckBox *checkBox1 = parentWidget->findChild<QCheckBox *>("name1");
    QCheckBox *checkBox2 = parentWidget->findChild<QCheckBox *>("name2");
    • 1
    • 2

    由于递归查找,当发现孩子中存在符合要求的就会终止,由于直接孩子中存在名为“name1”的QCheckBox,所以checkBox1表示文本为“CheckBox2”的QCheckBox;由于子孙孩子中存在名为“name2”的QCheckBox,所以checkBox2表示文本为“CheckBox4”的QCheckBox。

    • Qt::FindChildOption取值为Qt::FindDirectChildrenOnly。
    QCheckBox *checkBox = parentWidget->findChild<QCheckBox *>("name", Qt::FindDirectChildrenOnly);
    • 1

    由于采用了Qt::FindDirectChildrenOnly,只会查找parentWidget的直接孩子,直接孩子中存在名为“name”的QCheckBox,所以返回文本为“CheckBox1”的QCheckBox。

注意:

  1. 理解直接与非直接孩子的区别与关系(可以想象一下血缘关系)。
  2. name是按照objectName()来查找的,并不是text(),切勿搞错。

Qt查找孩子findChild的更多相关文章

  1. JS查找孩子节点

    以前看了JS方面的书,如今用到了,书看得再多,不用就忘了,所以经常用用你所学到的知识,温故知新. <!DOCTYPE html> <html> <head> < ...

  2. Qt 查找功能

    版权声明 该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处!     导语 这一篇我们来加上查找菜单的功能.因为要涉及Qt Creator的很多实用功 ...

  3. 通过QT查找Word中的关键字,并做高亮或删除操作

    最近由于项目需要,要用QT操作Word文档.具体的工作需求:在指定的Word文档(*.doc文件/*.docx文件)中查找关键字,找到后做高亮操作或者直接删除操作,然后另存为到别的目录(表示这个文件被 ...

  4. qt查找框设置

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7229129.html 主界面弹出查找框方法,查找框显示在主界面上层,并还可以点击主界面,非模态. class ...

  5. Qt之findChild

    简述 在Qt编程过程中,通常会有多个部件嵌套,而大多数部件都有父子依赖关系,但是有些情况下不能直接引用子部件,这时我们可以通过父部件来findChild -"查找孩子". 简述 查 ...

  6. jQuery的offset、position、scroll,元素尺寸、对象过滤、查找、文档处理

    jQuery_offset和position var offset = $('.xxx').offset() console.log(offset.left.,offset.top)xxx相对于页面左 ...

  7. jQuery之元素查找

    在已经匹配出的元素集合中根据选择器查找孩子/父母/兄弟标签1. children(): 子标签中找2. find() : 后代标签中找3. parent() : 父标签4. prevAll() : 前 ...

  8. Java数据结构(十五)—— 多路查找树

    多路查找树 二叉树和B树 二叉树的问题分析 二叉树操作效率高 二叉树需要加载到内存,若二叉树的节点多存在如下问题: 问题1:构建二叉树时,需多次进行I/O操作,对与速度有影响 问题2:节点海量造成二叉 ...

  9. 使用Qt5.7.0 VS2015版本生成兼容XP的可执行程序 good(从VS2012 update1开始支持xp和c++11)

    一.直接使用VS2012/VS2013/VS2015生成XP兼容的可执行程序 Visual Studio刚发布时没打补丁,称为RTM版,之后会陆续发布补丁,进行bug修复和功能增强.VS2010及之前 ...

随机推荐

  1. 怎样開始学习ADF和Jdeveroper 11g

    先给一些资料能够帮助刚開始学习的人開始学习ADF和Jdeveloper11g 1.首先毫无疑问,你要懂java语言. 能够看看Thinking In Java, 或者原来sun的网上的一些文档Sun' ...

  2. JavaScript进阶之路 初学者的开始

    一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...

  3. 一起学 Java集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  4. 巨蟒python全栈开发flask7 语音识别升级版&&mongoDB

    1.web简陋版玩具 首先,复制上一节课的内容,将其中的语音文件删除掉, 放入三个文件,然后,我们需要在app写入下面的内容 下图是需要修改的地方: Recorder_ok.js是一个web录音的工具 ...

  5. Storm-源码分析汇总

    Storm Features Storm 简介 Storm Topology的并发度 Storm - Guaranteeing message processing Storm - Transacti ...

  6. DES加密原理

    DES加密步奏: 1.初始化两个字符串,一个为指定的秘钥,一个为初始化向量,要求是8个字符. 2.加密:秘钥.向量.需加密的字符串传换成byte[]类型: 声明加密标准类,DESCryptoServi ...

  7. HTTP 错误 500.21 - Internal Server Error 解决方案(转)

    不久前重新安装了Windows7,在安装了VS2010 开发平台之后,将网站发布到IIS,访问发生如下错误: HTTP 错误 500.21 - Internal Server Error处理程序“Ni ...

  8. 2015-04-14——css3 @media

    //判断横竖屏 @media screen and (min-aspect-ratio: 13/13) { body {background-color:red;}}  //屏幕宽高比,必须是除数形式 ...

  9. 对protected函数的简单理解 good

    对于protected提供的函数和属性,除非想扩充这个类的功能,否则是完全用不到的.外部函数main()永远只能调用public的那些函数.所以从拖拉控件编程的角度来讲,只需要学习public的函数和 ...

  10. Django的模型层(2)- 多表操作(上)

    一.创建模型 例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一(on ...