Add flag for non-recursive lookup of child qobject(s)

Merge-request: 40
Reviewed-by: olivier
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>

Change-Id: I1194ba0d8bba92ece3132171e230cece341ec127
Reviewed-on: http://codereview.qt.nokia.com/2957
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
This commit is contained in:
David Faure 2011-08-15 13:24:23 +02:00 committed by Qt by Nokia
parent c74aa53383
commit 3a1568c30c
6 changed files with 165 additions and 24 deletions

View File

@ -434,6 +434,21 @@ hostNameLabel->setText(tr("Name:"));
QString example = tr("Example"); QString example = tr("Example");
//! [40] //! [40]
//! [41]
QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildOnly);
//! [41]
//! [42]
QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildOnly);
//! [42]
//! [43]
QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildOnly);
//! [43]
//! [meta data] //! [meta data]
//: This is a comment for the translator. //: This is a comment for the translator.
//= qtn_foo_bar //= qtn_foo_bar

View File

@ -1293,7 +1293,11 @@ public:
AnchorBottom AnchorBottom
}; };
enum FindChildOption {
FindDirectChildrenOnly = 0x0,
FindChildrenRecursively = 0x1
};
Q_DECLARE_FLAGS(FindChildOptions, FindChildOption)
enum DropAction { enum DropAction {
CopyAction = 0x1, CopyAction = 0x1,

View File

@ -2110,6 +2110,13 @@
\sa QWidget::windowFlags, {Window Flags Example} \sa QWidget::windowFlags, {Window Flags Example}
*/ */
/*!
\enum Qt::FindChildOption
\value FindDirectChildrenOnly Looks only at the direct children of the object.
\value FindChildrenRecursively Looks at all children of the object (recursive search).
*/
/*! /*!
\enum Qt::DropAction \enum Qt::DropAction

View File

@ -1028,8 +1028,8 @@ QObjectPrivate::Connection::~Connection()
\brief the name of this object \brief the name of this object
You can find an object by name (and type) using findChild(). You can You can find an object by name (and type) using findChild().
find a set of objects with findChildren(). You can find a set of objects with findChildren().
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5
@ -1545,12 +1545,13 @@ void QObject::killTimer(int id)
/*! /*!
\fn T *QObject::findChild(const QString &name) const \fn T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
Returns the child of this object that can be cast into type T and Returns the child of this object that can be cast into type T and
that is called \a name, or 0 if there is no such object. that is called \a name, or 0 if there is no such object.
Omitting the \a name argument causes all object names to be matched. Omitting the \a name argument causes all object names to be matched.
The search is performed recursively. The search is performed recursively, unless \a options specifies the
option FindDirectChildrenOnly.
If there is more than one child matching the search, the most If there is more than one child matching the search, the most
direct ancestor is returned. If there are several direct direct ancestor is returned. If there are several direct
@ -1558,7 +1559,8 @@ void QObject::killTimer(int id)
case, findChildren() should be used. case, findChildren() should be used.
This example returns a child \l{QPushButton} of \c{parentWidget} This example returns a child \l{QPushButton} of \c{parentWidget}
named \c{"button1"}: named \c{"button1"}, even if the button isn't a direct child of
the parent:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10
@ -1566,16 +1568,27 @@ void QObject::killTimer(int id)
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
This example returns a child \l{QPushButton} of \c{parentWidget}
(its direct parent) named \c{"button1"}:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 41
This example returns a \l{QListWidget} child of \c{parentWidget},
its direct parent:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 42
\sa findChildren() \sa findChildren()
*/ */
/*! /*!
\fn QList<T> QObject::findChildren(const QString &name) const \fn QList<T> QObject::findChildren(const QString &name, Qt::FindChildOptions options) const
Returns all children of this object with the given \a name that can be 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. 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. Omitting the \a name argument causes all object names to be matched.
The search is performed recursively. The search is performed recursively, unless \a options specifies the
option FindDirectChildrenOnly.
The following example shows how to find a list of child \l{QWidget}s of The following example shows how to find a list of child \l{QWidget}s of
the specified \c{parentWidget} named \c{widgetname}: the specified \c{parentWidget} named \c{widgetname}:
@ -1586,11 +1599,15 @@ void QObject::killTimer(int id)
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
This example returns all \c{QPushButton}s that are immediate children of \c{parentWidget}:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 43
\sa findChild() \sa findChild()
*/ */
/*! /*!
\fn QList<T> QObject::findChildren(const QRegExp &regExp) const \fn QList<T> QObject::findChildren(const QRegExp &regExp, Qt::FindChildOptions options) const
\overload findChildren() \overload findChildren()
Returns the children of this object that can be cast to type T Returns the children of this object that can be cast to type T
@ -1650,7 +1667,7 @@ void QObject::killTimer(int id)
\internal \internal
*/ */
void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re, void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
const QMetaObject &mo, QList<void*> *list) const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
{ {
if (!parent || !list) if (!parent || !list)
return; return;
@ -1667,13 +1684,14 @@ void qt_qFindChildren_helper(const QObject *parent, const QString &name, const Q
list->append(obj); list->append(obj);
} }
} }
qt_qFindChildren_helper(obj, name, re, mo, list); if (options & Qt::FindChildrenRecursively)
qt_qFindChildren_helper(obj, name, re, mo, list, options);
} }
} }
/*! \internal /*! \internal
*/ */
QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo) QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
{ {
if (!parent) if (!parent)
return 0; return 0;
@ -1685,11 +1703,13 @@ QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const
if (mo.cast(obj) && (name.isNull() || obj->objectName() == name)) if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
return obj; return obj;
} }
if (options & Qt::FindChildrenRecursively) {
for (i = 0; i < children.size(); ++i) { for (i = 0; i < children.size(); ++i) {
obj = qt_qFindChild_helper(children.at(i), name, mo); obj = qt_qFindChild_helper(children.at(i), name, mo, options);
if (obj) if (obj)
return obj; return obj;
} }
}
return 0; return 0;
} }

