diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 964597a2da..9fe3827d86 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -773,6 +773,20 @@ QString QLocale::bcp47Name() const return bcp47Name(TagSeparator::Dash); } +#include "qobject.h" + +void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QMetaObject &mo, + QList *list, Qt::FindChildOptions options) +{ + qt_qFindChildren_helper(parent, QAnyStringView{name}, mo, list, options); +} + +QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, + Qt::FindChildOptions options) +{ + return qt_qFindChild_helper(parent, QAnyStringView{name}, mo, options); +} + #include "qobjectdefs.h" int QMetaObject::indexOfEnumerator(const char *name) const diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 88e928044b..1319402839 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1982,7 +1982,7 @@ void QObject::killTimer(int id) /*! - \fn template T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const + \fn template T *QObject::findChild(QAnyStringView name, Qt::FindChildOptions options) const Returns the child of this object that can be cast into type T and that is called \a name, or \nullptr if there is no such object. @@ -2016,11 +2016,14 @@ void QObject::killTimer(int id) \snippet code/src_corelib_kernel_qobject.cpp 42 + \note In Qt versions prior to 6.7, this function took \a name as + \c{QString}, not \c{QAnyStringView}. + \sa findChildren() */ /*! - \fn template QList QObject::findChildren(const QString &name, Qt::FindChildOptions options) const + \fn template QList QObject::findChildren(QAnyStringView name, Qt::FindChildOptions options) const 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. @@ -2042,6 +2045,9 @@ void QObject::killTimer(int id) \snippet code/src_corelib_kernel_qobject.cpp 43 + \note In Qt versions prior to 6.7, this function took \a name as + \c{QString}, not \c{QAnyStringView}. + \sa findChild() */ @@ -2103,46 +2109,26 @@ 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) +static bool matches_objectName_non_null(QObject *obj, QAnyStringView name) { - 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); - } + if (auto ext = QObjectPrivate::get(obj)->extraData) + return ext ->objectName.valueBypassingBindings() == name; + return name.isEmpty(); } /*! \internal */ -void qt_qFindChildren_helper(const QObject *parent, const QString &name, +void qt_qFindChildren_helper(const QObject *parent, QAnyStringView 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); for (QObject *obj : parent->children()) { - if (mo.cast(obj)) + if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name))) list->append(obj); if (options & Qt::FindChildrenRecursively) - qt_qFindChildren_helper(obj, mo, list, options); + qt_qFindChildren_helper(obj, name, mo, list, options); } } @@ -2169,13 +2155,13 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re /*! \internal - */ -QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options) +*/ +QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name, const QMetaObject &mo, Qt::FindChildOptions options) { Q_ASSERT(parent); for (QObject *obj : parent->children()) { - if (mo.cast(obj) && (name.isNull() || obj->objectName() == name)) - return obj; + if (mo.cast(obj) && (name.isNull() || matches_objectName_non_null(obj, name))) + return obj; } if (options & Qt::FindChildrenRecursively) { for (QObject *child : parent->children()) { diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 824a29a5a4..3660a5b3c4 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -43,13 +43,22 @@ struct QDynamicMetaObjectData; typedef QList QObjectList; +#if QT_CORE_REMOVED_SINCE(6, 7) Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QMetaObject &mo, QList *list, Qt::FindChildOptions options); +#endif +Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, QAnyStringView 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); +#if QT_CORE_REMOVED_SINCE(6, 7) Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options); +#endif +Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name, + const QMetaObject &mo, Qt::FindChildOptions options); class Q_CORE_EXPORT QObjectData { @@ -131,14 +140,14 @@ public: void killTimer(int id); template - inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const + T findChild(QAnyStringView aName = {}, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { typedef typename std::remove_cv::type>::type ObjType; return static_cast(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options)); } template - inline QList findChildren(const QString &aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const + QList findChildren(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { typedef typename std::remove_cv::type>::type ObjType; QList list; @@ -150,11 +159,7 @@ public: 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; + return findChildren(QAnyStringView{}, options); } #if QT_CONFIG(regularexpression) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index deb8c542dd..33ecb869b3 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -39,6 +39,8 @@ #include +using namespace Qt::StringLiterals; + class tst_QObject : public QObject { Q_OBJECT @@ -520,6 +522,10 @@ void tst_QObject::findChildren() QTimer t1(&o); QTimer t121(&o12); QTimer emptyname(&o); + QObject oo; + QObject o21(&oo); + QObject o22(&oo); + QObject o23(&oo); Q_SET_OBJECT_NAME(o); Q_SET_OBJECT_NAME(o1); @@ -530,6 +536,13 @@ void tst_QObject::findChildren() Q_SET_OBJECT_NAME(t1); Q_SET_OBJECT_NAME(t121); emptyname.setObjectName(""); + Q_SET_OBJECT_NAME(oo); + const QUtf8StringView utf8_name = u8"utf8 ⁎ obj"; + o21.setObjectName(utf8_name); + const QStringView utf16_name = u"utf16 ⁎ obj"; + o22.setObjectName(utf16_name); + constexpr QLatin1StringView L1_name("L1 ⁎ obj"); + o23.setObjectName(L1_name); QObject *op = nullptr; @@ -560,6 +573,27 @@ void tst_QObject::findChildren() op = o.findChild("o1"); QCOMPARE(op, &o1); + op = oo.findChild(utf8_name); + QCOMPARE(op, &o21); + op = oo.findChild(utf8_name.chopped(1)); + QCOMPARE(op, nullptr); + const QUtf8StringView utf8_name_with_trailing_data = u8"utf8 ⁎ obj_data"; + op = oo.findChild(utf8_name_with_trailing_data.chopped(5)); + QCOMPARE(op, &o21); + op = oo.findChild(utf16_name); + QCOMPARE(op, &o22); + op = oo.findChild(utf16_name.chopped(1)); + QCOMPARE(op, nullptr); + const QStringView utf16_name_with_trailing_data = u"utf16 ⁎ obj_data"; + op = oo.findChild(utf16_name_with_trailing_data.chopped(5)); + QCOMPARE(op, &o22); + op = oo.findChild(L1_name); + QCOMPARE(op, &o23); + op = oo.findChild(L1_name.chopped(1)); + QCOMPARE(op, nullptr); + op = oo.findChild((L1_name + "_data"_L1).chopped(5)); + QCOMPARE(op, &o23); + QList l; QList tl;