summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobject.h')
-rw-r--r--src/corelib/kernel/qobject.h225
1 files changed, 109 insertions, 116 deletions
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 7fa2790208..06cfefd61b 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -19,10 +19,9 @@
#include <QtCore/qobject_impl.h>
#include <QtCore/qbindingstorage.h>
+#include <QtCore/qtcoreexports.h>
-#if __has_include(<chrono>)
-# include <chrono>
-#endif
+#include <chrono>
QT_BEGIN_NAMESPACE
@@ -45,13 +44,24 @@ struct QDynamicMetaObjectData;
typedef QList<QObject*> 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<void *> *list, Qt::FindChildOptions options);
+#endif
+Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, QAnyStringView name,
+ const QMetaObject &mo, QList<void *> *list,
+ Qt::FindChildOptions options);
+#if QT_CORE_REMOVED_SINCE(6, 7)
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
QList<void *> *list, Qt::FindChildOptions options);
+#endif
Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
const QMetaObject &mo, QList<void *> *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
{
@@ -74,7 +84,8 @@ public:
uint isQuickItem : 1;
uint willBeWidget : 1; // for handling widget-specific bits in QObject's ctor
uint wasWidget : 1; // for properly cleaning up in QObject's dtor
- uint unused : 21;
+ uint receiveParentEvents: 1;
+ uint unused : 20;
QAtomicInt postedEvents;
QDynamicMetaObjectData *metaObject;
QBindingStorage bindingStorage;
@@ -103,7 +114,7 @@ public:
virtual bool event(QEvent *event);
virtual bool eventFilter(QObject *watched, QEvent *event);
-#if defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC)
+#if defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
static QString tr(const char *sourceText, const char * = nullptr, int = -1)
{ return QString::fromUtf8(sourceText); }
#endif // QT_NO_TRANSLATION
@@ -125,29 +136,36 @@ public:
bool blockSignals(bool b) noexcept;
QThread *thread() const;
+#if QT_CORE_REMOVED_SINCE(6, 7)
void moveToThread(QThread *thread);
+#endif
+ bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL);
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
-#if __has_include(<chrono>)
- Q_ALWAYS_INLINE
- int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer)
- {
- return startTimer(int(time.count()), timerType);
- }
+
+#if QT_CORE_REMOVED_SINCE(6, 8)
+ int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer);
#endif
+ int startTimer(std::chrono::nanoseconds time, Qt::TimerType timerType = Qt::CoarseTimer);
+
void killTimer(int id);
+ void killTimer(Qt::TimerId id);
template<typename T>
- 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<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));
}
template<typename T>
- inline QList<T> findChildren(const QString &aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
+ 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);
@@ -155,13 +173,15 @@ public:
}
template<typename T>
+ T findChild(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
+ {
+ return findChild<T>({}, options);
+ }
+
+ template<typename T>
QList<T> findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{
- typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
- QList<T> list;
- qt_qFindChildren_helper(this, ObjType::staticMetaObject,
- reinterpret_cast<QList<void *> *>(&list), options);
- return list;
+ return findChildren<T>(QAnyStringView{}, options);
}
#if QT_CONFIG(regularexpression)
@@ -169,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);
@@ -192,7 +214,7 @@ public:
inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
template<typename PointerToMemberFunction>
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
template<typename PointerToMemberFunction, typename Functor>
@@ -200,54 +222,28 @@ public:
template<typename PointerToMemberFunction, typename Functor>
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
#else
- //Connect a signal to a pointer to qobject member function
+ //connect with context
template <typename Func1, typename Func2>
- static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
- const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
- Qt::ConnectionType type = Qt::AutoConnection)
+ static inline QMetaObject::Connection
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
+ const typename QtPrivate::ContextTypeForFunctor<Func2>::ContextType *context, Func2 &&slot,
+ Qt::ConnectionType type = Qt::AutoConnection)
{
typedef QtPrivate::FunctionPointer<Func1> SignalType;
- typedef QtPrivate::FunctionPointer<Func2> SlotType;
+ typedef QtPrivate::FunctionPointer<std::decay_t<Func2>> SlotType;
- static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
- "No Q_OBJECT in the class with the signal");
-
- //compilation error if the arguments does not match.
- static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
- "The slot requires more arguments than the signal provides.");
- static_assert((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
- "Signal and slot arguments are not compatible.");
- static_assert((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
- "Return type of the slot is not compatible with the return type of the signal.");
-
- const int *types = nullptr;
- if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
- types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
-
- return connectImpl(sender, reinterpret_cast<void **>(&signal),
- receiver, reinterpret_cast<void **>(&slot),
- new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
- typename SignalType::ReturnType>(slot),
- type, types, &SignalType::Object::staticMetaObject);
- }
-
- //connect to a function pointer (not a member)
- template <typename Func1, typename Func2>
- static inline typename std::enable_if<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0, QMetaObject::Connection>::type
- connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
- {
- return connect(sender, signal, sender, slot, Qt::DirectConnection);
- }
+ if constexpr (SlotType::ArgumentCount != -1) {
+ static_assert((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
+ "Return type of the slot is not compatible with the return type of the signal.");
+ } else {
+ constexpr int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<std::decay_t<Func2>, typename SignalType::Arguments>::Value;
+ [[maybe_unused]]
+ constexpr int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
+ typedef typename QtPrivate::FunctorReturnType<std::decay_t<Func2>, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value>::Value SlotReturnType;
- //connect to a function pointer (not a member)
- template <typename Func1, typename Func2>
- static inline typename std::enable_if<int(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0 &&
- !QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction, QMetaObject::Connection>::type
- connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
- Qt::ConnectionType type = Qt::AutoConnection)
- {
- typedef QtPrivate::FunctionPointer<Func1> SignalType;
- typedef QtPrivate::FunctionPointer<Func2> SlotType;
+ static_assert((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
+ "Return type of the slot is not compatible with the return type of the signal.");
+ }
static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
"No Q_OBJECT in the class with the signal");
@@ -255,67 +251,35 @@ public:
//compilation error if the arguments does not match.
static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
"The slot requires more arguments than the signal provides.");
- static_assert((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
- "Signal and slot arguments are not compatible.");
- static_assert((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
- "Return type of the slot is not compatible with the return type of the signal.");
const int *types = nullptr;
if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
- return connectImpl(sender, reinterpret_cast<void **>(&signal), context, nullptr,
- new QtPrivate::QStaticSlotObject<Func2,
- typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
- typename SignalType::ReturnType>(slot),
+ void **pSlot = nullptr;
+ if constexpr (std::is_member_function_pointer_v<std::decay_t<Func2>>) {
+ pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
+ } else {
+ Q_ASSERT_X((type & Qt::UniqueConnection) == 0, "",
+ "QObject::connect: Unique connection requires the slot to be a pointer to "
+ "a member function of a QObject subclass.");
+ }
+
+ return connectImpl(sender, reinterpret_cast<void **>(&signal), context, pSlot,
+ QtPrivate::makeCallableObject<Func1>(std::forward<Func2>(slot)),
type, types, &SignalType::Object::staticMetaObject);
}
- //connect to a functor
+#ifndef QT_NO_CONTEXTLESS_CONNECT
+ //connect without context
template <typename Func1, typename Func2>
- static inline typename std::enable_if<
- QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1 &&
- !std::is_convertible_v<Func2, const char*>, // don't match old-style connect
- QMetaObject::Connection>::type
- connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
+ static inline QMetaObject::Connection
+ connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 &&slot)
{
- return connect(sender, signal, sender, std::move(slot), Qt::DirectConnection);
- }
-
- //connect to a functor, with a "context" object defining in which event loop is going to be executed
- template <typename Func1, typename Func2>
- static inline typename std::enable_if<
- QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1 &&
- !std::is_convertible_v<Func2, const char*>, // don't match old-style connect
- QMetaObject::Connection>::type
- connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
- Qt::ConnectionType type = Qt::AutoConnection)
- {
- typedef QtPrivate::FunctionPointer<Func1> SignalType;
- const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
-
- static_assert((FunctorArgumentCount >= 0),
- "Signal and slot arguments are not compatible.");
- const int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
- typedef typename QtPrivate::FunctorReturnType<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value>::Value SlotReturnType;
-
- static_assert((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
- "Return type of the slot is not compatible with the return type of the signal.");
-
- static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
- "No Q_OBJECT in the class with the signal");
-
- const int *types = nullptr;
- if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
- types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
-
- return connectImpl(sender, reinterpret_cast<void **>(&signal), context, nullptr,
- new QtPrivate::QFunctorSlotObject<Func2, SlotArgumentCount,
- typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value,
- typename SignalType::ReturnType>(std::move(slot)),
- type, types, &SignalType::Object::staticMetaObject);
+ return connect(sender, signal, sender, std::forward<Func2>(slot), Qt::DirectConnection);
}
-#endif //Q_CLANG_QDOC
+#endif // QT_NO_CONTEXTLESS_CONNECT
+#endif //Q_QDOC
static bool disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member);
@@ -328,7 +292,7 @@ public:
{ return disconnect(this, nullptr, receiver, member); }
static bool disconnect(const QMetaObject::Connection &);
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
template<typename PointerToMemberFunction>
static bool disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method);
#else
@@ -361,12 +325,14 @@ public:
return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, zero,
&SignalType::Object::staticMetaObject);
}
-#endif //Q_CLANG_QDOC
+#endif //Q_QDOC
void dumpObjectTree() const;
void dumpObjectInfo() const;
+ QT_CORE_INLINE_SINCE(6, 6)
bool setProperty(const char *name, const QVariant &value);
+ inline bool setProperty(const char *name, QVariant &&value);
QVariant property(const char *name) const;
QList<QByteArray> dynamicPropertyNames() const;
QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; }
@@ -419,8 +385,9 @@ protected:
private:
void doSetObjectName(const QString &name);
+ bool doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue);
+
Q_DISABLE_COPY(QObject)
- Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
private:
static QMetaObject::Connection connectImpl(const QObject *sender, void **signal,
@@ -437,9 +404,22 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch
const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); }
+#if QT_CORE_INLINE_IMPL_SINCE(6, 6)
+bool QObject::setProperty(const char *name, const QVariant &value)
+{
+ return doSetProperty(name, &value, nullptr);
+}
+#endif // inline since 6.6
+bool QObject::setProperty(const char *name, QVariant &&value)
+{
+ return doSetProperty(name, &value, &value);
+}
+
template <class T>
inline T qobject_cast(QObject *object)
{
+ static_assert(std::is_pointer_v<T>,
+ "qobject_cast requires to cast towards a pointer type");
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
"qobject_cast requires the type to have a Q_OBJECT macro");
@@ -449,6 +429,10 @@ inline T qobject_cast(QObject *object)
template <class T>
inline T qobject_cast(const QObject *object)
{
+ static_assert(std::is_pointer_v<T>,
+ "qobject_cast requires to cast towards a pointer type");
+ static_assert(std::is_const_v<std::remove_pointer_t<T>>,
+ "qobject_cast cannot cast away constness (use const_cast)");
typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
"qobject_cast requires the type to have a Q_OBJECT macro");
@@ -470,7 +454,7 @@ qobject_iid_cast(const QObject *object)
return qobject_iid_cast<std::remove_cv_t<T>>(o);
}
-#if defined(Q_CLANG_QDOC)
+#if defined(Q_QDOC)
# define Q_DECLARE_INTERFACE(IFace, IId)
#elif !defined(Q_MOC_RUN)
# define Q_DECLARE_INTERFACE(IFace, IId) \
@@ -498,15 +482,19 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
class QSignalBlocker
{
public:
+ Q_NODISCARD_CTOR
inline explicit QSignalBlocker(QObject *o) noexcept;
+ Q_NODISCARD_CTOR
inline explicit QSignalBlocker(QObject &o) noexcept;
inline ~QSignalBlocker();
+ Q_NODISCARD_CTOR
inline QSignalBlocker(QSignalBlocker &&other) noexcept;
inline QSignalBlocker &operator=(QSignalBlocker &&other) noexcept;
inline void reblock() noexcept;
inline void unblock() noexcept;
+ inline void dismiss() noexcept;
private:
Q_DISABLE_COPY(QSignalBlocker)
@@ -571,6 +559,11 @@ void QSignalBlocker::unblock() noexcept
m_inhibited = true;
}
+void QSignalBlocker::dismiss() noexcept
+{
+ m_o = nullptr;
+}
+
namespace QtPrivate {
inline QObject & deref_for_methodcall(QObject &o) { return o; }
inline QObject & deref_for_methodcall(QObject *o) { return *o; }