QObject: add check for Q_OBJECT macro to findChild(ren)

We can't fix the underlying reported problem, but we can warn that the
user has made a mistake.

[ChangeLog][QtCore][QObject] The class template parameter passed to
QObject::findChild() or findChildren() is now required to have the
Q_OBJECT macro. Forgetting to add it could result in finding children of
the nearest ancestor class that has the macro.

Pick-to: 6.7
Fixes: QTBUG-105023
Change-Id: I5f663c2f9f4149af84fefffd17c008f027241b56
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
Thiago Macieira 2024-03-25 10:41:25 -04:00
parent 43cefd882e
commit ce2585d0e9
1 changed files with 6 additions and 0 deletions

View File

@ -155,6 +155,8 @@ public:
T findChild(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
"No Q_OBJECT in the class passed to QObject::findChild");
return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
}
@ -162,6 +164,8 @@ public:
QList<T> findChildren(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
"No Q_OBJECT in the class passed to QObject::findChildren");
QList<T> list;
qt_qFindChildren_helper(this, aName, ObjType::staticMetaObject,
reinterpret_cast<QList<void *> *>(&list), options);
@ -185,6 +189,8 @@ public:
inline QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
"No Q_OBJECT in the class passed to QObject::findChildren");
QList<T> list;
qt_qFindChildren_helper(this, re, ObjType::staticMetaObject,
reinterpret_cast<QList<void *> *>(&list), options);