使用QObject及其子类创建的对象是以对象树的形式来组织的。创建一个QObject对象时若设置一个父对象,它就会被添加到父对象的子对象列表里,一个父对象被删除时,其全部的子对象都会自动删除。QObject类的构造函数里有一个参数用于设置对象的父对象,还有一些函数可以在运行时访问对象树中的对象:
(1)函数childern()。返回对象的子对象列表,函数定义如下:
const QObjectList& QObject::children();
函数的返回值是QObjectList类型,就是QObject类型指针列表,定义如下:
typedef QList<QObject*> QObjectList;
对于界面上的容器类组件,容器内的所有组件(包括内部的布局组件)都是其子对象。可以通过children()函数来访问组件内的所有的子对象。例如以下代码访问groupBox容器内的所有组件:
QObjectList objList = ui->groupbox->children(); //获取子对象列表for(int i = 0;i < objList.size();i++){const QMetaObject *meta = objList.at(i)->metaObject(); //获取元对象QString className = QString(meta->className()); //获取子对象的类名称if(className == "QPushButton"){QPushButton *btn = qobject_cast<QPushButton*>(objList.at(i));/*** 获取到QPushButton指针,可以对当前btn进行一些操作 ****/QString str = btn->text();btn->setText(str + "***"); //更新按钮显示文字}if(className == "QSpinBox"){QSpinBox *spin = qobject_cast<QSpinBox*>(objList.at(i));//如果是QSpinBox组件,获得QSpinBox*指针,然后可以进行一些操作spin->setValue(0); //更新当前SpinBox的值}}
(2) 函数findChild()。在对象的子对象中查找可以转换为类型T的子对象,定义如下:
template<typename T>T QObject::findChild(const QString &name = QString(),Qt::FindChildOptions options = Qt::FindChildrenRecursively);
参数name是子对象的名称;参数options表示查找方式,默认在子对象中递归查找,也就是会查找子对象的子对象。若设置为Qt::FindDirectChildrenOnly表示只查找直接子对象。
例如:
QPushButton *btn = this->findChild<QPushButton*>("btnOK");//查找窗口上对象名称为btnOK的QPushButton按钮,默认递归查找,只要窗口上有按钮btnOK,就可以找到这个对象
(3)函数fidChildren()。用于在对象的子对象中查找可以转换为类型T的子对象,可以指定对象名称,也可以使用正则表达式(QRegularExpression)来匹配对象名称。如果不设置要查找的对象名称,就返回所有能转换为灯型T的对象。函数原型定义如下:
template <typename T> QList<T> QObject::findChildren(const QString &name = QString(),Qt::FindChildOptions options = Qt::FindChildrenRecursively);template <typename T> QList<T> QObject::findChildren(const QRegularExpression &re,Qt::FindChildOptions options = Qt::FindChildrenRecursively);
例如,下面代码找到分组框内的所有的QPushButton按钮组件:
QList<QPushButton*> btnList = ui->groupBox->findChildren<QPushButton*>();//获取QPushButton组件列表
for(int i = 0;i < btnList.size();i++){
//列表内均为QPushButton组件,因此无需进行类名判断和类型转换QPushButton *btn = btnList.at(i);QString str = btn->text();btn->setText(str + "***");
}