我们在编写Qt应用是,经常会遇到需要获取某个窗口或控件下面的所有子控件,但是有时发现获取到的子控件总是不对,今天抽空对该函数进行分析一下:
这是创建的一个QApplication应用,UI文件未做任何修改。
接下来往centralwidget中放一些控件,看看是否能正确获取到子控件:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->centralwidget->setObjectName("centralwidget");
QVBoxLayout *centerLayout = new QVBoxLayout(ui->centralwidget);
QFrame *frame_1 = new QFrame(ui->centralwidget);
QFrame *frame_2 = new QFrame(ui->centralwidget);
centerLayout->setObjectName("centerLayout");
frame_1->setObjectName("frame_1");
frame_2->setObjectName("frame_2");
frame_1->setStyleSheet("background-color:red;");
frame_2->setStyleSheet("background-color:yellow;");
centerLayout->addWidget(frame_1);
centerLayout->addWidget(frame_2);
for (QObject *o : ui->centralwidget->children()) {
qDebug()<<"ui->centralwidget->children:"<<o->objectName();
}
}
这是正常的写法,我们在创建时都为frame_1和frame_2都设置了父对象,然后再分别添加到layout中去,此时的结果:

可以看到children能正确访问到,并且按照设置父对象的顺序。注意:该函数会返回控件的布局,因为布局的父对象也是该控件,一般情况下,我们是不需要获取到布局的。而且这里的顺序并不是添加到layout中的顺序,接下来我们加以验证:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->centralwidget->setObjectName("centralwidget");
QVBoxLayout *centerLayout = new QVBoxLayout(ui->centralwidget);
QFrame *frame_1 = new QFrame();
QFrame *frame_2 = new QFrame();
centerLayout->setObjectName("centerLayout");
frame_2->setParent(ui->centralwidget);
frame_1->setParent(ui->centralwidget);
frame_1->setObjectName("frame_1");
frame_2->setObjectName("frame_2");
frame_1->setStyleSheet("background-color:red;");
frame_2->setStyleSheet("background-color:yellow;");
centerLayout->addWidget(frame_1);
centerLayout->addWidget(frame_2);
for (QObject *o : ui->centralwidget->children()) {
qDebug()<<"ui->centralwidget->children:"<<o->objectName();
}
}
结果如下:

本文详细分析了在Qt应用程序中如何正确获取窗口或控件的子控件,包括使用`children()`函数和布局管理器。讨论了设置父对象、布局顺序、`findChildren()`函数以及自定义递归算法在获取子控件时的影响。同时,指出了获取子控件顺序的限制,并提供了按照布局顺序获取子控件的解决方案。

1728

被折叠的 条评论
为什么被折叠?



