Qt之findChild

简介: 简述在Qt编程过程中,通常会有多个部件嵌套,而大多数部件都有父子依赖关系,但是有些情况下不能直接引用子部件,这时我们可以通过父部件来findChild -“查找孩子”。简述查找选项findChild描述示例分析效果源码可能情况查找选项枚举Qt::FindChildOption:Qt::FindChildOp

简述

在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

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

示例

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

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

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

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

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

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

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

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

我们不妨来分析一下!

分析

假如我们有一个主界面,主界面上有一个文本为“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 *>();

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

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

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

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

    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");

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

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

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

注意:

  1. 理解直接与非直接孩子的区别与关系(可以想象一下血缘关系)。
  2. name是按照objectName()来查找的,并不是text(),切勿搞错。
目录
相关文章
|
11月前
|
Linux 定位技术 C++
【Qt】-学Qt前的准备
【Qt】-学Qt前的准备
|
11月前
|
前端开发 编译器 开发工具
Qt
Qt
382 0
|
算法
Qt之QTimeLine
简述 QTimeLine 类提供了用于控制动画的时间轴,通常用于通过定期调用一个槽函数来动画一个 GUI 控件。 相信了解动画的人对帧应该不陌生,可以把一个动画想象成由很多张静态画面组成,而每一个画面就是一帧图像。每隔一定时间间隔就显示一帧图像,当该间隔较短时,人眼就感觉不出来了,觉得看到的是连续的影像。 简述 详细说明 状态 方向 曲线形状 详细
2331 0
|
安全 并行计算
Qt之QFutureWatcher
简述 QFuture 表示异步计算的结果,QFutureWatcher 则允许使用信号和槽监视 QFuture,也就是说,QFutureWatcher 是为 QFuture 而生的。 简述 详细描述 基本使用 更多参考 详细描述 QFutureWatcher 提供了有关 QFuture 的信息和通知,使用 setFuture() 函数开始监视一个特
3793 0
|
存储
Qt之QUrlQuery
简述 QUrlQuery 类提供了一种方法来操纵 URL 查询中的 key-value 对。 简述 详细描述 编码 处理空格和加号 全解码 非标准分隔符 使用 QUrlQuery 分隔符 查询 删除 是否为空 详细描述 QUrlQuery 用来解析 URL 中的查询字符串,像下面这样: 上述的查询字符串在 URL 中 被用来传输
2968 0
Qt之QScrollArea
简述 QScrollArea提供了一个滚动视图到另一个部件。 滚动区域用于显示一个画面中的子部件的内容。如果部件超过画面的大小,视图可以提供滚动条,这样就都可以看到部件的整个区域。 简述 基本使用 对齐方式 调整部件大小 手动调整 自动调整 获取与移除部件 获取 移除 基本使用 子部件必须使用setWidget()指定,例如: QLab
3314 0
|
缓存 Unix Windows
Qt之QLocalSocket
简述 QLocalSocket类提供了一个本地socket。 在Windows中,这是一个命名管道;在Unix中,这是一个本地网域socket。 如果发生错误,socketError()会返回错误的类型,errorString()则返回人类可读的错误描述。 虽然QLocalSocket是一个事件循环使用而设计,它也可以不被如此使用。这种情况下,必须使用 waitF
2732 0
Qt之QSpinBox和QDoubleSpinBox
简述 QSpinBox和QDoubleSpinBox均派生自QAbstractSpinBox。 QSpinBox旨在处理整数和离散值(例如:月份名称),QDoubleSpinBox则用于处理浮点值。他们之间的区别就是处理数据的类型不同,其他功能都基本相同。 QDoubleSpinBox的默认的精度是2位小数,但可以通过setDecimals()来改变。 下面主要以QS
2079 0
|
网络协议 存储
Qt之QNetworkAddressEntry
简述 QNetworkAddressEntry类由网络接口支持,存储了一个IP地址,子网掩码和广播地址。 每个网络接口可以包含零个或多个IP地址,进而可以关联到一个子网掩码和/或一个广播地址(取决于操作系统的支持)。 这个类代表一个这样的组。 简述 常用接口 使用 更多参考 常用接口 QHostAddress broadcast() co
1858 0