diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp index 31be899357..42afeb44c1 100644 --- a/examples/widgets/painting/shared/arthurstyle.cpp +++ b/examples/widgets/painting/shared/arthurstyle.cpp @@ -441,7 +441,7 @@ int ArthurStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWid void ArthurStyle::polish(QWidget *widget) { if (widget->layout() && qobject_cast(widget)) { - if (widget->findChildren().size() == 0) { + if (!widget->findChild()) { widget->layout()->setSpacing(0); widget->layout()->setContentsMargins(12, 12, 12, 12); } else { diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index fddda64b19..8a007899e3 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -449,7 +449,7 @@ QListWidget *list = parentWidget->findChild(QString(), Qt::FindDi //! [43] -QList childButtons = parentWidget.findChildren(QString(), Qt::FindDirectChildrenOnly); +QList childButtons = parentWidget.findChildren(Qt::FindDirectChildrenOnly); //! [43] //! [44] diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 8eb2af0c61..d524fd4305 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1947,7 +1947,8 @@ void QObject::killTimer(int id) Returns all children of this object with the given \a name that can be cast to type T, or an empty list if there are no such objects. - Omitting the \a name argument causes all object names to be matched. + A null \a name argument causes all objects to be matched, an empty one + only those whose objectName is empty. The search is performed recursively, unless \a options specifies the option FindDirectChildrenOnly. @@ -1967,6 +1968,19 @@ void QObject::killTimer(int id) \sa findChild() */ +/*! + \fn template QList QObject::findChildren(Qt::FindChildOptions options) const + \overload + \since 6.3 + + Returns all children of this object that can be cast to type T, or + an empty list if there are no such objects. + The search is performed recursively, unless \a options specifies the + option FindDirectChildrenOnly. + + \sa findChild() +*/ + /*! \fn QList QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options) const \overload findChildren() @@ -2012,24 +2026,46 @@ void QObject::killTimer(int id) \sa QObject::findChildren() */ +static void qt_qFindChildren_with_name(const QObject *parent, const QString &name, + const QMetaObject &mo, QList *list, + Qt::FindChildOptions options) +{ + Q_ASSERT(parent); + Q_ASSERT(list); + Q_ASSERT(!name.isNull()); + for (QObject *obj : parent->children()) { + if (mo.cast(obj) && obj->objectName() == name) + list->append(obj); + if (options & Qt::FindChildrenRecursively) + qt_qFindChildren_with_name(obj, name, mo, list, options); + } +} + /*! \internal */ void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QMetaObject &mo, QList *list, Qt::FindChildOptions options) +{ + if (name.isNull()) + return qt_qFindChildren_helper(parent, mo, list, options); + else + return qt_qFindChildren_with_name(parent, name, mo, list, options); +} + +/*! + \internal +*/ +void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo, + QList *list, Qt::FindChildOptions options) { Q_ASSERT(parent); Q_ASSERT(list); - const QObjectList &children = parent->children(); - QObject *obj; - for (int i = 0; i < children.size(); ++i) { - obj = children.at(i); - if (mo.cast(obj)) { - if (name.isNull() || obj->objectName() == name) - list->append(obj); - } + for (QObject *obj : parent->children()) { + if (mo.cast(obj)) + list->append(obj); if (options & Qt::FindChildrenRecursively) - qt_qFindChildren_helper(obj, name, mo, list, options); + qt_qFindChildren_helper(obj, mo, list, options); } } @@ -2042,10 +2078,7 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re { Q_ASSERT(parent); Q_ASSERT(list); - const QObjectList &children = parent->children(); - QObject *obj; - for (int i = 0; i < children.size(); ++i) { - obj = children.at(i); + for (QObject *obj : parent->children()) { if (mo.cast(obj)) { QRegularExpressionMatch m = re.match(obj->objectName()); if (m.hasMatch()) @@ -2063,18 +2096,13 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options) { Q_ASSERT(parent); - const QObjectList &children = parent->children(); - QObject *obj; - int i; - for (i = 0; i < children.size(); ++i) { - obj = children.at(i); + for (QObject *obj : parent->children()) { if (mo.cast(obj) && (name.isNull() || obj->objectName() == name)) return obj; } if (options & Qt::FindChildrenRecursively) { - for (i = 0; i < children.size(); ++i) { - obj = qt_qFindChild_helper(children.at(i), name, mo, options); - if (obj) + for (QObject *child : parent->children()) { + if (QObject *obj = qt_qFindChild_helper(child, name, mo, options)) return obj; } } @@ -3593,7 +3621,7 @@ void QMetaObject::connectSlotsByName(QObject *o) const QMetaObject *mo = o->metaObject(); Q_ASSERT(mo); const QObjectList list = // list of all objects to look for matching signals including... - o->findChildren(QString()) // all children of 'o'... + o->findChildren() // all children of 'o'... << o; // and the object 'o' itself // for each method/slot of o ... diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 6a8088ef12..c2fc2910f0 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -83,6 +83,8 @@ typedef QList QObjectList; Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QMetaObject &mo, QList *list, Qt::FindChildOptions options); +Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo, + QList *list, Qt::FindChildOptions options); Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re, const QMetaObject &mo, QList *list, Qt::FindChildOptions options); Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options); @@ -167,7 +169,7 @@ public: } template - inline QList findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const + inline QList findChildren(const QString &aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { typedef typename std::remove_cv::type>::type ObjType; QList list; @@ -176,6 +178,16 @@ public: return list; } + template + QList findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const + { + typedef typename std::remove_cv::type>::type ObjType; + QList list; + qt_qFindChildren_helper(this, ObjType::staticMetaObject, + reinterpret_cast *>(&list), options); + return list; + } + #if QT_CONFIG(regularexpression) template inline QList findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 7776ae6613..ee200de57d 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -2607,7 +2607,7 @@ void QDockAreaLayout::removePlaceHolder(const QString &name) if (!index.isEmpty()) remove(index); const auto groups = - mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); + mainWindow->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { index = dwgw->layoutInfo()->indexOfPlaceHolder(name); if (!index.isEmpty()) { @@ -3045,7 +3045,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { QDockAreaLayoutItem *item = nullptr; const auto groups = - mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); + mainWindow->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { QList index = dwgw->layoutInfo()->indexOfPlaceHolder(dockWidget->objectName()); if (!index.isEmpty()) { diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 59e2e4e57a..18dd05e63b 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -431,7 +431,7 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() } // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent - const auto dockWidgets = findChildren(QString(), Qt::FindDirectChildrenOnly); + const auto dockWidgets = findChildren(Qt::FindDirectChildrenOnly); for (QDockWidget *dw : dockWidgets) { bool wasFloating = dw->isFloating(); bool wasHidden = dw->isHidden(); @@ -451,7 +451,7 @@ void QDockWidgetGroupWindow::destroyOrHideIfEmpty() dw->show(); } #if QT_CONFIG(tabbar) - const auto tabBars = findChildren(QString(), Qt::FindDirectChildrenOnly); + const auto tabBars = findChildren(Qt::FindDirectChildrenOnly); for (QTabBar *tb : tabBars) tb->setParent(parentWidget()); #endif @@ -1056,7 +1056,7 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const dockAreaLayout.saveState(stream); #if QT_CONFIG(tabbar) const QList floatingTabs = - mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); + mainWindow->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *floating : floatingTabs) { if (floating->layoutInfo()->isEmpty()) @@ -1835,7 +1835,7 @@ QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget) if (info) return info; const auto groups = - parent()->findChildren(QString(), Qt::FindDirectChildrenOnly); + parent()->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { info = dwgw->layoutInfo()->info(widget); if (info) @@ -2104,7 +2104,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) previousPath = currentHoveredFloat->layoutInfo()->indexOf(widget); // Let's remove the widget from any possible group window const auto groups = - parent()->findChildren(QString(), Qt::FindDirectChildrenOnly); + parent()->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { if (dwgw == currentHoveredFloat) continue; @@ -2134,7 +2134,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) #if QT_CONFIG(dockwidget) // Let's remove the widget from any possible group window const auto groups = - parent()->findChildren(QString(), Qt::FindDirectChildrenOnly); + parent()->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) { QList path = dwgw->layoutInfo()->indexOf(widget); if (!path.isEmpty()) @@ -2730,7 +2730,7 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat #if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget) QSet used = newState.dockAreaLayout.usedTabBars(); const auto groups = - parent()->findChildren(QString(), Qt::FindDirectChildrenOnly); + parent()->findChildren(Qt::FindDirectChildrenOnly); for (QDockWidgetGroupWindow *dwgw : groups) used += dwgw->layoutInfo()->usedTabBars(); diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f5c16faa56..3d52478299 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -755,6 +755,8 @@ void tst_QObject::findChildren() op = o.findChild("unnamed", Qt::FindDirectChildrenOnly); QCOMPARE(op, static_cast(0)); + l = o.findChildren(Qt::FindDirectChildrenOnly); + QCOMPARE(l.size(), 5); l = o.findChildren(QString(), Qt::FindDirectChildrenOnly); QCOMPARE(l.size(), 5); l = o.findChildren("", Qt::FindDirectChildrenOnly);