Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:09:26

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 
0005 #ifndef QOBJECT_H
0006 #define QOBJECT_H
0007 
0008 #ifndef QT_NO_QOBJECT
0009 
0010 #include <QtCore/qobjectdefs.h>
0011 #include <QtCore/qstring.h>
0012 #include <QtCore/qbytearray.h>
0013 #include <QtCore/qlist.h>
0014 #ifdef QT_INCLUDE_COMPAT
0015 #include <QtCore/qcoreevent.h>
0016 #endif
0017 #include <QtCore/qscopedpointer.h>
0018 #include <QtCore/qmetatype.h>
0019 
0020 #include <QtCore/qobject_impl.h>
0021 #include <QtCore/qbindingstorage.h>
0022 #include <QtCore/qtcoreexports.h>
0023 
0024 #include <chrono>
0025 
0026 QT_BEGIN_NAMESPACE
0027 
0028 
0029 template <typename T> class QBindable;
0030 class QEvent;
0031 class QTimerEvent;
0032 class QChildEvent;
0033 struct QMetaObject;
0034 class QVariant;
0035 class QObjectPrivate;
0036 class QObject;
0037 class QThread;
0038 class QWidget;
0039 class QAccessibleWidget;
0040 #if QT_CONFIG(regularexpression)
0041 class QRegularExpression;
0042 #endif
0043 struct QDynamicMetaObjectData;
0044 
0045 typedef QList<QObject*> QObjectList;
0046 
0047 #if QT_CORE_REMOVED_SINCE(6, 7)
0048 Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
0049                                            const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
0050 #endif
0051 Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, QAnyStringView name,
0052                                            const QMetaObject &mo, QList<void *> *list,
0053                                            Qt::FindChildOptions options);
0054 #if QT_CORE_REMOVED_SINCE(6, 7)
0055 Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QMetaObject &mo,
0056                                            QList<void *> *list, Qt::FindChildOptions options);
0057 #endif
0058 Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
0059                                            const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
0060 #if QT_CORE_REMOVED_SINCE(6, 7)
0061 Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
0062 #endif
0063 Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, QAnyStringView name,
0064                                             const QMetaObject &mo, Qt::FindChildOptions options);
0065 
0066 class Q_CORE_EXPORT QObjectData
0067 {
0068     Q_DISABLE_COPY(QObjectData)
0069 public:
0070     QObjectData() = default;
0071     virtual ~QObjectData() = 0;
0072     QObject *q_ptr;
0073     QObject *parent;
0074     QObjectList children;
0075 
0076     uint isWidget : 1;
0077     uint blockSig : 1;
0078     uint wasDeleted : 1;
0079     uint isDeletingChildren : 1;
0080     uint sendChildEvents : 1;
0081     uint receiveChildEvents : 1;
0082     uint isWindow : 1; // for QWindow
0083     uint deleteLaterCalled : 1;
0084     uint isQuickItem : 1;
0085     uint willBeWidget : 1; // for handling widget-specific bits in QObject's ctor
0086     uint wasWidget : 1; // for properly cleaning up in QObject's dtor
0087     uint receiveParentEvents: 1;
0088     uint unused : 20;
0089     QAtomicInt postedEvents;
0090     QDynamicMetaObjectData *metaObject;
0091     QBindingStorage bindingStorage;
0092 
0093 #if QT_CORE_REMOVED_SINCE(6, 9) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
0094     QMetaObject *dynamicMetaObject() const;
0095 #else
0096     const QMetaObject *dynamicMetaObject() const;
0097 #endif
0098 
0099 #ifdef QT_DEBUG
0100     enum { CheckForParentChildLoopsWarnDepth = 4096 };
0101 #endif
0102 };
0103 
0104 class Q_CORE_EXPORT QObject
0105 {
0106     Q_OBJECT
0107 
0108     Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged
0109                BINDABLE bindableObjectName)
0110     Q_DECLARE_PRIVATE(QObject)
0111 
0112 public:
0113     Q_INVOKABLE explicit QObject(QObject *parent = nullptr);
0114     virtual ~QObject();
0115 
0116     virtual bool event(QEvent *event);
0117     virtual bool eventFilter(QObject *watched, QEvent *event);
0118 
0119 #if defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
0120     static QString tr(const char *sourceText, const char * = nullptr, int = -1)
0121         { return QString::fromUtf8(sourceText); }
0122 #endif // QT_NO_TRANSLATION
0123 
0124     QString objectName() const;
0125 #if QT_CORE_REMOVED_SINCE(6, 4)
0126     void setObjectName(const QString &name);
0127 #endif
0128     Q_WEAK_OVERLOAD
0129     void setObjectName(const QString &name) { doSetObjectName(name); }
0130     void setObjectName(QAnyStringView name);
0131     QBindable<QString> bindableObjectName();
0132 
0133     inline bool isWidgetType() const { return d_ptr->isWidget; }
0134     inline bool isWindowType() const { return d_ptr->isWindow; }
0135     inline bool isQuickItemType() const { return d_ptr->isQuickItem; }
0136 
0137     inline bool signalsBlocked() const noexcept { return d_ptr->blockSig; }
0138     bool blockSignals(bool b) noexcept;
0139 
0140     QThread *thread() const;
0141 #if QT_CORE_REMOVED_SINCE(6, 7)
0142     void moveToThread(QThread *thread);
0143 #endif
0144     bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL);
0145 
0146     int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
0147 
0148 #if QT_CORE_REMOVED_SINCE(6, 8)
0149     int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer);
0150 #endif
0151     int startTimer(std::chrono::nanoseconds time, Qt::TimerType timerType = Qt::CoarseTimer);
0152 
0153     void killTimer(int id);
0154     void killTimer(Qt::TimerId id);
0155 
0156     template<typename T>
0157     T findChild(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
0158     {
0159         typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
0160         static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
0161                           "No Q_OBJECT in the class passed to QObject::findChild");
0162         return static_cast<T>(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options));
0163     }
0164 
0165     template<typename T>
0166     QList<T> findChildren(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
0167     {
0168         typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
0169         static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
0170                           "No Q_OBJECT in the class passed to QObject::findChildren");
0171         QList<T> list;
0172         qt_qFindChildren_helper(this, aName, ObjType::staticMetaObject,
0173                                 reinterpret_cast<QList<void *> *>(&list), options);
0174         return list;
0175     }
0176 
0177     template<typename T>
0178     T findChild(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
0179     {
0180         return findChild<T>({}, options);
0181     }
0182 
0183     template<typename T>
0184     QList<T> findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
0185     {
0186         return findChildren<T>(QAnyStringView{}, options);
0187     }
0188 
0189 #if QT_CONFIG(regularexpression)
0190     template<typename T>
0191     inline QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
0192     {
0193         typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
0194         static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
0195                           "No Q_OBJECT in the class passed to QObject::findChildren");
0196         QList<T> list;
0197         qt_qFindChildren_helper(this, re, ObjType::staticMetaObject,
0198                                 reinterpret_cast<QList<void *> *>(&list), options);
0199         return list;
0200     }
0201 #endif // QT_CONFIG(regularexpression)
0202 
0203     inline const QObjectList &children() const { return d_ptr->children; }
0204 
0205     void setParent(QObject *parent);
0206     void installEventFilter(QObject *filterObj);
0207     void removeEventFilter(QObject *obj);
0208 
0209     static QMetaObject::Connection connect(const QObject *sender, const char *signal,
0210                         const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
0211 
0212     static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
0213                         const QObject *receiver, const QMetaMethod &method,
0214                         Qt::ConnectionType type = Qt::AutoConnection);
0215 
0216     inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
0217                         const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
0218 
0219 #ifdef Q_QDOC
0220     template<typename PointerToMemberFunction>
0221     static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
0222     template<typename PointerToMemberFunction, typename Functor>
0223     static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor);
0224     template<typename PointerToMemberFunction, typename Functor>
0225     static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
0226 #else
0227     //connect with context
0228     template <typename Func1, typename Func2>
0229     static inline QMetaObject::Connection
0230         connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
0231                 const typename QtPrivate::ContextTypeForFunctor<Func2>::ContextType *context, Func2 &&slot,
0232                 Qt::ConnectionType type = Qt::AutoConnection)
0233     {
0234         typedef QtPrivate::FunctionPointer<Func1> SignalType;
0235         typedef QtPrivate::FunctionPointer<std::decay_t<Func2>> SlotType;
0236 
0237         if constexpr (SlotType::ArgumentCount != -1) {
0238             static_assert((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
0239                             "Return type of the slot is not compatible with the return type of the signal.");
0240         } else {
0241             constexpr int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<std::decay_t<Func2>, typename SignalType::Arguments>::Value;
0242             [[maybe_unused]]
0243             constexpr int SlotArgumentCount = (FunctorArgumentCount >= 0) ? FunctorArgumentCount : 0;
0244             typedef typename QtPrivate::FunctorReturnType<std::decay_t<Func2>, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotArgumentCount>::Value>::type SlotReturnType;
0245 
0246             static_assert((QtPrivate::AreArgumentsCompatible<SlotReturnType, typename SignalType::ReturnType>::value),
0247                             "Return type of the slot is not compatible with the return type of the signal.");
0248         }
0249 
0250         static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
0251                           "No Q_OBJECT in the class with the signal");
0252 
0253         //compilation error if the arguments does not match.
0254         static_assert(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
0255                           "The slot requires more arguments than the signal provides.");
0256 
0257         const int *types = nullptr;
0258         if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
0259             types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
0260 
0261         void **pSlot = nullptr;
0262         if constexpr (std::is_member_function_pointer_v<std::decay_t<Func2>>) {
0263             pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
0264         } else {
0265             Q_ASSERT_X((type & Qt::UniqueConnection) == 0, "",
0266                        "QObject::connect: Unique connection requires the slot to be a pointer to "
0267                        "a member function of a QObject subclass.");
0268         }
0269 
0270         return connectImpl(sender, reinterpret_cast<void **>(&signal), context, pSlot,
0271                            QtPrivate::makeCallableObject<Func1>(std::forward<Func2>(slot)),
0272                            type, types, &SignalType::Object::staticMetaObject);
0273     }
0274 
0275 #ifndef QT_NO_CONTEXTLESS_CONNECT
0276     //connect without context
0277     template <typename Func1, typename Func2>
0278     static inline QMetaObject::Connection
0279         connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 &&slot)
0280     {
0281         return connect(sender, signal, sender, std::forward<Func2>(slot), Qt::DirectConnection);
0282     }
0283 #endif // QT_NO_CONTEXTLESS_CONNECT
0284 #endif //Q_QDOC
0285 
0286     static bool disconnect(const QObject *sender, const char *signal,
0287                            const QObject *receiver, const char *member);
0288     static bool disconnect(const QObject *sender, const QMetaMethod &signal,
0289                            const QObject *receiver, const QMetaMethod &member);
0290     inline bool disconnect(const char *signal = nullptr,
0291                            const QObject *receiver = nullptr, const char *member = nullptr) const
0292         { return disconnect(this, signal, receiver, member); }
0293     inline bool disconnect(const QObject *receiver, const char *member = nullptr) const
0294         { return disconnect(this, nullptr, receiver, member); }
0295     static bool disconnect(const QMetaObject::Connection &);
0296 
0297 #ifdef Q_QDOC
0298     template<typename PointerToMemberFunction>
0299     static bool disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method);
0300 #else
0301     template <typename Func1, typename Func2>
0302     static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
0303                                   const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot)
0304     {
0305         typedef QtPrivate::FunctionPointer<Func1> SignalType;
0306         typedef QtPrivate::FunctionPointer<Func2> SlotType;
0307 
0308         static_assert(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
0309                           "No Q_OBJECT in the class with the signal");
0310 
0311         //compilation error if the arguments does not match.
0312         static_assert((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
0313                           "Signal and slot arguments are not compatible.");
0314 
0315         return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, reinterpret_cast<void **>(&slot),
0316                               &SignalType::Object::staticMetaObject);
0317     }
0318     template <typename Func1>
0319     static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
0320                                   const QObject *receiver, void **zero)
0321     {
0322         // This is the overload for when one wish to disconnect a signal from any slot. (slot=nullptr)
0323         // Since the function template parameter cannot be deduced from '0', we use a
0324         // dummy void ** parameter that must be equal to 0
0325         Q_ASSERT(!zero);
0326         typedef QtPrivate::FunctionPointer<Func1> SignalType;
0327         return disconnectImpl(sender, reinterpret_cast<void **>(&signal), receiver, zero,
0328                               &SignalType::Object::staticMetaObject);
0329     }
0330 #endif //Q_QDOC
0331 
0332     void dumpObjectTree() const;
0333     void dumpObjectInfo() const;
0334 
0335     QT_CORE_INLINE_SINCE(6, 6)
0336     bool setProperty(const char *name, const QVariant &value);
0337     inline bool setProperty(const char *name, QVariant &&value);
0338     QVariant property(const char *name) const;
0339     QList<QByteArray> dynamicPropertyNames() const;
0340     QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; }
0341     const QBindingStorage *bindingStorage() const { return &d_ptr->bindingStorage; }
0342 
0343 Q_SIGNALS:
0344     void destroyed(QObject * = nullptr);
0345     void objectNameChanged(const QString &objectName, QPrivateSignal);
0346 
0347 public:
0348     inline QObject *parent() const { return d_ptr->parent; }
0349 
0350     inline bool inherits(const char *classname) const
0351     {
0352         return const_cast<QObject *>(this)->qt_metacast(classname) != nullptr;
0353     }
0354 
0355 public Q_SLOTS:
0356     void deleteLater();
0357 
0358 protected:
0359     QObject *sender() const;
0360     int senderSignalIndex() const;
0361     int receivers(const char *signal) const;
0362     bool isSignalConnected(const QMetaMethod &signal) const;
0363 
0364     virtual void timerEvent(QTimerEvent *event);
0365     virtual void childEvent(QChildEvent *event);
0366     virtual void customEvent(QEvent *event);
0367 
0368     virtual void connectNotify(const QMetaMethod &signal);
0369     virtual void disconnectNotify(const QMetaMethod &signal);
0370 
0371 protected:
0372     QObject(QObjectPrivate &dd, QObject *parent = nullptr);
0373 
0374 protected:
0375     QScopedPointer<QObjectData> d_ptr;
0376 
0377     friend struct QMetaObject;
0378     friend struct QMetaObjectPrivate;
0379     friend class QMetaCallEvent;
0380     friend class QApplication;
0381     friend class QApplicationPrivate;
0382     friend class QCoreApplication;
0383     friend class QCoreApplicationPrivate;
0384     friend class QWidget;
0385     friend class QAccessibleWidget;
0386     friend class QThreadData;
0387 
0388 private:
0389     void doSetObjectName(const QString &name);
0390     bool doSetProperty(const char *name, const QVariant *lvalue, QVariant *rvalue);
0391 
0392     Q_DISABLE_COPY(QObject)
0393 
0394 private:
0395     static QMetaObject::Connection connectImpl(const QObject *sender, void **signal,
0396                                                const QObject *receiver, void **slotPtr,
0397                                                QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type,
0398                                                const int *types, const QMetaObject *senderMetaObject);
0399 
0400     static bool disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot,
0401                                const QMetaObject *senderMetaObject);
0402 
0403 };
0404 
0405 inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
0406                                             const char *amember, Qt::ConnectionType atype) const
0407 { return connect(asender, asignal, this, amember, atype); }
0408 
0409 #if QT_CORE_INLINE_IMPL_SINCE(6, 6)
0410 bool QObject::setProperty(const char *name, const QVariant &value)
0411 {
0412     return doSetProperty(name, &value, nullptr);
0413 }
0414 #endif // inline since 6.6
0415 bool QObject::setProperty(const char *name, QVariant &&value)
0416 {
0417     return doSetProperty(name, &value, &value);
0418 }
0419 
0420 template <class T>
0421 inline T qobject_cast(QObject *object)
0422 {
0423     static_assert(std::is_pointer_v<T>,
0424                   "qobject_cast requires to cast towards a pointer type");
0425     typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
0426     static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
0427                     "qobject_cast requires the type to have a Q_OBJECT macro");
0428     return static_cast<T>(ObjType::staticMetaObject.cast(object));
0429 }
0430 
0431 template <class T>
0432 inline T qobject_cast(const QObject *object)
0433 {
0434     static_assert(std::is_pointer_v<T>,
0435                   "qobject_cast requires to cast towards a pointer type");
0436     static_assert(std::is_const_v<std::remove_pointer_t<T>>,
0437                   "qobject_cast cannot cast away constness (use const_cast)");
0438     typedef typename std::remove_cv<typename std::remove_pointer<T>::type>::type ObjType;
0439     static_assert(QtPrivate::HasQ_OBJECT_Macro<ObjType>::Value,
0440                       "qobject_cast requires the type to have a Q_OBJECT macro");
0441     return static_cast<T>(ObjType::staticMetaObject.cast(object));
0442 }
0443 
0444 
0445 template <class T> constexpr const char * qobject_interface_iid() = delete;
0446 template <class T> inline T *
0447 qobject_iid_cast(QObject *object, const char *IId = qobject_interface_iid<T *>())
0448 {
0449     return reinterpret_cast<T *>((object ? object->qt_metacast(IId) : nullptr));
0450 }
0451 template <class T> inline std::enable_if_t<std::is_const<T>::value, T *>
0452 qobject_iid_cast(const QObject *object)
0453 {
0454     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
0455     QObject *o = const_cast<QObject *>(object);
0456     return qobject_iid_cast<std::remove_cv_t<T>>(o);
0457 }
0458 
0459 #if defined(Q_QDOC)
0460 #  define Q_DECLARE_INTERFACE(IFace, IId)
0461 #elif !defined(Q_MOC_RUN)
0462 #  define Q_DECLARE_INTERFACE(IFace, IId) \
0463     template <> constexpr const char *qobject_interface_iid<IFace *>() \
0464     { return IId; } \
0465     template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
0466     { return qobject_iid_cast<IFace>(object); } \
0467     template <> inline const IFace *qobject_cast<const IFace *>(const QObject *object) \
0468     { return qobject_iid_cast<const IFace>(object); }
0469 #endif // Q_MOC_RUN
0470 
0471 inline const QBindingStorage *qGetBindingStorage(const QObject *o)
0472 {
0473     return o->bindingStorage();
0474 }
0475 inline QBindingStorage *qGetBindingStorage(QObject *o)
0476 {
0477     return o->bindingStorage();
0478 }
0479 
0480 #ifndef QT_NO_DEBUG_STREAM
0481 Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
0482 #endif
0483 
0484 class QSignalBlocker
0485 {
0486 public:
0487     Q_NODISCARD_CTOR
0488     inline explicit QSignalBlocker(QObject *o) noexcept;
0489     Q_NODISCARD_CTOR
0490     inline explicit QSignalBlocker(QObject &o) noexcept;
0491     inline ~QSignalBlocker();
0492 
0493     Q_NODISCARD_CTOR
0494     inline QSignalBlocker(QSignalBlocker &&other) noexcept;
0495     inline QSignalBlocker &operator=(QSignalBlocker &&other) noexcept;
0496 
0497     inline void reblock() noexcept;
0498     inline void unblock() noexcept;
0499     inline void dismiss() noexcept;
0500 
0501 private:
0502     Q_DISABLE_COPY(QSignalBlocker)
0503     QObject *m_o;
0504     bool m_blocked;
0505     bool m_inhibited;
0506 };
0507 
0508 QSignalBlocker::QSignalBlocker(QObject *o) noexcept
0509     : m_o(o),
0510       m_blocked(o && o->blockSignals(true)),
0511       m_inhibited(false)
0512 {}
0513 
0514 QSignalBlocker::QSignalBlocker(QObject &o) noexcept
0515     : m_o(&o),
0516       m_blocked(o.blockSignals(true)),
0517       m_inhibited(false)
0518 {}
0519 
0520 QSignalBlocker::QSignalBlocker(QSignalBlocker &&other) noexcept
0521     : m_o(other.m_o),
0522       m_blocked(other.m_blocked),
0523       m_inhibited(other.m_inhibited)
0524 {
0525     other.m_o = nullptr;
0526 }
0527 
0528 QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other) noexcept
0529 {
0530     if (this != &other) {
0531         // if both *this and other block the same object's signals:
0532         // unblock *this iff our dtor would unblock, but other's wouldn't
0533         if (m_o != other.m_o || (!m_inhibited && other.m_inhibited))
0534             unblock();
0535         m_o = other.m_o;
0536         m_blocked = other.m_blocked;
0537         m_inhibited = other.m_inhibited;
0538         // disable other:
0539         other.m_o = nullptr;
0540     }
0541     return *this;
0542 }
0543 
0544 QSignalBlocker::~QSignalBlocker()
0545 {
0546     if (m_o && !m_inhibited)
0547         m_o->blockSignals(m_blocked);
0548 }
0549 
0550 void QSignalBlocker::reblock() noexcept
0551 {
0552     if (m_o)
0553         m_o->blockSignals(true);
0554     m_inhibited = false;
0555 }
0556 
0557 void QSignalBlocker::unblock() noexcept
0558 {
0559     if (m_o)
0560         m_o->blockSignals(m_blocked);
0561     m_inhibited = true;
0562 }
0563 
0564 void QSignalBlocker::dismiss() noexcept
0565 {
0566     m_o = nullptr;
0567 }
0568 
0569 namespace QtPrivate {
0570     inline QObject & deref_for_methodcall(QObject &o) { return  o; }
0571     inline QObject & deref_for_methodcall(QObject *o) { return *o; }
0572 }
0573 #define Q_SET_OBJECT_NAME(obj) QT_PREPEND_NAMESPACE(QtPrivate)::deref_for_methodcall(obj).setObjectName(QLatin1StringView(#obj))
0574 
0575 QT_END_NAMESPACE
0576 
0577 #endif
0578 
0579 #endif // QOBJECT_H