View File

@ -78,8 +78,8 @@ class QObjectUserData;
typedef QList<QObject*> QObjectList; typedef QList<QObject*> QObjectList;
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re, Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
const QMetaObject &mo, QList<void *> *list); const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo); Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
class class
#if defined(__INTEL_COMPILER) && defined(Q_OS_WIN) #if defined(__INTEL_COMPILER) && defined(Q_OS_WIN)
@ -155,11 +155,11 @@ public:
void killTimer(int id); void killTimer(int id);
template<typename T> template<typename T>
inline T findChild(const QString &aName = QString()) const inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject)); } { return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject, options)); }
template<typename T> template<typename T>
inline QList<T> findChildren(const QString &aName = QString()) const inline QList<T> findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ {
QList<T> list; QList<T> list;
union { union {
@ -167,13 +167,13 @@ public:
QList<void *> *voidList; QList<void *> *voidList;
} u; } u;
u.typedList = &list; u.typedList = &list;
qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList); qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
return list; return list;
} }
#ifndef QT_NO_REGEXP #ifndef QT_NO_REGEXP
template<typename T> template<typename T>
inline QList<T> findChildren(const QRegExp &re) const inline QList<T> findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ {
QList<T> list; QList<T> list;
union { union {
@ -181,7 +181,7 @@ public:
QList<void *> *voidList; QList<void *> *voidList;
} u; } u;
u.typedList = &list; u.typedList = &list;
qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList); qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
return list; return list;
} }
#endif #endif

View File

@ -689,6 +689,101 @@ void tst_QObject::findChildren()
tl = o.findChildren<QTimer *>("t1"); tl = o.findChildren<QTimer *>("t1");
QCOMPARE(tl.size(), 1); QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t1); QCOMPARE(tl.at(0), &t1);
// Find direct child/children
op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly);
QCOMPARE(op, &o1);
op = o.findChild<QObject*>("o2", Qt::FindDirectChildrenOnly);
QCOMPARE(op, &o2);
op = o.findChild<QObject*>("o11", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("o12", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("o111", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("t1", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(&t1));
op = o.findChild<QObject*>("t121", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QTimer*>("t1", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(&t1));
op = o.findChild<QTimer*>("t121", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QTimer*>("o12", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("o", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("harry", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly);
QCOMPARE(op, &o1);
l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o1);
l = o.findChildren<QObject*>("o2", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o2);
l = o.findChildren<QObject*>("o11", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
l = o.findChildren<QObject*>("o12", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
l = o.findChildren<QObject*>("o111", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
l = o.findChildren<QObject*>("t1", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), static_cast<QObject *>(&t1));
l = o.findChildren<QObject*>("t121", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
tl = o.findChildren<QTimer*>("t1", Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t1);
tl = o.findChildren<QTimer*>("t121", Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 0);
l = o.findChildren<QObject*>("o", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
l = o.findChildren<QObject*>("harry", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
tl = o.findChildren<QTimer*>("o12", Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 0);
l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QCOMPARE(l.at(0), &o1);
l = o.findChildren<QObject*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 2);
QVERIFY(l.contains(&o1));
QVERIFY(l.contains(&o2));
l = o.findChildren<QObject*>(QRegExp("t.*"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 1);
QVERIFY(l.contains(&t1));
tl = o.findChildren<QTimer*>(QRegExp(".*"), Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 2);
QVERIFY(tl.contains(&t1));
tl = o.findChildren<QTimer*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 0);
l = o.findChildren<QObject*>(QRegExp("harry"), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
// empty and null string check
op = o.findChild<QObject*>(QString(), Qt::FindDirectChildrenOnly);
QCOMPARE(op, &o1);
op = o.findChild<QObject*>("", Qt::FindDirectChildrenOnly);
QCOMPARE(op, &unnamed);
op = o.findChild<QObject*>("unnamed", Qt::FindDirectChildrenOnly);
QCOMPARE(op, static_cast<QObject *>(0));
l = o.findChildren<QObject*>(QString(), Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 5);
l = o.findChildren<QObject*>("", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 2);
l = o.findChildren<QObject*>("unnamed", Qt::FindDirectChildrenOnly);
QCOMPARE(l.size(), 0);
tl = o.findChildren<QTimer *>("t1", Qt::FindDirectChildrenOnly);
QCOMPARE(tl.size(), 1);
QCOMPARE(tl.at(0), &t1);
} }