1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qobject_p.h"
44 #include "qmetaobject_p.h"
46 #include "qabstracteventdispatcher.h"
47 #include "qabstracteventdispatcher_p.h"
48 #include "qcoreapplication.h"
49 #include "qcoreapplication_p.h"
51 #include "qmetaobject.h"
53 #include <qregularexpression.h>
55 #include <private/qthread_p.h>
59 #include <qvarlengtharray.h>
61 #include <qsemaphore.h>
62 #include <qsharedpointer.h>
64 #include <private/qorderedmutexlocker_p.h>
73 static int DIRECT_CONNECTION_ONLY = 0;
75 static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
77 int *types = new int [typeNames.count() + 1];
79 for (int i = 0; i < typeNames.count(); ++i) {
80 const QByteArray typeName = typeNames.at(i);
81 if (typeName.endsWith('*'))
82 types[i] = QMetaType::VoidStar;
84 types[i] = QMetaType::type(typeName);
87 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
88 "(Make sure '%s' is registered using qRegisterMetaType().)",
89 typeName.constData(), typeName.constData());
94 types[typeNames.count()] = 0;
99 static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc)
101 QScopedArrayPointer<int> types(new int [argc + 1]);
102 for (int i = 0; i < argc; ++i) {
103 const QArgumentType &type = argumentTypes[i];
105 types[i] = type.type();
106 else if (type.name().endsWith('*'))
107 types[i] = QMetaType::VoidStar;
109 types[i] = QMetaType::type(type.name());
112 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
113 "(Make sure '%s' is registered using qRegisterMetaType().)",
114 type.name().constData(), type.name().constData());
123 static QBasicMutex _q_ObjectMutexPool[131];
126 * mutex to be locked when accessing the connectionlists or the senders list
128 static inline QMutex *signalSlotLock(const QObject *o)
130 return static_cast<QMutex *>(&_q_ObjectMutexPool[
131 uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]);
134 extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
137 extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
140 struct QConnectionSenderSwitcher {
142 QObjectPrivate::Sender *previousSender;
143 QObjectPrivate::Sender currentSender;
146 inline QConnectionSenderSwitcher() : switched(false) {}
148 inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id)
150 switchSender(receiver, sender, signal_absolute_id);
153 inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id)
155 this->receiver = receiver;
156 currentSender.sender = sender;
157 currentSender.signal = signal_absolute_id;
158 currentSender.ref = 1;
159 previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender);
163 inline ~QConnectionSenderSwitcher()
166 QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender);
169 Q_DISABLE_COPY(QConnectionSenderSwitcher)
173 void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
174 void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
175 void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
176 int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
178 QObjectData::~QObjectData() {}
180 QMetaObject *QObjectData::dynamicMetaObject() const
182 return metaObject->toDynamicMetaObject(q_ptr);
185 QObjectPrivate::QObjectPrivate(int version)
186 : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
188 if (version != QObjectPrivateVersion)
189 qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
190 version, QObjectPrivateVersion);
192 // QObjectData initialization
194 parent = 0; // no parent yet. It is set by setParent()
195 isWidget = false; // assume not a widget object
196 blockSig = false; // not blocking signals
197 wasDeleted = false; // double-delete catcher
198 isDeletingChildren = false; // set by deleteChildren()
199 sendChildEvents = true; // if we should send ChildInsert and ChildRemove events to parent
200 receiveChildEvents = true;
203 connectedSignals[0] = connectedSignals[1] = 0;
208 QObjectPrivate::~QObjectPrivate()
210 if (extraData && !extraData->runningTimers.isEmpty()) {
211 // unregister pending timers
212 if (threadData->eventDispatcher)
213 threadData->eventDispatcher->unregisterTimers(q_ptr);
215 // release the timer ids back to the pool
216 for (int i = 0; i < extraData->runningTimers.size(); ++i)
217 QAbstractEventDispatcherPrivate::releaseTimerId(extraData->runningTimers.at(i));
221 QCoreApplication::removePostedEvents(q_ptr, 0);
225 if (metaObject) metaObject->objectDestroyed(q_ptr);
227 #ifndef QT_NO_USERDATA
229 qDeleteAll(extraData->userData);
235 For a given metaobject, compute the signal offset, and the method offset (including signals)
237 static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int *methodOffset)
239 *signalOffset = *methodOffset = 0;
240 const QMetaObject *m = metaobject->d.superdata;
242 const QMetaObjectPrivate *d = QMetaObjectPrivate::get(m);
243 *methodOffset += d->methodCount;
244 Q_ASSERT(d->revision >= 4);
245 *signalOffset += d->signalCount;
251 This vector contains the all connections from an object.
253 Each object may have one vector containing the lists of
254 connections for a given signal. The index in the vector correspond
255 to the signal index. The signal index is the one returned by
256 QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal).
257 Negative index means connections to all signals.
259 This vector is protected by the object mutex (signalSlotMutexes())
261 Each Connection is also part of a 'senders' linked list. The mutex
262 of the receiver must be locked when touching the pointers of this
265 class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList>
268 bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse
269 bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
270 int inUse; //number of functions that are currently accessing this object or its connections
271 QObjectPrivate::ConnectionList allsignals;
273 QObjectConnectionListVector()
274 : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0)
277 QObjectPrivate::ConnectionList &operator[](int at)
281 return QVector<QObjectPrivate::ConnectionList>::operator[](at);
285 // Used by QAccessibleWidget
286 bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
289 int signal_index = signalIndex(signal);
290 if (signal_index < 0)
292 QMutexLocker locker(signalSlotLock(q));
293 if (connectionLists) {
294 if (signal_index < connectionLists->count()) {
295 const QObjectPrivate::Connection *c =
296 connectionLists->at(signal_index).first;
299 if (c->receiver == receiver)
301 c = c->nextConnectionList;
308 // Used by QAccessibleWidget
309 QObjectList QObjectPrivate::receiverList(const char *signal) const
312 QObjectList returnValue;
313 int signal_index = signalIndex(signal);
314 if (signal_index < 0)
316 QMutexLocker locker(signalSlotLock(q));
317 if (connectionLists) {
318 if (signal_index < connectionLists->count()) {
319 const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
323 returnValue << c->receiver;
324 c = c->nextConnectionList;
331 // Used by QAccessibleWidget
332 QObjectList QObjectPrivate::senderList() const
334 QObjectList returnValue;
335 QMutexLocker locker(signalSlotLock(q_func()));
336 for (Connection *c = senders; c; c = c->next)
337 returnValue << c->sender;
342 Add the connection \a c to to the list of connections of the sender's object
343 for the specified \a signal
345 The signalSlotLock() of the sender and receiver must be locked while calling
348 Will also add the connection in the sender's list of the receiver.
350 void QObjectPrivate::addConnection(int signal, Connection *c)
352 Q_ASSERT(c->sender == q_ptr);
353 if (!connectionLists)
354 connectionLists = new QObjectConnectionListVector();
355 if (signal >= connectionLists->count())
356 connectionLists->resize(signal + 1);
358 ConnectionList &connectionList = (*connectionLists)[signal];
359 if (connectionList.last) {
360 connectionList.last->nextConnectionList = c;
362 connectionList.first = c;
364 connectionList.last = c;
366 cleanConnectionLists();
368 c->prev = &(QObjectPrivate::get(c->receiver)->senders);
372 c->next->prev = &c->next;
375 connectedSignals[0] = connectedSignals[1] = ~0;
376 } else if (signal < (int)sizeof(connectedSignals) * 8) {
377 connectedSignals[signal >> 5] |= (1 << (signal & 0x1f));
381 void QObjectPrivate::cleanConnectionLists()
383 if (connectionLists->dirty && !connectionLists->inUse) {
384 // remove broken connections
385 for (int signal = -1; signal < connectionLists->count(); ++signal) {
386 QObjectPrivate::ConnectionList &connectionList =
387 (*connectionLists)[signal];
389 // Set to the last entry in the connection list that was *not*
390 // deleted. This is needed to update the list's last pointer
391 // at the end of the cleanup.
392 QObjectPrivate::Connection *last = 0;
394 QObjectPrivate::Connection **prev = &connectionList.first;
395 QObjectPrivate::Connection *c = *prev;
399 prev = &c->nextConnectionList;
402 QObjectPrivate::Connection *next = c->nextConnectionList;
409 // Correct the connection list's last pointer.
410 // As conectionList.last could equal last, this could be a noop
411 connectionList.last = last;
413 connectionLists->dirty = false;
419 QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
420 const QObject *sender, int signalId,
421 int nargs, int *types, void **args, QSemaphore *semaphore)
422 : QEvent(MetaCall), slotObj_(0), sender_(sender), signalId_(signalId),
423 nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
424 callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
429 QMetaCallEvent::QMetaCallEvent(QObject::QSlotObjectBase *slotO, const QObject *sender, int signalId,
430 int nargs, int *types, void **args, QSemaphore *semaphore)
431 : QEvent(MetaCall), slotObj_(slotO), sender_(sender), signalId_(signalId),
432 nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
433 callFunction_(0), method_offset_(0), method_relative_(-1)
441 QMetaCallEvent::~QMetaCallEvent()
444 for (int i = 0; i < nargs_; ++i) {
445 if (types_[i] && args_[i])
446 QMetaType::destroy(types_[i], args_[i]);
453 semaphore_->release();
455 if (slotObj_ && !slotObj_->ref.deref())
461 void QMetaCallEvent::placeMetaCall(QObject *object)
464 slotObj_->call(object, args_);
465 } else if (callFunction_ && method_offset_ <= object->metaObject()->methodOffset()) {
466 callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_);
468 QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_);
474 \brief The QObject class is the base class of all Qt objects.
480 QObject is the heart of the Qt \l{Object Model}. The central
481 feature in this model is a very powerful mechanism for seamless
482 object communication called \l{signals and slots}. You can
483 connect a signal to a slot with connect() and destroy the
484 connection with disconnect(). To avoid never ending notification
485 loops you can temporarily block signals with blockSignals(). The
486 protected functions connectNotify() and disconnectNotify() make
487 it possible to track connections.
489 QObjects organize themselves in \l {Object Trees & Ownership}
490 {object trees}. When you create a QObject with another object as
491 parent, the object will automatically add itself to the parent's
492 children() list. The parent takes ownership of the object; i.e.,
493 it will automatically delete its children in its destructor. You
494 can look for an object by name and optionally type using
495 findChild() or findChildren().
497 Every object has an objectName() and its class name can be found
498 via the corresponding metaObject() (see QMetaObject::className()).
499 You can determine whether the object's class inherits another
500 class in the QObject inheritance hierarchy by using the
503 When an object is deleted, it emits a destroyed() signal. You can
504 catch this signal to avoid dangling references to QObjects.
506 QObjects can receive events through event() and filter the events
507 of other objects. See installEventFilter() and eventFilter() for
508 details. A convenience handler, childEvent(), can be reimplemented
509 to catch child events.
511 Events are delivered in the thread in which the object was
512 created; see \l{Thread Support in Qt} and thread() for details.
513 Note that event processing is not done at all for QObjects with no
514 thread affinity (thread() returns zero). Use the moveToThread()
515 function to change the thread affinity for an object and its
516 children (the object cannot be moved if it has a parent).
518 Last but not least, QObject provides the basic timer support in
519 Qt; see QTimer for high-level support for timers.
521 Notice that the Q_OBJECT macro is mandatory for any object that
522 implements signals, slots or properties. You also need to run the
523 \l{moc}{Meta Object Compiler} on the source file. We strongly
524 recommend the use of this macro in all subclasses of QObject
525 regardless of whether or not they actually use signals, slots and
526 properties, since failure to do so may lead certain functions to
527 exhibit strange behavior.
529 All Qt widgets inherit QObject. The convenience function
530 isWidgetType() returns whether an object is actually a widget. It
532 \l{qobject_cast()}{qobject_cast}<QWidget *>(\e{obj}) or
533 \e{obj}->\l{inherits()}{inherits}("QWidget").
535 Some QObject functions, e.g. children(), return a QObjectList.
536 QObjectList is a typedef for QList<QObject *>.
538 \target No copy constructor
539 \section1 No copy constructor or assignment operator
541 QObject has neither a copy constructor nor an assignment operator.
542 This is by design. Actually, they are declared, but in a
543 \c{private} section with the macro Q_DISABLE_COPY(). In fact, all
544 Qt classes derived from QObject (direct or indirect) use this
545 macro to declare their copy constructor and assignment operator to
546 be private. The reasoning is found in the discussion on
547 \l{Identity vs Value} {Identity vs Value} on the Qt \l{Object
550 The main consequence is that you should use pointers to QObject
551 (or to your QObject subclass) where you might otherwise be tempted
552 to use your QObject subclass as a value. For example, without a
553 copy constructor, you can't use a subclass of QObject as the value
554 to be stored in one of the container classes. You must store
557 \section1 Auto-Connection
559 Qt's meta-object system provides a mechanism to automatically connect
560 signals and slots between QObject subclasses and their children. As long
561 as objects are defined with suitable object names, and slots follow a
562 simple naming convention, this connection can be performed at run-time
563 by the QMetaObject::connectSlotsByName() function.
565 \l uic generates code that invokes this function to enable
566 auto-connection to be performed between widgets on forms created
567 with \e{Qt Designer}. More information about using auto-connection with \e{Qt Designer} is
568 given in the \l{Using a Designer UI File in Your Application} section of
569 the \e{Qt Designer} manual.
571 \section1 Dynamic Properties
573 From Qt 4.2, dynamic properties can be added to and removed from QObject
574 instances at run-time. Dynamic properties do not need to be declared at
575 compile-time, yet they provide the same advantages as static properties
576 and are manipulated using the same API - using property() to read them
577 and setProperty() to write them.
579 From Qt 4.3, dynamic properties are supported by
580 \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
581 and both standard Qt widgets and user-created forms can be given dynamic
584 \section1 Internationalization (i18n)
586 All QObject subclasses support Qt's translation features, making it possible
587 to translate an application's user interface into different languages.
589 To make user-visible text translatable, it must be wrapped in calls to
590 the tr() function. This is explained in detail in the
591 \l{Writing Source Code for Translation} document.
593 \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
594 \sa {Object Trees & Ownership}
600 Returns a pointer to the object named \a name that inherits \a
601 type and with a given \a parent.
603 Returns 0 if there is no such child.
605 \snippet code/src_corelib_kernel_qobject.cpp 0
608 void *qt_find_obj_child(QObject *parent, const char *type, const QString &name)
610 QObjectList list = parent->children();
611 if (list.size() == 0) return 0;
612 for (int i = 0; i < list.size(); ++i) {
613 QObject *obj = list.at(i);
614 if (name == obj->objectName() && obj->inherits(type))
621 /*****************************************************************************
622 QObject member functions
623 *****************************************************************************/
625 // check the constructor's parent thread argument
626 static bool check_parent_thread(QObject *parent,
627 QThreadData *parentThreadData,
628 QThreadData *currentThreadData)
630 if (parent && parentThreadData != currentThreadData) {
631 QThread *parentThread = parentThreadData->thread;
632 QThread *currentThread = currentThreadData->thread;
633 qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
634 "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
635 parent->metaObject()->className(),
637 parentThread ? parentThread->metaObject()->className() : "QThread",
639 currentThread ? currentThread->metaObject()->className() : "QThread",
647 Constructs an object with parent object \a parent.
649 The parent of an object may be viewed as the object's owner. For
650 instance, a \l{QDialog}{dialog box} is the parent of the \uicontrol{OK}
651 and \uicontrol{Cancel} buttons it contains.
653 The destructor of a parent object destroys all child objects.
655 Setting \a parent to 0 constructs an object with no parent. If the
656 object is a widget, it will become a top-level window.
658 \sa parent(), findChild(), findChildren()
661 QObject::QObject(QObject *parent)
662 : d_ptr(new QObjectPrivate)
666 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
667 d->threadData->ref();
670 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
674 d->threadData->deref();
683 QObject::QObject(QObjectPrivate &dd, QObject *parent)
688 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
689 d->threadData->ref();
692 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
697 d->parent->d_func()->children.append(this);
699 // no events sent here, this is done at the end of the QWidget constructor
704 d->threadData->deref();
712 Destroys the object, deleting all its child objects.
714 All signals to and from the object are automatically disconnected, and
715 any pending posted events for the object are removed from the event
716 queue. However, it is often safer to use deleteLater() rather than
717 deleting a QObject subclass directly.
719 \warning All child objects are deleted. If any of these objects
720 are on the stack or global, sooner or later your program will
721 crash. We do not recommend holding pointers to child objects from
722 outside the parent. If you still do, the destroyed() signal gives
723 you an opportunity to detect when an object is destroyed.
725 \warning Deleting a QObject while pending events are waiting to
726 be delivered can cause a crash. You must not delete the QObject
727 directly if it exists in a different thread than the one currently
728 executing. Use deleteLater() instead, which will cause the event
729 loop to delete the object after all pending events have been
738 d->wasDeleted = true;
739 d->blockSig = 0; // unblock signals so we always emit destroyed()
741 QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.load();
742 if (sharedRefcount) {
743 if (sharedRefcount->strongref.load() > 0) {
744 qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash.");
745 // but continue deleting, it's too late to stop anyway
748 // indicate to all QWeakPointers that this QObject has now been deleted
749 sharedRefcount->strongref.store(0);
750 if (!sharedRefcount->weakref.deref())
751 delete sharedRefcount;
754 if (d->isSignalConnected(0)) {
756 emit destroyed(this);
758 // all the signal/slots connections are still in place - if we don't
759 // quit now, we will crash pretty soon.
760 qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
765 if (d->declarativeData)
766 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
768 // set ref to zero to indicate that this object has been deleted
769 if (d->currentSender != 0)
770 d->currentSender->ref = 0;
771 d->currentSender = 0;
773 if (d->connectionLists || d->senders) {
774 QMutex *signalSlotMutex = signalSlotLock(this);
775 QMutexLocker locker(signalSlotMutex);
777 // disconnect all receivers
778 if (d->connectionLists) {
779 ++d->connectionLists->inUse;
780 int connectionListsCount = d->connectionLists->count();
781 for (int signal = -1; signal < connectionListsCount; ++signal) {
782 QObjectPrivate::ConnectionList &connectionList =
783 (*d->connectionLists)[signal];
785 while (QObjectPrivate::Connection *c = connectionList.first) {
787 connectionList.first = c->nextConnectionList;
792 QMutex *m = signalSlotLock(c->receiver);
793 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
797 if (c->next) c->next->prev = c->prev;
803 connectionList.first = c->nextConnectionList;
808 if (!--d->connectionLists->inUse) {
809 delete d->connectionLists;
811 d->connectionLists->orphaned = true;
813 d->connectionLists = 0;
816 // disconnect all senders
817 QObjectPrivate::Connection *node = d->senders;
819 QObject *sender = node->sender;
820 QMutex *m = signalSlotLock(sender);
822 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
823 //the node has maybe been removed while the mutex was unlocked in relock?
824 if (!node || node->sender != sender) {
829 QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
831 senderLists->dirty = true;
839 if (!d->children.isEmpty())
842 qt_removeObject(this);
844 if (d->parent) // remove it from parent object
845 d->setParent_helper(0);
848 QObjectPrivate::Connection::~Connection()
850 if (ownArgumentTypes) {
851 const int *v = argumentTypes.load();
852 if (v != &DIRECT_CONNECTION_ONLY)
855 if (isSlotObject && !slotObj->ref.deref())
861 \fn QMetaObject *QObject::metaObject() const
863 Returns a pointer to the meta-object of this object.
865 A meta-object contains information about a class that inherits
866 QObject, e.g. class name, superclass name, properties, signals and
867 slots. Every QObject subclass that contains the Q_OBJECT macro will have a
870 The meta-object information is required by the signal/slot
871 connection mechanism and the property system. The inherits()
872 function also makes use of the meta-object.
874 If you have no pointer to an actual object instance but still
875 want to access the meta-object of a class, you can use \l
880 \snippet code/src_corelib_kernel_qobject.cpp 1
886 \variable QObject::staticMetaObject
888 This variable stores the meta-object for the class.
890 A meta-object contains information about a class that inherits
891 QObject, e.g. class name, superclass name, properties, signals and
892 slots. Every class that contains the Q_OBJECT macro will also have
895 The meta-object information is required by the signal/slot
896 connection mechanism and the property system. The inherits()
897 function also makes use of the meta-object.
899 If you have a pointer to an object, you can use metaObject() to
900 retrieve the meta-object associated with that object.
904 \snippet code/src_corelib_kernel_qobject.cpp 2
909 /*! \fn T *qobject_cast<T *>(QObject *object)
912 Returns the given \a object cast to type T if the object is of type
913 T (or of a subclass); otherwise returns 0. If \a object is 0 then
914 it will also return 0.
916 The class T must inherit (directly or indirectly) QObject and be
917 declared with the \l Q_OBJECT macro.
919 A class is considered to inherit itself.
923 \snippet code/src_corelib_kernel_qobject.cpp 3
925 The qobject_cast() function behaves similarly to the standard C++
926 \c dynamic_cast(), with the advantages that it doesn't require
927 RTTI support and it works across dynamic library boundaries.
929 qobject_cast() can also be used in conjunction with interfaces;
930 see the \l{tools/plugandpaint}{Plug & Paint} example for details.
932 \warning If T isn't declared with the Q_OBJECT macro, this
933 function's return value is undefined.
935 \sa QObject::inherits()
939 \fn bool QObject::inherits(const char *className) const
941 Returns true if this object is an instance of a class that
942 inherits \a className or a QObject subclass that inherits \a
943 className; otherwise returns false.
945 A class is considered to inherit itself.
949 \snippet code/src_corelib_kernel_qobject.cpp 4
951 If you need to determine whether an object is an instance of a particular
952 class for the purpose of casting it, consider using qobject_cast<Type *>(object)
955 \sa metaObject(), qobject_cast()
959 \property QObject::objectName
961 \brief the name of this object
963 You can find an object by name (and type) using findChild().
964 You can find a set of objects with findChildren().
966 \snippet code/src_corelib_kernel_qobject.cpp 5
968 By default, this property contains an empty string.
970 \sa metaObject(), QMetaObject::className()
973 QString QObject::objectName() const
976 return d->extraData ? d->extraData->objectName : QString();
980 Sets the object's name to \a name.
982 void QObject::setObjectName(const QString &name)
986 d->extraData = new QObjectPrivate::ExtraData;
988 if (d->extraData->objectName != name) {
989 d->extraData->objectName = name;
990 emit objectNameChanged(d->extraData->objectName);
994 /*! \fn void QObject::objectNameChanged(const QString &objectName)
996 This signal is emitted after the object's name has been changed. The new object name is passed as \a objectName.
998 \sa QObject::objectName
1002 \fn bool QObject::isWidgetType() const
1004 Returns true if the object is a widget; otherwise returns false.
1006 Calling this function is equivalent to calling
1007 inherits("QWidget"), except that it is much faster.
1012 This virtual function receives events to an object and should
1013 return true if the event \a e was recognized and processed.
1015 The event() function can be reimplemented to customize the
1016 behavior of an object.
1018 \sa installEventFilter(), timerEvent(), QApplication::sendEvent(),
1019 QApplication::postEvent(), QWidget::event()
1022 bool QObject::event(QEvent *e)
1024 switch (e->type()) {
1026 timerEvent((QTimerEvent*)e);
1029 case QEvent::ChildAdded:
1030 case QEvent::ChildPolished:
1031 case QEvent::ChildRemoved:
1032 childEvent((QChildEvent*)e);
1035 case QEvent::DeferredDelete:
1036 qDeleteInEventHandler(this);
1039 case QEvent::MetaCall:
1041 QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
1043 QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId());
1045 mce->placeMetaCall(this);
1049 case QEvent::ThreadChange: {
1051 QThreadData *threadData = d->threadData;
1052 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1053 if (eventDispatcher) {
1054 QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
1055 if (!timers.isEmpty()) {
1056 // do not to release our timer ids back to the pool (since the timer ids are moving to a new thread).
1057 eventDispatcher->unregisterTimers(this);
1058 QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
1059 Q_ARG(void*, (new QList<QAbstractEventDispatcher::TimerInfo>(timers))));
1066 if (e->type() >= QEvent::User) {
1076 \fn void QObject::timerEvent(QTimerEvent *event)
1078 This event handler can be reimplemented in a subclass to receive
1079 timer events for the object.
1081 QTimer provides a higher-level interface to the timer
1082 functionality, and also more general information about timers. The
1083 timer event is passed in the \a event parameter.
1085 \sa startTimer(), killTimer(), event()
1088 void QObject::timerEvent(QTimerEvent *)
1094 This event handler can be reimplemented in a subclass to receive
1095 child events. The event is passed in the \a event parameter.
1097 QEvent::ChildAdded and QEvent::ChildRemoved events are sent to
1098 objects when children are added or removed. In both cases you can
1099 only rely on the child being a QObject, or if isWidgetType()
1100 returns true, a QWidget. (This is because, in the
1101 \l{QEvent::ChildAdded}{ChildAdded} case, the child is not yet
1102 fully constructed, and in the \l{QEvent::ChildRemoved}{ChildRemoved}
1103 case it might have been destructed already).
1105 QEvent::ChildPolished events are sent to widgets when children
1106 are polished, or when polished children are added. If you receive
1107 a child polished event, the child's construction is usually
1108 completed. However, this is not guaranteed, and multiple polish
1109 events may be delivered during the execution of a widget's
1112 For every child widget, you receive one
1113 \l{QEvent::ChildAdded}{ChildAdded} event, zero or more
1114 \l{QEvent::ChildPolished}{ChildPolished} events, and one
1115 \l{QEvent::ChildRemoved}{ChildRemoved} event.
1117 The \l{QEvent::ChildPolished}{ChildPolished} event is omitted if
1118 a child is removed immediately after it is added. If a child is
1119 polished several times during construction and destruction, you
1120 may receive several child polished events for the same child,
1121 each time with a different virtual table.
1126 void QObject::childEvent(QChildEvent * /* event */)
1132 This event handler can be reimplemented in a subclass to receive
1133 custom events. Custom events are user-defined events with a type
1134 value at least as large as the QEvent::User item of the
1135 QEvent::Type enum, and is typically a QEvent subclass. The event
1136 is passed in the \a event parameter.
1140 void QObject::customEvent(QEvent * /* event */)
1147 Filters events if this object has been installed as an event
1148 filter for the \a watched object.
1150 In your reimplementation of this function, if you want to filter
1151 the \a event out, i.e. stop it being handled further, return
1152 true; otherwise return false.
1155 \snippet code/src_corelib_kernel_qobject.cpp 6
1157 Notice in the example above that unhandled events are passed to
1158 the base class's eventFilter() function, since the base class
1159 might have reimplemented eventFilter() for its own internal
1162 \warning If you delete the receiver object in this function, be
1163 sure to return true. Otherwise, Qt will forward the event to the
1164 deleted object and the program might crash.
1166 \sa installEventFilter()
1169 bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
1175 \fn bool QObject::signalsBlocked() const
1177 Returns true if signals are blocked; otherwise returns false.
1179 Signals are not blocked by default.
1185 If \a block is true, signals emitted by this object are blocked
1186 (i.e., emitting a signal will not invoke anything connected to it).
1187 If \a block is false, no such blocking will occur.
1189 The return value is the previous value of signalsBlocked().
1191 Note that the destroyed() signal will be emitted even if the signals
1192 for this object have been blocked.
1194 \sa signalsBlocked()
1197 bool QObject::blockSignals(bool block)
1200 bool previous = d->blockSig;
1201 d->blockSig = block;
1206 Returns the thread in which the object lives.
1210 QThread *QObject::thread() const
1212 return d_func()->threadData->thread;
1216 Changes the thread affinity for this object and its children. The
1217 object cannot be moved if it has a parent. Event processing will
1218 continue in the \a targetThread.
1220 To move an object to the main thread, use QApplication::instance()
1221 to retrieve a pointer to the current application, and then use
1222 QApplication::thread() to retrieve the thread in which the
1223 application lives. For example:
1225 \snippet code/src_corelib_kernel_qobject.cpp 7
1227 If \a targetThread is zero, all event processing for this object
1228 and its children stops.
1230 Note that all active timers for the object will be reset. The
1231 timers are first stopped in the current thread and restarted (with
1232 the same interval) in the \a targetThread. As a result, constantly
1233 moving an object between threads can postpone timer events
1236 A QEvent::ThreadChange event is sent to this object just before
1237 the thread affinity is changed. You can handle this event to
1238 perform any special processing. Note that any new events that are
1239 posted to this object will be handled in the \a targetThread.
1241 \warning This function is \e not thread-safe; the current thread
1242 must be same as the current thread affinity. In other words, this
1243 function can only "push" an object from the current thread to
1244 another thread, it cannot "pull" an object from any arbitrary
1245 thread to the current thread.
1249 void QObject::moveToThread(QThread *targetThread)
1253 if (d->threadData->thread == targetThread) {
1254 // object is already in this thread
1258 if (d->parent != 0) {
1259 qWarning("QObject::moveToThread: Cannot move objects with a parent");
1263 qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
1267 QThreadData *currentData = QThreadData::current();
1268 QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0);
1269 if (d->threadData->thread == 0 && currentData == targetData) {
1270 // one exception to the rule: we allow moving objects with no thread affinity to the current thread
1271 currentData = d->threadData;
1272 } else if (d->threadData != currentData) {
1273 qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
1274 "Cannot move to target thread (%p)\n",
1275 currentData->thread, d->threadData->thread, targetData->thread);
1278 qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. "
1279 "Check that all plugins are compiled against the right Qt binaries. Export "
1280 "DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.");
1287 d->moveToThread_helper();
1289 QOrderedMutexLocker locker(¤tData->postEventList.mutex,
1290 &targetData->postEventList.mutex);
1292 // keep currentData alive (since we've got it locked)
1296 d_func()->setThreadData_helper(currentData, targetData);
1300 // now currentData can commit suicide if it wants to
1301 currentData->deref();
1304 void QObjectPrivate::moveToThread_helper()
1307 QEvent e(QEvent::ThreadChange);
1308 QCoreApplication::sendEvent(q, &e);
1309 for (int i = 0; i < children.size(); ++i) {
1310 QObject *child = children.at(i);
1311 child->d_func()->moveToThread_helper();
1315 void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData)
1319 // move posted events
1320 int eventsMoved = 0;
1321 for (int i = 0; i < currentData->postEventList.size(); ++i) {
1322 const QPostEvent &pe = currentData->postEventList.at(i);
1325 if (pe.receiver == q) {
1326 // move this post event to the targetList
1327 targetData->postEventList.addEvent(pe);
1328 const_cast<QPostEvent &>(pe).event = 0;
1332 if (eventsMoved > 0 && targetData->eventDispatcher) {
1333 targetData->canWait = false;
1334 targetData->eventDispatcher->wakeUp();
1337 // the current emitting thread shouldn't restore currentSender after calling moveToThread()
1339 currentSender->ref = 0;
1342 // set new thread data
1344 threadData->deref();
1345 threadData = targetData;
1347 for (int i = 0; i < children.size(); ++i) {
1348 QObject *child = children.at(i);
1349 child->d_func()->setThreadData_helper(currentData, targetData);
1353 void QObjectPrivate::_q_reregisterTimers(void *pointer)
1356 QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
1357 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1358 for (int i = 0; i < timerList->size(); ++i) {
1359 const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
1360 eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
1367 // The timer flag hasTimer is set when startTimer is called.
1368 // It is not reset when killing the timer because more than
1369 // one timer might be active.
1373 Starts a timer and returns a timer identifier, or returns zero if
1374 it could not start a timer.
1376 A timer event will occur every \a interval milliseconds until
1377 killTimer() is called. If \a interval is 0, then the timer event
1378 occurs once every time there are no more window system events to
1381 The virtual timerEvent() function is called with the QTimerEvent
1382 event parameter class when a timer event occurs. Reimplement this
1383 function to get timer events.
1385 If multiple timers are running, the QTimerEvent::timerId() can be
1386 used to find out which timer was activated.
1390 \snippet code/src_corelib_kernel_qobject.cpp 8
1392 Note that QTimer's accuracy depends on the underlying operating system and
1393 hardware. The \a timerType argument allows you to customize the accuracy of
1394 the timer. See Qt::TimerType for information on the different timer types.
1395 Most platforms support an accuracy of 20 milliseconds; some provide more.
1396 If Qt is unable to deliver the requested number of timer events, it will
1397 silently discard some.
1399 The QTimer class provides a high-level programming interface with
1400 single-shot timers and timer signals instead of events. There is
1401 also a QBasicTimer class that is more lightweight than QTimer and
1402 less clumsy than using timer IDs directly.
1404 \sa timerEvent(), killTimer(), QTimer::singleShot()
1407 int QObject::startTimer(int interval, Qt::TimerType timerType)
1412 qWarning("QObject::startTimer: QTimer cannot have a negative interval");
1416 if (!d->threadData->eventDispatcher) {
1417 qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
1420 int timerId = d->threadData->eventDispatcher->registerTimer(interval, timerType, this);
1422 d->extraData = new QObjectPrivate::ExtraData;
1423 d->extraData->runningTimers.append(timerId);
1428 Kills the timer with timer identifier, \a id.
1430 The timer identifier is returned by startTimer() when a timer
1433 \sa timerEvent(), startTimer()
1436 void QObject::killTimer(int id)
1440 int at = d->extraData ? d->extraData->runningTimers.indexOf(id) : -1;
1442 // timer isn't owned by this object
1443 qWarning("QObject::killTimer(): Error: timer id %d is not valid for object %p (%s), timer has not been killed",
1446 qPrintable(objectName()));
1450 if (d->threadData->eventDispatcher)
1451 d->threadData->eventDispatcher->unregisterTimer(id);
1453 d->extraData->runningTimers.remove(at);
1454 QAbstractEventDispatcherPrivate::releaseTimerId(id);
1460 \fn QObject *QObject::parent() const
1462 Returns a pointer to the parent object.
1468 \fn const QObjectList &QObject::children() const
1470 Returns a list of child objects.
1471 The QObjectList class is defined in the \c{<QObject>} header
1472 file as the following:
1474 \quotefromfile kernel/qobject.h
1475 \skipto /typedef .*QObjectList/
1476 \printuntil QObjectList
1478 The first child added is the \l{QList::first()}{first} object in
1479 the list and the last child added is the \l{QList::last()}{last}
1480 object in the list, i.e. new children are appended at the end.
1482 Note that the list order changes when QWidget children are
1483 \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A
1484 widget that is raised becomes the last object in the list, and a
1485 widget that is lowered becomes the first object in the list.
1487 \sa findChild(), findChildren(), parent(), setParent()
1492 \fn T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
1494 Returns the child of this object that can be cast into type T and
1495 that is called \a name, or 0 if there is no such object.
1496 Omitting the \a name argument causes all object names to be matched.
1497 The search is performed recursively, unless \a options specifies the
1498 option FindDirectChildrenOnly.
1500 If there is more than one child matching the search, the most
1501 direct ancestor is returned. If there are several direct
1502 ancestors, it is undefined which one will be returned. In that
1503 case, findChildren() should be used.
1505 This example returns a child \l{QPushButton} of \c{parentWidget}
1506 named \c{"button1"}, even if the button isn't a direct child of
1509 \snippet code/src_corelib_kernel_qobject.cpp 10
1511 This example returns a \l{QListWidget} child of \c{parentWidget}:
1513 \snippet code/src_corelib_kernel_qobject.cpp 11
1515 This example returns a child \l{QPushButton} of \c{parentWidget}
1516 (its direct parent) named \c{"button1"}:
1518 \snippet code/src_corelib_kernel_qobject.cpp 41
1520 This example returns a \l{QListWidget} child of \c{parentWidget},
1523 \snippet code/src_corelib_kernel_qobject.cpp 42
1529 \fn QList<T> QObject::findChildren(const QString &name, Qt::FindChildOptions options) const
1531 Returns all children of this object with the given \a name that can be
1532 cast to type T, or an empty list if there are no such objects.
1533 Omitting the \a name argument causes all object names to be matched.
1534 The search is performed recursively, unless \a options specifies the
1535 option FindDirectChildrenOnly.
1537 The following example shows how to find a list of child \l{QWidget}s of
1538 the specified \c{parentWidget} named \c{widgetname}:
1540 \snippet code/src_corelib_kernel_qobject.cpp 12
1542 This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
1544 \snippet code/src_corelib_kernel_qobject.cpp 13
1546 This example returns all \c{QPushButton}s that are immediate children of \c{parentWidget}:
1548 \snippet code/src_corelib_kernel_qobject.cpp 43
1554 \fn QList<T> QObject::findChildren(const QRegExp ®Exp, Qt::FindChildOptions options) const
1555 \overload findChildren()
1557 Returns the children of this object that can be cast to type T
1558 and that have names matching the regular expression \a regExp,
1559 or an empty list if there are no such objects.
1560 The search is performed recursively, unless \a options specifies the
1561 option FindDirectChildrenOnly.
1565 \fn QList<T> QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options) const
1566 \overload findChildren()
1570 Returns the children of this object that can be cast to type T
1571 and that have names matching the regular expression \a re,
1572 or an empty list if there are no such objects.
1573 The search is performed recursively, unless \a options specifies the
1574 option FindDirectChildrenOnly.
1578 \fn T qFindChild(const QObject *obj, const QString &name)
1580 \overload qFindChildren()
1583 This function is equivalent to
1584 \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
1586 \note This function was provided as a workaround for MSVC 6
1587 which did not support member template functions. It is advised
1588 to use the other form in new code.
1590 \sa QObject::findChild()
1594 \fn QList<T> qFindChildren(const QObject *obj, const QString &name)
1596 \overload qFindChildren()
1599 This function is equivalent to
1600 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
1602 \note This function was provided as a workaround for MSVC 6
1603 which did not support member template functions. It is advised
1604 to use the other form in new code.
1606 \sa QObject::findChildren()
1610 \fn QList<T> qFindChildren(const QObject *obj, const QRegExp ®Exp)
1612 \overload qFindChildren()
1614 This function is equivalent to
1615 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp).
1617 \note This function was provided as a workaround for MSVC 6
1618 which did not support member template functions. It is advised
1619 to use the other form in new code.
1621 \sa QObject::findChildren()
1627 void qt_qFindChildren_helper(const QObject *parent, const QString &name,
1628 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1630 if (!parent || !list)
1632 const QObjectList &children = parent->children();
1634 for (int i = 0; i < children.size(); ++i) {
1635 obj = children.at(i);
1637 if (name.isNull() || obj->objectName() == name)
1640 if (options & Qt::FindChildrenRecursively)
1641 qt_qFindChildren_helper(obj, name, mo, list, options);
1645 #ifndef QT_NO_REGEXP
1649 void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
1650 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1652 if (!parent || !list)
1654 const QObjectList &children = parent->children();
1655 QRegExp reCopy = re;
1657 for (int i = 0; i < children.size(); ++i) {
1658 obj = children.at(i);
1659 if (mo.cast(obj) && reCopy.indexIn(obj->objectName()) != -1)
1662 if (options & Qt::FindChildrenRecursively)
1663 qt_qFindChildren_helper(obj, re, mo, list, options);
1666 #endif // QT_NO_REGEXP
1668 #ifndef QT_NO_REGEXP
1672 void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
1673 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1675 if (!parent || !list)
1677 const QObjectList &children = parent->children();
1679 for (int i = 0; i < children.size(); ++i) {
1680 obj = children.at(i);
1682 QRegularExpressionMatch m = re.match(obj->objectName());
1686 if (options & Qt::FindChildrenRecursively)
1687 qt_qFindChildren_helper(obj, re, mo, list, options);
1690 #endif // QT_NO_REGEXP
1694 QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
1698 const QObjectList &children = parent->children();
1701 for (i = 0; i < children.size(); ++i) {
1702 obj = children.at(i);
1703 if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
1706 if (options & Qt::FindChildrenRecursively) {
1707 for (i = 0; i < children.size(); ++i) {
1708 obj = qt_qFindChild_helper(children.at(i), name, mo, options);
1717 Makes the object a child of \a parent.
1719 \sa QWidget::setParent()
1722 void QObject::setParent(QObject *parent)
1725 Q_ASSERT(!d->isWidget);
1726 d->setParent_helper(parent);
1729 void QObjectPrivate::deleteChildren()
1731 Q_ASSERT_X(!isDeletingChildren, "QObjectPrivate::deleteChildren()", "isDeletingChildren already set, did this function recurse?");
1732 isDeletingChildren = true;
1733 // delete children objects
1734 // don't use qDeleteAll as the destructor of the child might
1736 for (int i = 0; i < children.count(); ++i) {
1737 currentChildBeingDeleted = children.at(i);
1739 delete currentChildBeingDeleted;
1742 currentChildBeingDeleted = 0;
1743 isDeletingChildren = false;
1746 void QObjectPrivate::setParent_helper(QObject *o)
1752 QObjectPrivate *parentD = parent->d_func();
1753 if (parentD->isDeletingChildren && wasDeleted
1754 && parentD->currentChildBeingDeleted == q) {
1755 // don't do anything since QObjectPrivate::deleteChildren() already
1756 // cleared our entry in parentD->children.
1758 const int index = parentD->children.indexOf(q);
1759 if (parentD->isDeletingChildren) {
1760 parentD->children[index] = 0;
1762 parentD->children.removeAt(index);
1763 if (sendChildEvents && parentD->receiveChildEvents) {
1764 QChildEvent e(QEvent::ChildRemoved, q);
1765 QCoreApplication::sendEvent(parent, &e);
1772 // object hierarchies are constrained to a single thread
1773 if (threadData != parent->d_func()->threadData) {
1774 qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");
1778 parent->d_func()->children.append(q);
1779 if(sendChildEvents && parent->d_func()->receiveChildEvents) {
1781 QChildEvent e(QEvent::ChildAdded, q);
1782 QCoreApplication::sendEvent(parent, &e);
1786 if (!isDeletingChildren && declarativeData)
1787 QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
1791 \fn void QObject::installEventFilter(QObject *filterObj)
1793 Installs an event filter \a filterObj on this object. For example:
1794 \snippet code/src_corelib_kernel_qobject.cpp 14
1796 An event filter is an object that receives all events that are
1797 sent to this object. The filter can either stop the event or
1798 forward it to this object. The event filter \a filterObj receives
1799 events via its eventFilter() function. The eventFilter() function
1800 must return true if the event should be filtered, (i.e. stopped);
1801 otherwise it must return false.
1803 If multiple event filters are installed on a single object, the
1804 filter that was installed last is activated first.
1806 Here's a \c KeyPressEater class that eats the key presses of its
1809 \snippet code/src_corelib_kernel_qobject.cpp 15
1811 And here's how to install it on two widgets:
1813 \snippet code/src_corelib_kernel_qobject.cpp 16
1815 The QShortcut class, for example, uses this technique to intercept
1816 shortcut key presses.
1818 \warning If you delete the receiver object in your eventFilter()
1819 function, be sure to return true. If you return false, Qt sends
1820 the event to the deleted object and the program will crash.
1822 Note that the filtering object must be in the same thread as this
1823 object. If \a filterObj is in a different thread, this function does
1824 nothing. If either \a filterObj or this object are moved to a different
1825 thread after calling this function, the event filter will not be
1826 called until both objects have the same thread affinity again (it
1829 \sa removeEventFilter(), eventFilter(), event()
1832 void QObject::installEventFilter(QObject *obj)
1837 if (d->threadData != obj->d_func()->threadData) {
1838 qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
1843 d->extraData = new QObjectPrivate::ExtraData;
1845 // clean up unused items in the list
1846 d->extraData->eventFilters.removeAll((QObject*)0);
1847 d->extraData->eventFilters.removeAll(obj);
1848 d->extraData->eventFilters.prepend(obj);
1852 Removes an event filter object \a obj from this object. The
1853 request is ignored if such an event filter has not been installed.
1855 All event filters for this object are automatically removed when
1856 this object is destroyed.
1858 It is always safe to remove an event filter, even during event
1859 filter activation (i.e. from the eventFilter() function).
1861 \sa installEventFilter(), eventFilter(), event()
1864 void QObject::removeEventFilter(QObject *obj)
1868 for (int i = 0; i < d->extraData->eventFilters.count(); ++i) {
1869 if (d->extraData->eventFilters.at(i) == obj)
1870 d->extraData->eventFilters[i] = 0;
1877 \fn QObject::destroyed(QObject *obj)
1879 This signal is emitted immediately before the object \a obj is
1880 destroyed, and can not be blocked.
1882 All the objects's children are destroyed immediately after this
1885 \sa deleteLater(), QPointer
1889 Schedules this object for deletion.
1891 The object will be deleted when control returns to the event
1892 loop. If the event loop is not running when this function is
1893 called (e.g. deleteLater() is called on an object before
1894 QCoreApplication::exec()), the object will be deleted once the
1895 event loop is started.
1897 Note that entering and leaving a new event loop (e.g., by opening a modal
1898 dialog) will \e not perform the deferred deletion; for the object to be
1899 deleted, the control must return to the event loop from which
1900 deleteLater() was called.
1902 \b{Note:} It is safe to call this function more than once; when the
1903 first deferred deletion event is delivered, any pending events for the
1904 object are removed from the event queue.
1906 \sa destroyed(), QPointer
1908 void QObject::deleteLater()
1910 QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
1914 \fn QString QObject::tr(const char *sourceText, const char *disambiguation, int n)
1917 Returns a translated version of \a sourceText, optionally based on a
1918 \a disambiguation string and value of \a n for strings containing plurals;
1919 otherwise returns \a sourceText itself if no appropriate translated string
1923 \snippet mainwindows/sdi/mainwindow.cpp implicit tr context
1926 If the same \a sourceText is used in different roles within the
1927 same context, an additional identifying string may be passed in
1928 \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
1929 the preferred way to pass comments to translators.
1933 \snippet code/src_corelib_kernel_qobject.cpp 17
1936 See \l{Writing Source Code for Translation} for a detailed description of
1937 Qt's translation mechanisms in general, and the
1938 \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
1939 section for information on disambiguation.
1941 \warning This method is reentrant only if all translators are
1942 installed \e before calling this method. Installing or removing
1943 translators while performing translations is not supported. Doing
1944 so will probably result in crashes or other undesirable behavior.
1946 \sa trUtf8(), QApplication::translate(), {Internationalization with Qt}
1950 \fn QString QObject::trUtf8(const char *sourceText, const char *disambiguation, int n)
1953 Returns a translated version of \a sourceText, or
1954 QString::fromUtf8(\a sourceText) if there is no appropriate
1955 version. It is otherwise identical to tr(\a sourceText, \a
1956 disambiguation, \a n).
1958 \warning This method is reentrant only if all translators are
1959 installed \e before calling this method. Installing or removing
1960 translators while performing translations is not supported. Doing
1961 so will probably result in crashes or other undesirable behavior.
1963 \warning For portability reasons, we recommend that you use
1964 escape sequences for specifying non-ASCII characters in string
1965 literals to trUtf8(). For example:
1967 \snippet code/src_corelib_kernel_qobject.cpp 20
1969 \sa tr(), QApplication::translate(), {Internationalization with Qt}
1975 /*****************************************************************************
1977 *****************************************************************************/
1980 const int flagged_locations_count = 2;
1981 static const char* flagged_locations[flagged_locations_count] = {0};
1983 const char *qFlagLocation(const char *method)
1986 flagged_locations[idx] = method;
1987 idx = (idx+1) % flagged_locations_count;
1991 static int extract_code(const char *member)
1993 // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE
1994 return (((int)(*member) - '0') & 0x3);
1997 static const char * extract_location(const char *member)
1999 for (int i = 0; i < flagged_locations_count; ++i) {
2000 if (member == flagged_locations[i]) {
2001 // signature includes location information after the first null-terminator
2002 const char *location = member + qstrlen(member) + 1;
2003 if (*location != '\0')
2011 static bool check_signal_macro(const QObject *sender, const char *signal,
2012 const char *func, const char *op)
2014 int sigcode = extract_code(signal);
2015 if (sigcode != QSIGNAL_CODE) {
2016 if (sigcode == QSLOT_CODE)
2017 qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
2018 func, op, sender->metaObject()->className(), signal+1);
2020 qWarning("QObject::%s: Use the SIGNAL macro to %s %s::%s",
2021 func, op, sender->metaObject()->className(), signal);
2027 static bool check_method_code(int code, const QObject *object,
2028 const char *method, const char *func)
2030 if (code != QSLOT_CODE && code != QSIGNAL_CODE) {
2031 qWarning("QObject::%s: Use the SLOT or SIGNAL macro to "
2032 "%s %s::%s", func, func, object->metaObject()->className(), method);
2038 static void err_method_notfound(const QObject *object,
2039 const char *method, const char *func)
2041 const char *type = "method";
2042 switch (extract_code(method)) {
2043 case QSLOT_CODE: type = "slot"; break;
2044 case QSIGNAL_CODE: type = "signal"; break;
2046 const char *loc = extract_location(method);
2047 if (strchr(method,')') == 0) // common typing mistake
2048 qWarning("QObject::%s: Parentheses expected, %s %s::%s%s%s",
2049 func, type, object->metaObject()->className(), method+1,
2050 loc ? " in ": "", loc ? loc : "");
2052 qWarning("QObject::%s: No such %s %s::%s%s%s",
2053 func, type, object->metaObject()->className(), method+1,
2054 loc ? " in ": "", loc ? loc : "");
2059 static void err_info_about_objects(const char * func,
2060 const QObject * sender,
2061 const QObject * receiver)
2063 QString a = sender ? sender->objectName() : QString();
2064 QString b = receiver ? receiver->objectName() : QString();
2066 qWarning("QObject::%s: (sender name: '%s')", func, a.toLocal8Bit().data());
2068 qWarning("QObject::%s: (receiver name: '%s')", func, b.toLocal8Bit().data());
2072 Returns a pointer to the object that sent the signal, if called in
2073 a slot activated by a signal; otherwise it returns 0. The pointer
2074 is valid only during the execution of the slot that calls this
2075 function from this object's thread context.
2077 The pointer returned by this function becomes invalid if the
2078 sender is destroyed, or if the slot is disconnected from the
2081 \warning This function violates the object-oriented principle of
2082 modularity. However, getting access to the sender might be useful
2083 when many signals are connected to a single slot.
2085 \warning As mentioned above, the return value of this function is
2086 not valid when the slot is called via a Qt::DirectConnection from
2087 a thread different from this object's thread. Do not use this
2088 function in this type of scenario.
2090 \sa senderSignalIndex(), QSignalMapper
2093 QObject *QObject::sender() const
2097 QMutexLocker locker(signalSlotLock(this));
2098 if (!d->currentSender)
2101 for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
2102 if (c->sender == d->currentSender->sender)
2103 return d->currentSender->sender;
2112 Returns the meta-method index of the signal that called the currently
2113 executing slot, which is a member of the class returned by sender().
2114 If called outside of a slot activated by a signal, -1 is returned.
2116 For signals with default parameters, this function will always return
2117 the index with all parameters, regardless of which was used with
2118 connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
2119 will have two different indexes (with and without the parameter), but
2120 this function will always return the index with a parameter. This does
2121 not apply when overloading signals with different parameters.
2123 \warning This function violates the object-oriented principle of
2124 modularity. However, getting access to the signal index might be useful
2125 when many signals are connected to a single slot.
2127 \warning The return value of this function is not valid when the slot
2128 is called via a Qt::DirectConnection from a thread different from this
2129 object's thread. Do not use this function in this type of scenario.
2131 \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method()
2134 int QObject::senderSignalIndex() const
2137 return d->senderSignalIndex();
2141 Returns the number of receivers connected to the \a signal.
2143 Since both slots and signals can be used as receivers for signals,
2144 and the same connections can be made many times, the number of
2145 receivers is the same as the number of connections made from this
2148 When calling this function, you can use the \c SIGNAL() macro to
2149 pass a specific signal:
2151 \snippet code/src_corelib_kernel_qobject.cpp 21
2153 \warning This function violates the object-oriented principle of
2154 modularity. However, it might be useful when you need to perform
2155 expensive initialization only if something is connected to a
2158 \sa isSignalConnected()
2161 int QObject::receivers(const char *signal) const
2166 QByteArray signal_name = QMetaObject::normalizedSignature(signal);
2167 signal = signal_name;
2169 if (!check_signal_macro(this, signal, "receivers", "bind"))
2172 signal++; // skip code
2173 int signal_index = d->signalIndex(signal);
2174 if (signal_index < 0) {
2176 err_method_notfound(this, signal-1, "receivers");
2181 if (d->declarativeData && QAbstractDeclarativeData::receivers) {
2182 receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
2183 metaObject()->indexOfMethod(signal));
2186 if (!d->isSignalConnected(signal_index))
2189 QMutexLocker locker(signalSlotLock(this));
2190 if (d->connectionLists) {
2191 if (signal_index < d->connectionLists->count()) {
2192 const QObjectPrivate::Connection *c =
2193 d->connectionLists->at(signal_index).first;
2195 receivers += c->receiver ? 1 : 0;
2196 c = c->nextConnectionList;
2206 Returns true if the \a signal is connected to at least one receiver,
2207 otherwise returns false.
2209 \a signal must be a signal member of this object, otherwise the behaviour
2212 \snippet code/src_corelib_kernel_qobject.cpp 21
2214 As the code snippet above illustrates, you can use this function
2215 to avoid emitting a signal that nobody listens to.
2217 \warning This function violates the object-oriented principle of
2218 modularity. However, it might be useful when you need to perform
2219 expensive initialization only if something is connected to a
2222 bool QObject::isSignalConnected(const QMetaMethod &signal) const
2228 Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
2229 "QObject::isSignalConnected" , "the parameter must be a signal member of the object");
2230 uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/5;
2232 if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
2233 signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
2237 computeOffsets(signal.mobj, &signalOffset, &methodOffset);
2238 signalIndex += signalOffset;
2240 if (signalIndex < sizeof(d->connectedSignals) * 8)
2241 return d->isSignalConnected(signalIndex);
2243 QMutexLocker locker(signalSlotLock(this));
2244 if (d->connectionLists) {
2245 if (signalIndex < uint(d->connectionLists->count())) {
2246 const QObjectPrivate::Connection *c =
2247 d->connectionLists->at(signalIndex).first;
2251 c = c->nextConnectionList;
2261 This helper function calculates signal and method index for the given
2262 member in the specified class.
2265 \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2267 \li If specified member is not a member of obj instance class (or one of
2268 its parent classes) then both signalIndex and methodIndex are set to -1.
2271 This function is used by QObject::connect and QObject::disconnect which
2272 are working with QMetaMethod.
2274 \a signalIndex is set to the signal index of member. If the member
2275 specified is not signal this variable is set to -1.
2277 \a methodIndex is set to the method index of the member. If the
2278 member is not a method of the object specified by the \a obj argument this
2279 variable is set to -1.
2281 void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2282 const QMetaMethod &member,
2283 int *signalIndex, int *methodIndex)
2287 if (!obj || !member.mobj)
2289 const QMetaObject *m = obj->metaObject();
2290 // Check that member is member of obj class
2291 while (m != 0 && m != member.mobj)
2295 *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2299 computeOffsets(m, &signalOffset, &methodOffset);
2301 *methodIndex += methodOffset;
2302 if (member.methodType() == QMetaMethod::Signal) {
2303 *signalIndex = originalClone(m, *signalIndex);
2304 *signalIndex += signalOffset;
2310 static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2311 const QMetaObject *receiver, const QMetaMethod &method)
2313 if (signal.attributes() & QMetaMethod::Compatibility) {
2314 if (!(method.attributes() & QMetaMethod::Compatibility))
2315 qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2316 sender->className(), signal.methodSignature().constData());
2317 } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2318 method.methodType() == QMetaMethod::Signal) {
2319 qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2320 sender->className(), signal.methodSignature().constData(),
2321 receiver->className(), method.methodSignature().constData());
2328 Creates a connection of the given \a type from the \a signal in
2329 the \a sender object to the \a method in the \a receiver object.
2330 Returns a handle to the connection that can be used to disconnect
2333 You must use the \c SIGNAL() and \c SLOT() macros when specifying
2334 the \a signal and the \a method, for example:
2336 \snippet code/src_corelib_kernel_qobject.cpp 22
2338 This example ensures that the label always displays the current
2339 scroll bar value. Note that the signal and slots parameters must not
2340 contain any variable names, only the type. E.g. the following would
2341 not work and return false:
2343 \snippet code/src_corelib_kernel_qobject.cpp 23
2345 A signal can also be connected to another signal:
2347 \snippet code/src_corelib_kernel_qobject.cpp 24
2349 In this example, the \c MyWidget constructor relays a signal from
2350 a private member variable, and makes it available under a name
2351 that relates to \c MyWidget.
2353 A signal can be connected to many slots and signals. Many signals
2354 can be connected to one slot.
2356 If a signal is connected to several slots, the slots are activated
2357 in the same order as the order the connection was made, when the
2360 The function returns a handle to a connection if it successfully
2361 connects the signal to the slot. The Connection handle will be invalid
2362 if it cannot create the connection, for example, if QObject is unable
2363 to verify the existence of either \a signal or \a method, or if their
2364 signatures aren't compatible.
2365 You can check if the QMetaObject::Connection is valid by casting it to a bool.
2367 By default, a signal is emitted for every connection you make;
2368 two signals are emitted for duplicate connections. You can break
2369 all of these connections with a single disconnect() call.
2370 If you pass the Qt::UniqueConnection \a type, the connection will only
2371 be made if it is not a duplicate. If there is already a duplicate
2372 (exact same signal to the exact same slot on the same objects),
2373 the connection will fail and connect will return an invalid QMetaObject::Connection.
2375 The optional \a type parameter describes the type of connection
2376 to establish. In particular, it determines whether a particular
2377 signal is delivered to a slot immediately or queued for delivery
2378 at a later time. If the signal is queued, the parameters must be
2379 of types that are known to Qt's meta-object system, because Qt
2380 needs to copy the arguments to store them in an event behind the
2381 scenes. If you try to use a queued connection and get the error
2384 \snippet code/src_corelib_kernel_qobject.cpp 25
2386 call qRegisterMetaType() to register the data type before you
2387 establish the connection.
2389 \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE()
2391 QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
2392 const QObject *receiver, const char *method,
2393 Qt::ConnectionType type)
2395 if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2396 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2397 sender ? sender->metaObject()->className() : "(null)",
2398 (signal && *signal) ? signal+1 : "(null)",
2399 receiver ? receiver->metaObject()->className() : "(null)",
2400 (method && *method) ? method+1 : "(null)");
2401 return QMetaObject::Connection(0);
2403 QByteArray tmp_signal_name;
2405 if (!check_signal_macro(sender, signal, "connect", "bind"))
2406 return QMetaObject::Connection(0);
2407 const QMetaObject *smeta = sender->metaObject();
2408 const char *signal_arg = signal;
2409 ++signal; //skip code
2410 QArgumentTypeArray signalTypes;
2411 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2412 QByteArray signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2413 int signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2414 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2415 if (signal_index < 0) {
2416 // check for normalized signatures
2417 tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2418 signal = tmp_signal_name.constData() + 1;
2420 signalTypes.clear();
2421 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2422 smeta = sender->metaObject();
2423 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2424 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2426 if (signal_index < 0) {
2427 err_method_notfound(sender, signal_arg, "connect");
2428 err_info_about_objects("connect", sender, receiver);
2429 return QMetaObject::Connection(0);
2431 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2432 int signalOffset, methodOffset;
2433 computeOffsets(smeta, &signalOffset, &methodOffset);
2434 signal_index += signalOffset;
2436 QByteArray tmp_method_name;
2437 int membcode = extract_code(method);
2439 if (!check_method_code(membcode, receiver, method, "connect"))
2440 return QMetaObject::Connection(0);
2441 const char *method_arg = method;
2442 ++method; // skip code
2444 QByteArray methodName;
2445 QArgumentTypeArray methodTypes;
2446 const QMetaObject *rmeta = receiver->metaObject();
2447 int method_index_relative = -1;
2448 Q_ASSERT(QMetaObjectPrivate::get(rmeta)->revision >= 7);
2451 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2452 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2455 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2456 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2459 if (method_index_relative < 0) {
2460 // check for normalized methods
2461 tmp_method_name = QMetaObject::normalizedSignature(method);
2462 method = tmp_method_name.constData();
2464 methodTypes.clear();
2465 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2466 // rmeta may have been modified above
2467 rmeta = receiver->metaObject();
2470 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2471 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2474 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2475 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2480 if (method_index_relative < 0) {
2481 err_method_notfound(receiver, method_arg, "connect");
2482 err_info_about_objects("connect", sender, receiver);
2483 return QMetaObject::Connection(0);
2486 if (!QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
2487 methodTypes.size(), methodTypes.constData())) {
2488 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2489 "\n %s::%s --> %s::%s",
2490 sender->metaObject()->className(), signal,
2491 receiver->metaObject()->className(), method);
2492 return QMetaObject::Connection(0);
2496 if ((type == Qt::QueuedConnection)
2497 && !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
2498 return QMetaObject::Connection(0);
2502 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
2503 QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2504 check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2506 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2507 sender, signal_index, smeta, receiver, method_index_relative, rmeta ,type, types));
2514 Creates a connection of the given \a type from the \a signal in
2515 the \a sender object to the \a method in the \a receiver object.
2516 Returns a handle to the connection that can be used to disconnect
2519 The Connection handle will be invalid if it cannot create the
2520 connection, for example, the parameters were invalid.
2521 You can check if the QMetaObject::Connection is valid by casting it to a bool.
2523 This function works in the same way as
2524 connect(const QObject *sender, const char *signal,
2525 const QObject *receiver, const char *method,
2526 Qt::ConnectionType type)
2527 but it uses QMetaMethod to specify signal and method.
2529 \sa connect(const QObject *sender, const char *signal,
2530 const QObject *receiver, const char *method,
2531 Qt::ConnectionType type)
2533 QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
2534 const QObject *receiver, const QMetaMethod &method,
2535 Qt::ConnectionType type)
2539 || signal.methodType() != QMetaMethod::Signal
2540 || method.methodType() == QMetaMethod::Constructor) {
2541 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2542 sender ? sender->metaObject()->className() : "(null)",
2543 signal.methodSignature().constData(),
2544 receiver ? receiver->metaObject()->className() : "(null)",
2545 method.methodSignature().constData() );
2546 return QMetaObject::Connection(0);
2553 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2554 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2557 const QMetaObject *smeta = sender->metaObject();
2558 const QMetaObject *rmeta = receiver->metaObject();
2559 if (signal_index == -1) {
2560 qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2561 signal.methodSignature().constData(), smeta->className());
2562 return QMetaObject::Connection(0);
2564 if (method_index == -1) {
2565 qWarning("QObject::connect: Can't find method %s on instance of class %s",
2566 method.methodSignature().constData(), rmeta->className());
2567 return QMetaObject::Connection(0);
2570 if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
2571 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2572 "\n %s::%s --> %s::%s",
2573 smeta->className(), signal.methodSignature().constData(),
2574 rmeta->className(), method.methodSignature().constData());
2575 return QMetaObject::Connection(0);
2579 if ((type == Qt::QueuedConnection)
2580 && !(types = queuedConnectionTypes(signal.parameterTypes())))
2581 return QMetaObject::Connection(0);
2584 check_and_warn_compat(smeta, signal, rmeta, method);
2586 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2587 sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
2592 \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2596 Connects \a signal from the \a sender object to this object's \a
2599 Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2601 Every connection you make emits a signal, so duplicate connections emit
2602 two signals. You can break a connection using disconnect().
2610 Disconnects \a signal in object \a sender from \a method in object
2611 \a receiver. Returns true if the connection is successfully broken;
2612 otherwise returns false.
2614 A signal-slot connection is removed when either of the objects
2615 involved are destroyed.
2617 disconnect() is typically used in three ways, as the following
2618 examples demonstrate.
2620 \li Disconnect everything connected to an object's signals:
2622 \snippet code/src_corelib_kernel_qobject.cpp 26
2624 equivalent to the non-static overloaded function
2626 \snippet code/src_corelib_kernel_qobject.cpp 27
2628 \li Disconnect everything connected to a specific signal:
2630 \snippet code/src_corelib_kernel_qobject.cpp 28
2632 equivalent to the non-static overloaded function
2634 \snippet code/src_corelib_kernel_qobject.cpp 29
2636 \li Disconnect a specific receiver:
2638 \snippet code/src_corelib_kernel_qobject.cpp 30
2640 equivalent to the non-static overloaded function
2642 \snippet code/src_corelib_kernel_qobject.cpp 31
2646 0 may be used as a wildcard, meaning "any signal", "any receiving
2647 object", or "any slot in the receiving object", respectively.
2649 The \a sender may never be 0. (You cannot disconnect signals from
2650 more than one object in a single call.)
2652 If \a signal is 0, it disconnects \a receiver and \a method from
2653 any signal. If not, only the specified signal is disconnected.
2655 If \a receiver is 0, it disconnects anything connected to \a
2656 signal. If not, slots in objects other than \a receiver are not
2659 If \a method is 0, it disconnects anything that is connected to \a
2660 receiver. If not, only slots named \a method will be disconnected,
2661 and all other slots are left alone. The \a method must be 0 if \a
2662 receiver is left out, so you cannot disconnect a
2663 specifically-named slot on all objects.
2667 bool QObject::disconnect(const QObject *sender, const char *signal,
2668 const QObject *receiver, const char *method)
2670 if (sender == 0 || (receiver == 0 && method != 0)) {
2671 qWarning("QObject::disconnect: Unexpected null parameter");
2675 const char *signal_arg = signal;
2676 QByteArray signal_name;
2677 bool signal_found = false;
2680 signal_name = QMetaObject::normalizedSignature(signal);
2681 signal = signal_name.constData();
2682 } QT_CATCH (const std::bad_alloc &) {
2683 // if the signal is already normalized, we can continue.
2684 if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2688 if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
2690 signal++; // skip code
2693 QByteArray method_name;
2694 const char *method_arg = method;
2696 bool method_found = false;
2699 method_name = QMetaObject::normalizedSignature(method);
2700 method = method_name.constData();
2701 } QT_CATCH(const std::bad_alloc &) {
2702 // if the method is already normalized, we can continue.
2703 if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
2707 membcode = extract_code(method);
2708 if (!check_method_code(membcode, receiver, method, "disconnect"))
2710 method++; // skip code
2713 /* We now iterate through all the sender's and receiver's meta
2714 * objects in order to also disconnect possibly shadowed signals
2715 * and slots with the same signature.
2718 const QMetaObject *smeta = sender->metaObject();
2719 QByteArray signalName;
2720 QArgumentTypeArray signalTypes;
2721 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2723 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2724 QByteArray methodName;
2725 QArgumentTypeArray methodTypes;
2726 Q_ASSERT(!receiver || QMetaObjectPrivate::get(receiver->metaObject())->revision >= 7);
2728 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2730 int signal_index = -1;
2732 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2733 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2734 if (signal_index < 0)
2736 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2737 int signalOffset, methodOffset;
2738 computeOffsets(smeta, &signalOffset, &methodOffset);
2739 signal_index += signalOffset;
2740 signal_found = true;
2744 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
2746 const QMetaObject *rmeta = receiver->metaObject();
2748 int method_index = QMetaObjectPrivate::indexOfMethod(
2749 rmeta, methodName, methodTypes.size(), methodTypes.constData());
2750 if (method_index >= 0)
2751 while (method_index < rmeta->methodOffset())
2752 rmeta = rmeta->superClass();
2753 if (method_index < 0)
2755 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
2756 method_found = true;
2757 } while ((rmeta = rmeta->superClass()));
2759 } while (signal && (smeta = smeta->superClass()));
2761 if (signal && !signal_found) {
2762 err_method_notfound(sender, signal_arg, "disconnect");
2763 err_info_about_objects("disconnect", sender, receiver);
2764 } else if (method && !method_found) {
2765 err_method_notfound(receiver, method_arg, "disconnect");
2766 err_info_about_objects("disconnect", sender, receiver);
2770 const_cast<QObject*>(sender)->disconnectNotify(QMetaMethod());
2778 Disconnects \a signal in object \a sender from \a method in object
2779 \a receiver. Returns true if the connection is successfully broken;
2780 otherwise returns false.
2782 This function provides the same possibilities like
2783 disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2784 but uses QMetaMethod to represent the signal and the method to be disconnected.
2786 Additionally this function returnsfalse and no signals and slots disconnected
2790 \li \a signal is not a member of sender class or one of its parent classes.
2792 \li \a method is not a member of receiver class or one of its parent classes.
2794 \li \a signal instance represents not a signal.
2798 QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
2799 In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
2800 method should also be QMetaMethod(). \a sender parameter should be never 0.
2802 \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2804 bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
2805 const QObject *receiver, const QMetaMethod &method)
2807 if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
2808 qWarning("QObject::disconnect: Unexpected null parameter");
2812 if(signal.methodType() != QMetaMethod::Signal) {
2813 qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
2814 "disconnect","unbind",
2815 sender->metaObject()->className(), signal.methodSignature().constData());
2820 if(method.methodType() == QMetaMethod::Constructor) {
2821 qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
2822 receiver->metaObject()->className(), method.methodSignature().constData());
2827 // Reconstructing SIGNAL() macro result for signal.methodSignature() string
2828 QByteArray signalSignature;
2830 signalSignature.reserve(signal.methodSignature().size()+1);
2831 signalSignature.append((char)(QSIGNAL_CODE + '0'));
2832 signalSignature.append(signal.methodSignature());
2839 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2840 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2842 // If we are here sender is not null. If signal is not null while signal_index
2843 // is -1 then this signal is not a member of sender.
2844 if (signal.mobj && signal_index == -1) {
2845 qWarning("QObject::disconect: signal %s not found on class %s",
2846 signal.methodSignature().constData(), sender->metaObject()->className());
2849 // If this condition is true then method is not a member of receeiver.
2850 if (receiver && method.mobj && method_index == -1) {
2851 qWarning("QObject::disconect: method %s not found on class %s",
2852 method.methodSignature().constData(), receiver->metaObject()->className());
2856 if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
2859 if (!signal.isValid()) {
2860 // The signal is a wildcard, meaning all signals were disconnected.
2861 // QMetaObjectPrivate::disconnect() doesn't call disconnectNotify()
2862 // per connection in this case. Call it once now, with an invalid
2863 // QMetaMethod as argument, as documented.
2864 const_cast<QObject*>(sender)->disconnectNotify(signal);
2872 \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method) const
2873 \overload disconnect()
2875 Disconnects \a signal from \a method of \a receiver.
2877 A signal-slot connection is removed when either of the objects
2878 involved are destroyed.
2882 \fn bool QObject::disconnect(const QObject *receiver, const char *method) const
2883 \overload disconnect()
2885 Disconnects all signals in this object from \a receiver's \a
2888 A signal-slot connection is removed when either of the objects
2889 involved are destroyed.
2896 This virtual function is called when something has been connected
2897 to \a signal in this object.
2899 If you want to compare \a signal with a specific signal, you can
2900 use QMetaMethod::fromSignal() as follows:
2902 \snippet code/src_corelib_kernel_qobject.cpp 32
2904 \warning This function violates the object-oriented principle of
2905 modularity. However, it might be useful when you need to perform
2906 expensive initialization only if something is connected to a
2909 \sa connect(), disconnectNotify()
2912 void QObject::connectNotify(const QMetaMethod &signal)
2920 This virtual function is called when something has been
2921 disconnected from \a signal in this object.
2923 See connectNotify() for an example of how to compare
2924 \a signal with a specific signal.
2926 If all signals were disconnected from this object (e.g., the
2927 signal argument to disconnect() was 0), disconnectNotify()
2928 is only called once, and the \a signal will be an invalid
2929 QMetaMethod (QMetaMethod::isValid() returns false).
2931 \warning This function violates the object-oriented principle of
2932 modularity. However, it might be useful for optimizing access to
2933 expensive resources.
2935 \sa disconnect(), connectNotify()
2938 void QObject::disconnectNotify(const QMetaMethod &signal)
2944 convert a signal index from the method range to the signal range
2946 static int methodIndexToSignalIndex(const QMetaObject **base, int signal_index)
2948 if (signal_index < 0)
2949 return signal_index;
2950 const QMetaObject *metaObject = *base;
2951 while (metaObject && metaObject->methodOffset() > signal_index)
2952 metaObject = metaObject->superClass();
2955 int signalOffset, methodOffset;
2956 computeOffsets(metaObject, &signalOffset, &methodOffset);
2957 if (signal_index < metaObject->methodCount())
2958 signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
2960 signal_index = signal_index - methodOffset + signalOffset;
2963 return signal_index;
2967 \a types is a 0-terminated vector of meta types for queued
2970 if \a signal_index is -1, then we effectively connect *all* signals
2971 from the sender to the receiver's slot
2973 QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_index,
2974 const QObject *receiver, int method_index, int type, int *types)
2976 const QMetaObject *smeta = sender->metaObject();
2977 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
2978 return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
2979 receiver, method_index,
2980 0, //FIXME, we could speed this connection up by computing the relative index
2985 Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
2987 method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
2989 the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
2991 QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
2992 int signal_index, const QMetaObject *smeta,
2993 const QObject *receiver, int method_index,
2994 const QMetaObject *rmeta, int type, int *types)
2996 QObject *s = const_cast<QObject *>(sender);
2997 QObject *r = const_cast<QObject *>(receiver);
2999 int method_offset = rmeta ? rmeta->methodOffset() : 0;
3000 Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
3001 QObjectPrivate::StaticMetaCallFunction callFunction =
3002 rmeta ? rmeta->d.static_metacall : 0;
3004 QOrderedMutexLocker locker(signalSlotLock(sender),
3005 signalSlotLock(receiver));
3007 if (type & Qt::UniqueConnection) {
3008 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3009 if (connectionLists && connectionLists->count() > signal_index) {
3010 const QObjectPrivate::Connection *c2 =
3011 (*connectionLists)[signal_index].first;
3013 int method_index_absolute = method_index + method_offset;
3016 if (c2->receiver == receiver && c2->method() == method_index_absolute)
3018 c2 = c2->nextConnectionList;
3021 type &= Qt::UniqueConnection - 1;
3024 QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
3027 c->method_relative = method_index;
3028 c->method_offset = method_offset;
3029 c->connectionType = type;
3030 c->isSlotObject = false;
3031 c->argumentTypes.store(types);
3032 c->nextConnectionList = 0;
3033 c->callFunction = callFunction;
3035 QObjectPrivate::get(s)->addConnection(signal_index, c.data());
3038 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3039 if (smethod.isValid())
3040 s->connectNotify(smethod);
3047 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3048 const QObject *receiver, int method_index)
3050 const QMetaObject *smeta = sender->metaObject();
3051 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3052 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3053 receiver, method_index, 0);
3058 Disconnect a single signal connection. If QMetaObject::connect() has been called
3059 multiple times for the same sender, signal_index, receiver and method_index only
3060 one of these connections will be removed.
3062 bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3063 const QObject *receiver, int method_index)
3065 const QMetaObject *smeta = sender->metaObject();
3066 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3067 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3068 receiver, method_index, 0,
3069 QMetaObjectPrivate::DisconnectOne);
3073 Helper function to remove the connection from the senders list and setting the receivers to 0
3075 bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
3076 const QObject *receiver, int method_index, void **slot,
3077 QMutex *senderMutex, DisconnectType disconnectType)
3079 bool success = false;
3082 && (receiver == 0 || (c->receiver == receiver
3083 && (method_index < 0 || c->method() == method_index)
3084 && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
3085 bool needToUnlock = false;
3086 QMutex *receiverMutex = 0;
3088 receiverMutex = signalSlotLock(c->receiver);
3089 // need to relock this receiver and sender in the correct order
3090 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3095 c->next->prev = c->prev;
3099 receiverMutex->unlock();
3105 if (disconnectType == DisconnectOne)
3108 c = c->nextConnectionList;
3114 Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3116 bool QMetaObjectPrivate::disconnect(const QObject *sender,
3117 int signal_index, const QMetaObject *smeta,
3118 const QObject *receiver, int method_index, void **slot,
3119 DisconnectType disconnectType)
3124 QObject *s = const_cast<QObject *>(sender);
3126 QMutex *senderMutex = signalSlotLock(sender);
3127 QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
3128 QOrderedMutexLocker locker(senderMutex, receiverMutex);
3130 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3131 if (!connectionLists)
3134 // prevent incoming connections changing the connectionLists while unlocked
3135 ++connectionLists->inUse;
3137 bool success = false;
3138 if (signal_index < 0) {
3139 // remove from all connection lists
3140 for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
3141 QObjectPrivate::Connection *c =
3142 (*connectionLists)[sig_index].first;
3143 if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3145 connectionLists->dirty = true;
3148 } else if (signal_index < connectionLists->count()) {
3149 QObjectPrivate::Connection *c =
3150 (*connectionLists)[signal_index].first;
3151 if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3153 connectionLists->dirty = true;
3157 --connectionLists->inUse;
3158 Q_ASSERT(connectionLists->inUse >= 0);
3159 if (connectionLists->orphaned && !connectionLists->inUse)
3160 delete connectionLists;
3164 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3165 if (smethod.isValid())
3166 s->disconnectNotify(smethod);
3173 \fn void QMetaObject::connectSlotsByName(QObject *object)
3175 Searches recursively for all child objects of the given \a object, and connects
3176 matching signals from them to slots of \a object that follow the following form:
3178 \snippet code/src_corelib_kernel_qobject.cpp 33
3180 Let's assume our object has a child object of type QPushButton with
3181 the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3182 button's \c{clicked()} signal would be:
3184 \snippet code/src_corelib_kernel_qobject.cpp 34
3186 \sa QObject::setObjectName()
3188 void QMetaObject::connectSlotsByName(QObject *o)
3192 const QMetaObject *mo = o->metaObject();
3194 const QObjectList list = o->findChildren<QObject *>(QString());
3195 for (int i = 0; i < mo->methodCount(); ++i) {
3196 QByteArray slotSignature = mo->method(i).methodSignature();
3197 const char *slot = slotSignature.constData();
3199 if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3201 bool foundIt = false;
3202 for(int j = 0; j < list.count(); ++j) {
3203 const QObject *co = list.at(j);
3204 QByteArray objName = co->objectName().toLatin1();
3205 int len = objName.length();
3206 if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
3208 const QMetaObject *smeta;
3209 int sigIndex = co->d_func()->signalIndex(slot + len + 4, &smeta);
3210 if (sigIndex < 0) { // search for compatible signals
3211 const QMetaObject *smo = co->metaObject();
3212 int slotlen = qstrlen(slot + len + 4) - 1;
3213 for (int k = 0; k < QMetaObjectPrivate::absoluteSignalCount(smo); ++k) {
3214 QMetaMethod method = QMetaObjectPrivate::signal(smo, k);
3215 if (!qstrncmp(method.methodSignature().constData(), slot + len + 4, slotlen)) {
3216 smeta = method.enclosingMetaObject();
3225 if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
3231 // we found our slot, now skip all overloads
3232 while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3234 } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3235 qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3240 static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3242 const int *argumentTypes = c->argumentTypes.load();
3243 if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) {
3244 QMetaMethod m = sender->metaObject()->method(signal);
3245 argumentTypes = queuedConnectionTypes(m.parameterTypes());
3246 if (!argumentTypes) // cannot queue arguments
3247 argumentTypes = &DIRECT_CONNECTION_ONLY;
3248 if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
3249 if (argumentTypes != &DIRECT_CONNECTION_ONLY)
3250 delete [] argumentTypes;
3251 argumentTypes = c->argumentTypes.load();
3254 if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3256 int nargs = 1; // include return type
3257 while (argumentTypes[nargs-1])
3259 int *types = (int *) malloc(nargs*sizeof(int));
3261 void **args = (void **) malloc(nargs*sizeof(void *));
3263 types[0] = 0; // return type
3264 args[0] = 0; // return value
3265 for (int n = 1; n < nargs; ++n)
3266 args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]);
3267 QMetaCallEvent *ev = c->isSlotObject ?
3268 new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
3269 new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
3270 QCoreApplication::postEvent(c->receiver, ev);
3275 void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
3280 computeOffsets(m, &signalOffset, &methodOffset);
3281 activate(sender, methodOffset, signalOffset, local_signal_index, argv);
3286 void QMetaObject::activate(QObject *sender, int methodOffset, int signalOffset, int local_signal_index,
3289 int signal_index = signalOffset + local_signal_index;
3291 if (sender->d_func()->declarativeData && QAbstractDeclarativeData::signalEmitted)
3292 QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
3293 methodOffset + local_signal_index, argv);
3295 if (!sender->d_func()->isSignalConnected(signal_index))
3296 return; // nothing connected to these signals, and no spy
3298 if (sender->d_func()->blockSig)
3301 int signal_absolute_index = methodOffset + local_signal_index;
3303 void *empty_argv[] = { 0 };
3304 if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
3305 qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
3306 argv ? argv : empty_argv);
3309 Qt::HANDLE currentThreadId = QThread::currentThreadId();
3312 QMutexLocker locker(signalSlotLock(sender));
3313 struct ConnectionListsRef {
3314 QObjectConnectionListVector *connectionLists;
3315 ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
3317 if (connectionLists)
3318 ++connectionLists->inUse;
3320 ~ConnectionListsRef()
3322 if (!connectionLists)
3325 --connectionLists->inUse;
3326 Q_ASSERT(connectionLists->inUse >= 0);
3327 if (connectionLists->orphaned) {
3328 if (!connectionLists->inUse)
3329 delete connectionLists;
3333 QObjectConnectionListVector *operator->() const { return connectionLists; }
3335 ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
3336 if (!connectionLists.connectionLists) {
3338 if (qt_signal_spy_callback_set.signal_end_callback != 0)
3339 qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3343 const QObjectPrivate::ConnectionList *list;
3344 if (signal_index < connectionLists->count())
3345 list = &connectionLists->at(signal_index);
3347 list = &connectionLists->allsignals;
3350 QObjectPrivate::Connection *c = list->first;
3352 // We need to check against last here to ensure that signals added
3353 // during the signal emission are not emitted in this emission.
3354 QObjectPrivate::Connection *last = list->last;
3360 QObject * const receiver = c->receiver;
3361 const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
3363 // determine if this connection should be sent immediately or
3364 // put into the event queue
3365 if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
3366 || (c->connectionType == Qt::QueuedConnection)) {
3367 queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
3369 #ifndef QT_NO_THREAD
3370 } else if (c->connectionType == Qt::BlockingQueuedConnection) {
3372 if (receiverInSameThread) {
3373 qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
3374 "Sender is %s(%p), receiver is %s(%p)",
3375 sender->metaObject()->className(), sender,
3376 receiver->metaObject()->className(), receiver);
3378 QSemaphore semaphore;
3379 QMetaCallEvent *ev = c->isSlotObject ?
3380 new QMetaCallEvent(c->slotObj, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
3381 new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore);
3382 QCoreApplication::postEvent(receiver, ev);
3383 semaphore.acquire();
3389 QConnectionSenderSwitcher sw;
3391 if (receiverInSameThread) {
3392 sw.switchSender(receiver, sender, signal_absolute_index);
3394 const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
3395 const int method_relative = c->method_relative;
3396 if (c->isSlotObject) {
3397 QExplicitlySharedDataPointer<QObject::QSlotObjectBase> obj(c->slotObj);
3399 obj->call(receiver, argv ? argv : empty_argv);
3401 } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
3402 //we compare the vtable to make sure we are not in the destructor of the object.
3404 if (qt_signal_spy_callback_set.slot_begin_callback != 0)
3405 qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
3407 callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
3409 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3410 qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
3413 const int method = method_relative + c->method_offset;
3416 if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
3417 qt_signal_spy_callback_set.slot_begin_callback(receiver,
3419 argv ? argv : empty_argv);
3422 metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
3424 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3425 qt_signal_spy_callback_set.slot_end_callback(receiver, method);
3430 if (connectionLists->orphaned)
3432 } while (c != last && (c = c->nextConnectionList) != 0);
3434 if (connectionLists->orphaned)
3436 } while (list != &connectionLists->allsignals &&
3437 //start over for all signals;
3438 ((list = &connectionLists->allsignals), true));
3442 if (qt_signal_spy_callback_set.signal_end_callback != 0)
3443 qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3448 signal_index comes from indexOfMethod()
3450 void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
3452 const QMetaObject *mo = sender->metaObject();
3453 while (mo->methodOffset() > signal_index)
3454 mo = mo->superClass();
3455 activate(sender, mo, signal_index - mo->methodOffset(), argv);
3459 Implementation of QObject::senderSignalIndex()
3461 int QObjectPrivate::senderSignalIndex() const
3464 QMutexLocker locker(signalSlotLock(q));
3468 for (QObjectPrivate::Connection *c = senders; c; c = c->next) {
3469 if (c->sender == currentSender->sender)
3470 return currentSender->signal;
3477 Returns the signal index used in the internal connectionLists vector.
3479 It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
3480 while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
3482 If \a meta is not 0, it is set to the meta-object where the signal was found.
3484 int QObjectPrivate::signalIndex(const char *signalName,
3485 const QMetaObject **meta) const
3488 const QMetaObject *base = q->metaObject();
3489 Q_ASSERT(QMetaObjectPrivate::get(base)->revision >= 7);
3490 QArgumentTypeArray types;
3491 QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signalName, types);
3492 int relative_index = QMetaObjectPrivate::indexOfSignalRelative(
3493 &base, name, types.size(), types.constData());
3494 if (relative_index < 0)
3495 return relative_index;
3496 relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
3497 int signalOffset, methodOffset;
3498 computeOffsets(base, &signalOffset, &methodOffset);
3501 return relative_index + signalOffset;
3504 /*****************************************************************************
3506 *****************************************************************************/
3508 #ifndef QT_NO_PROPERTIES
3511 Sets the value of the object's \a name property to \a value.
3513 If the property is defined in the class using Q_PROPERTY then
3514 true is returned on success and false otherwise. If the property
3515 is not defined using Q_PROPERTY, and therefore not listed in the
3516 meta-object, it is added as a dynamic property and false is returned.
3518 Information about all available properties is provided through the
3519 metaObject() and dynamicPropertyNames().
3521 Dynamic properties can be queried again using property() and can be
3522 removed by setting the property value to an invalid QVariant.
3523 Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent
3524 to be sent to the object.
3526 \b{Note:} Dynamic properties starting with "_q_" are reserved for internal
3529 \sa property(), metaObject(), dynamicPropertyNames()
3531 bool QObject::setProperty(const char *name, const QVariant &value)
3534 const QMetaObject* meta = metaObject();
3538 int id = meta->indexOfProperty(name);
3541 d->extraData = new QObjectPrivate::ExtraData;
3543 const int idx = d->extraData->propertyNames.indexOf(name);
3545 if (!value.isValid()) {
3548 d->extraData->propertyNames.removeAt(idx);
3549 d->extraData->propertyValues.removeAt(idx);
3552 d->extraData->propertyNames.append(name);
3553 d->extraData->propertyValues.append(value);
3555 d->extraData->propertyValues[idx] = value;
3559 QDynamicPropertyChangeEvent ev(name);
3560 QCoreApplication::sendEvent(this, &ev);
3564 QMetaProperty p = meta->property(id);
3566 if (!p.isWritable())
3567 qWarning("%s::setProperty: Property \"%s\" invalid,"
3568 " read-only or does not exist", metaObject()->className(), name);
3570 return p.write(this, value);
3574 Returns the value of the object's \a name property.
3576 If no such property exists, the returned variant is invalid.
3578 Information about all available properties is provided through the
3579 metaObject() and dynamicPropertyNames().
3581 \sa setProperty(), QVariant::isValid(), metaObject(), dynamicPropertyNames()
3583 QVariant QObject::property(const char *name) const
3586 const QMetaObject* meta = metaObject();
3590 int id = meta->indexOfProperty(name);
3594 const int i = d->extraData->propertyNames.indexOf(name);
3595 return d->extraData->propertyValues.value(i);
3597 QMetaProperty p = meta->property(id);
3599 if (!p.isReadable())
3600 qWarning("%s::property: Property \"%s\" invalid or does not exist",
3601 metaObject()->className(), name);
3603 return p.read(this);
3609 Returns the names of all properties that were dynamically added to
3610 the object using setProperty().
3612 QList<QByteArray> QObject::dynamicPropertyNames() const
3616 return d->extraData->propertyNames;
3617 return QList<QByteArray>();
3620 #endif // QT_NO_PROPERTIES
3623 /*****************************************************************************
3624 QObject debugging output routines.
3625 *****************************************************************************/
3627 static void dumpRecursive(int level, QObject *object)
3629 #if defined(QT_DEBUG)
3632 buf.fill(' ', level / 2 * 8);
3635 QString name = object->objectName();
3636 QString flags = QLatin1String("");
3638 if (qApp->focusWidget() == object)
3640 if (object->isWidgetType()) {
3641 QWidget * w = (QWidget *)object;
3642 if (w->isVisible()) {
3643 QString t("<%1,%2,%3,%4>");
3644 flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
3650 qDebug("%s%s::%s %s", (const char*)buf, object->metaObject()->className(), name.toLocal8Bit().data(),
3651 flags.toLatin1().data());
3652 QObjectList children = object->children();
3653 if (!children.isEmpty()) {
3654 for (int i = 0; i < children.size(); ++i)
3655 dumpRecursive(level+1, children.at(i));
3665 Dumps a tree of children to the debug output.
3667 This function is useful for debugging, but does nothing if the
3668 library has been compiled in release mode (i.e. without debugging
3671 \sa dumpObjectInfo()
3674 void QObject::dumpObjectTree()
3676 dumpRecursive(0, this);
3680 Dumps information about signal connections, etc. for this object
3681 to the debug output.
3683 This function is useful for debugging, but does nothing if the
3684 library has been compiled in release mode (i.e. without debugging
3687 \sa dumpObjectTree()
3690 void QObject::dumpObjectInfo()
3692 #if defined(QT_DEBUG)
3693 qDebug("OBJECT %s::%s", metaObject()->className(),
3694 objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
3697 QMutexLocker locker(signalSlotLock(this));
3699 // first, look for connections where this object is the sender
3700 qDebug(" SIGNALS OUT");
3702 if (d->connectionLists) {
3703 for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) {
3704 const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
3705 qDebug(" signal: %s", signal.methodSignature().constData());
3708 const QObjectPrivate::Connection *c =
3709 d->connectionLists->at(signal_index).first;
3712 qDebug(" <Disconnected receiver>");
3713 c = c->nextConnectionList;
3716 const QMetaObject *receiverMetaObject = c->receiver->metaObject();
3717 const QMetaMethod method = receiverMetaObject->method(c->method());
3718 qDebug(" --> %s::%s %s",
3719 receiverMetaObject->className(),
3720 c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
3721 method.methodSignature().constData());
3722 c = c->nextConnectionList;
3726 qDebug( " <None>" );
3729 // now look for connections where this object is the receiver
3730 qDebug(" SIGNALS IN");
3733 for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
3734 const QMetaMethod slot = metaObject()->method(s->method());
3735 qDebug(" <-- %s::%s %s",
3736 s->sender->metaObject()->className(),
3737 s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
3738 slot.methodSignature().constData());
3746 #ifndef QT_NO_USERDATA
3749 uint QObject::registerUserData()
3751 static int user_data_registration = 0;
3752 return user_data_registration++;
3757 QObjectUserData::~QObjectUserData()
3763 void QObject::setUserData(uint id, QObjectUserData* data)
3767 d->extraData = new QObjectPrivate::ExtraData;
3769 if (d->extraData->userData.size() <= (int) id)
3770 d->extraData->userData.resize((int) id + 1);
3771 d->extraData->userData[id] = data;
3776 QObjectUserData* QObject::userData(uint id) const
3781 if ((int)id < d->extraData->userData.size())
3782 return d->extraData->userData.at(id);
3786 #endif // QT_NO_USERDATA
3789 #ifndef QT_NO_DEBUG_STREAM
3790 QDebug operator<<(QDebug dbg, const QObject *o) {
3792 return dbg << "QObject(0x0) ";
3793 dbg.nospace() << o->metaObject()->className() << '(' << (void *)o;
3794 if (!o->objectName().isEmpty())
3795 dbg << ", name = " << o->objectName();
3802 \macro Q_CLASSINFO(Name, Value)
3805 This macro associates extra information to the class, which is
3806 available using QObject::metaObject(). Except for the ActiveQt
3807 extension, Qt doesn't use this information.
3809 The extra information takes the form of a \a Name string and a \a
3810 Value literal string.
3814 \snippet code/src_corelib_kernel_qobject.cpp 35
3816 \sa QMetaObject::classInfo()
3820 \macro Q_INTERFACES(...)
3823 This macro tells Qt which interfaces the class implements. This
3824 is used when implementing plugins.
3828 \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
3830 \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
3832 See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
3833 Basic Tools} example for details.
3835 \sa Q_DECLARE_INTERFACE(), Q_EXPORT_PLUGIN2(), {How to Create Qt Plugins}
3839 \macro Q_PROPERTY(...)
3842 This macro is used for declaring properties in classes that
3843 inherit QObject. Properties behave like class data members, but
3844 they have additional features accessible through the \l
3845 {Meta-Object System}.
3847 \snippet code/src_corelib_kernel_qobject.cpp 36
3849 The property name and type and the \c READ function are required.
3850 The type can be any type supported by QVariant, or it can be a
3851 user-defined type. The other items are optional, but a \c WRITE
3852 function is common. The attributes default to true except \c USER,
3853 which defaults to false.
3857 \snippet code/src_corelib_kernel_qobject.cpp 37
3859 For more details about how to use this macro, and a more detailed
3860 example of its use, see the discussion on \l {Qt's Property System}.
3862 \sa {Qt's Property System}
3869 This macro registers one or several enum types to the meta-object
3874 \snippet code/src_corelib_kernel_qobject.cpp 38
3876 If you want to register an enum that is declared in another class,
3877 the enum must be fully qualified with the name of the class
3878 defining it. In addition, the class \e defining the enum has to
3879 inherit QObject as well as declare the enum using Q_ENUMS().
3881 \sa {Qt's Property System}
3888 This macro registers one or several \l{QFlags}{flags types} to the
3889 meta-object system. It is typically used in a class definition to declare
3890 that values of a given enum can be used as flags and combined using the
3891 bitwise OR operator.
3893 For example, in QLibrary, the \l{QLibrary::LoadHints}{LoadHints} flag is
3894 declared in the following way:
3896 \snippet code/src_corelib_kernel_qobject.cpp 39a
3898 The declaration of the flags themselves is performed in the public section
3899 of the QLibrary class itself, using the \l Q_DECLARE_FLAGS() macro:
3901 \snippet code/src_corelib_kernel_qobject.cpp 39b
3903 \note This macro takes care of registering individual flag values
3904 with the meta-object system, so it is unnecessary to use Q_ENUMS()
3905 in addition to this macro.
3907 \sa {Qt's Property System}
3914 The Q_OBJECT macro must appear in the private section of a class
3915 definition that declares its own signals and slots or that uses
3916 other services provided by Qt's meta-object system.
3920 \snippet signalsandslots/signalsandslots.h 1
3922 \snippet signalsandslots/signalsandslots.h 2
3923 \snippet signalsandslots/signalsandslots.h 3
3925 \note This macro requires the class to be a subclass of QObject. Use
3926 Q_GADGET instead of Q_OBJECT to enable the meta object system's support
3927 for enums in a class that is not a QObject subclass. Q_GADGET makes a
3928 class member, \c{staticMetaObject}, available.
3929 \c{staticMetaObject} is of type QMetaObject and provides access to the
3930 enums declared with Q_ENUMS.
3931 Q_GADGET is provided only for C++.
3933 \sa {Meta-Object System}, {Signals and Slots}, {Qt's Property System}
3940 Use this macro to replace the \c signals keyword in class
3941 declarations, when you want to use Qt Signals and Slots with a
3942 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3944 The macro is normally used when \c no_keywords is specified with
3945 the \c CONFIG variable in the \c .pro file, but it can be used
3946 even when \c no_keywords is \e not specified.
3953 This is an additional macro that allows you to mark a single
3954 function as a signal. It can be quite useful, especially when you
3955 use a 3rd-party source code parser which doesn't understand a \c
3956 signals or \c Q_SIGNALS groups.
3958 Use this macro to replace the \c signals keyword in class
3959 declarations, when you want to use Qt Signals and Slots with a
3960 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3962 The macro is normally used when \c no_keywords is specified with
3963 the \c CONFIG variable in the \c .pro file, but it can be used
3964 even when \c no_keywords is \e not specified.
3971 Use this macro to replace the \c slots keyword in class
3972 declarations, when you want to use Qt Signals and Slots with a
3973 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3975 The macro is normally used when \c no_keywords is specified with
3976 the \c CONFIG variable in the \c .pro file, but it can be used
3977 even when \c no_keywords is \e not specified.
3984 This is an additional macro that allows you to mark a single
3985 function as a slot. It can be quite useful, especially when you
3986 use a 3rd-party source code parser which doesn't understand a \c
3987 slots or \c Q_SLOTS groups.
3989 Use this macro to replace the \c slots keyword in class
3990 declarations, when you want to use Qt Signals and Slots with a
3991 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3993 The macro is normally used when \c no_keywords is specified with
3994 the \c CONFIG variable in the \c .pro file, but it can be used
3995 even when \c no_keywords is \e not specified.
4002 Use this macro to replace the \c emit keyword for emitting
4003 signals, when you want to use Qt Signals and Slots with a
4004 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
4006 The macro is normally used when \c no_keywords is specified with
4007 the \c CONFIG variable in the \c .pro file, but it can be used
4008 even when \c no_keywords is \e not specified.
4015 Apply this macro to definitions of member functions to allow them to
4016 be invoked via the meta-object system. The macro is written before
4017 the return type, as shown in the following example:
4019 \snippet qmetaobject-invokable/window.h Window class with invokable method
4021 The \c invokableMethod() function is marked up using Q_INVOKABLE, causing
4022 it to be registered with the meta-object system and enabling it to be
4023 invoked using QMetaObject::invokeMethod().
4024 Since \c normalMethod() function is not registered in this way, it cannot
4025 be invoked using QMetaObject::invokeMethod().
4029 \typedef QObjectList
4032 Synonym for QList<QObject *>.
4035 void qDeleteInEventHandler(QObject *o)
4041 \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
4045 Creates a connection of the given \a type from the \a signal in
4046 the \a sender object to the \a method in the \a receiver object.
4047 Returns a handle to the connection that can be used to disconnect
4050 The signal must be a function declared as a signal in the header.
4051 The slot function can be any member function that can be connected
4053 A slot can be connected to a given signal if the signal has at
4054 least as many arguments as the slot, and there is an implicit
4055 conversion between the types of the corresponding arguments in the
4056 signal and the slot.
4060 \snippet code/src_corelib_kernel_qobject.cpp 44
4062 This example ensures that the label always displays the current
4065 A signal can be connected to many slots and signals. Many signals
4066 can be connected to one slot.
4068 If a signal is connected to several slots, the slots are activated
4069 in the same order as the order the connection was made, when the
4072 The function returns an handle to a connection if it successfully
4073 connects the signal to the slot. The Connection handle will be invalid
4074 if it cannot create the connection, for example, if QObject is unable
4075 to verify the existence of \a signal (if it was not declared as a signal)
4076 You can check if the QMetaObject::Connection is valid by casting it to a bool.
4078 By default, a signal is emitted for every connection you make;
4079 two signals are emitted for duplicate connections. You can break
4080 all of these connections with a single disconnect() call.
4081 If you pass the Qt::UniqueConnection \a type, the connection will only
4082 be made if it is not a duplicate. If there is already a duplicate
4083 (exact same signal to the exact same slot on the same objects),
4084 the connection will fail and connect will return an invalid QMetaObject::Connection.
4086 The optional \a type parameter describes the type of connection
4087 to establish. In particular, it determines whether a particular
4088 signal is delivered to a slot immediately or queued for delivery
4089 at a later time. If the signal is queued, the parameters must be
4090 of types that are known to Qt's meta-object system, because Qt
4091 needs to copy the arguments to store them in an event behind the
4092 scenes. If you try to use a queued connection and get the error
4095 \snippet code/src_corelib_kernel_qobject.cpp 25
4097 make sure to declare the argument type with Q_DECLARE_METATYPE
4102 \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
4107 Creates a connection of the given \a type from the \a signal in
4108 the \a sender object to the \a functor and returns a handle to the connection
4110 The signal must be a function declared as a signal in the header.
4111 The slot function can be any function or functor that can be connected
4113 A function can be connected to a given signal if the signal as at
4114 least as many argument as the slot. A functor can be connected to a signal
4115 if they have exactly the same number of arguments. There must exist implicit
4116 conversion between the types of the corresponding arguments in the
4117 signal and the slot.
4121 \snippet code/src_corelib_kernel_qobject.cpp 45
4123 If your compiler support C++11 lambda expressions, you can use them:
4125 \snippet code/src_corelib_kernel_qobject.cpp 46
4127 The connection will automatically disconnect if the sender is destroyed.
4132 Implementation of the template version of connect
4134 \a sender is the sender object
4135 \a signal is a pointer to a pointer to a member signal of the sender
4136 \a receiver is the receiver object, may not be null, will be equal to sender when
4137 connecting to a static function or a functor
4138 \a slot a pointer only used when using Qt::UniqueConnection
4139 \a type the Qt::ConnctionType passed as argument to connect
4140 \a types an array of integer with the metatype id of the parametter of the signal
4141 to be used with queued connection
4142 must stay valid at least for the whole time of the connection, this function
4143 do not take ownership. typically static data.
4144 If null, then the types will be computed when the signal is emit in a queued
4145 connection from the types from the signature.
4146 \a senderMetaObject is the metaobject used to lookup the signal, the signal must be in
4149 QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
4150 const QObject *receiver, void **slot,
4151 QObject::QSlotObjectBase *slotObj, Qt::ConnectionType type,
4152 const int *types, const QMetaObject *senderMetaObject)
4154 if (!sender || !signal || !slotObj || !senderMetaObject) {
4155 qWarning("QObject::connect: invalid null parametter");
4156 if (slotObj && !slotObj->ref.deref())
4158 return QMetaObject::Connection();
4160 int signal_index = -1;
4161 void *args[] = { &signal_index, signal };
4162 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4163 if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4164 qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
4165 if (!slotObj->ref.deref())
4167 return QMetaObject::Connection(0);
4169 int signalOffset, methodOffset;
4170 computeOffsets(senderMetaObject, &signalOffset, &methodOffset);
4171 signal_index += signalOffset;
4173 QObject *s = const_cast<QObject *>(sender);
4174 QObject *r = const_cast<QObject *>(receiver);
4176 QOrderedMutexLocker locker(signalSlotLock(sender),
4177 signalSlotLock(receiver));
4179 if (type & Qt::UniqueConnection) {
4180 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
4181 if (connectionLists && connectionLists->count() > signal_index) {
4182 const QObjectPrivate::Connection *c2 =
4183 (*connectionLists)[signal_index].first;
4186 if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
4187 if (!slotObj->ref.deref())
4189 return QMetaObject::Connection();
4191 c2 = c2->nextConnectionList;
4194 type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection);
4197 QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
4200 c->slotObj = slotObj;
4201 c->connectionType = type;
4202 c->isSlotObject = true;
4204 c->argumentTypes.store(types);
4205 c->ownArgumentTypes = false;
4208 QObjectPrivate::get(s)->addConnection(signal_index, c.data());
4209 QMetaObject::Connection ret(c.take());
4212 QMetaMethod method = QMetaObjectPrivate::signal(senderMetaObject, signal_index);
4213 Q_ASSERT(method.isValid());
4214 s->connectNotify(method);
4220 Disconnect a connection.
4222 If the \a connection is invalid or has already been disconnected, do nothing
4227 bool QObject::disconnect(const QMetaObject::Connection &connection)
4229 QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(connection.d_ptr);
4231 if (!c || !c->receiver)
4234 QMutex *senderMutex = signalSlotLock(c->sender);
4235 QMutex *receiverMutex = signalSlotLock(c->receiver);
4236 QOrderedMutexLocker locker(senderMutex, receiverMutex);
4238 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists;
4239 Q_ASSERT(connectionLists);
4240 connectionLists->dirty = true;
4244 c->next->prev = c->prev;
4246 // disconnectNotify() not called (the signal index is unknown).
4251 /*! \fn bool QObject::disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
4252 \overload diconnect()
4255 Disconnects \a signal in object \a sender from \a method in object
4256 \a receiver. Returns true if the connection is successfully broken;
4257 otherwise returns false.
4259 A signal-slot connection is removed when either of the objects
4260 involved are destroyed.
4262 disconnect() is typically used in three ways, as the following
4263 examples demonstrate.
4265 \li Disconnect everything connected to an object's signals:
4267 \snippet code/src_corelib_kernel_qobject.cpp 26
4269 \li Disconnect everything connected to a specific signal:
4271 \snippet code/src_corelib_kernel_qobject.cpp 47
4273 \li Disconnect a specific receiver:
4275 \snippet code/src_corelib_kernel_qobject.cpp 30
4277 \li Disconnect a connection from one specific signal to a specific slot:
4279 \snippet code/src_corelib_kernel_qobject.cpp 48
4284 0 may be used as a wildcard, meaning "any signal", "any receiving
4285 object", or "any slot in the receiving object", respectively.
4287 The \a sender may never be 0. (You cannot disconnect signals from
4288 more than one object in a single call.)
4290 If \a signal is 0, it disconnects \a receiver and \a method from
4291 any signal. If not, only the specified signal is disconnected.
4293 If \a receiver is 0, it disconnects anything connected to \a
4294 signal. If not, slots in objects other than \a receiver are not
4297 If \a method is 0, it disconnects anything that is connected to \a
4298 receiver. If not, only slots named \a method will be disconnected,
4299 and all other slots are left alone. The \a method must be 0 if \a
4300 receiver is left out, so you cannot disconnect a
4301 specifically-named slot on all objects.
4303 \note It is not possible to use this overload to diconnect signals
4304 connected to functors or lambda expressions. That is because it is not
4305 possible to compare them. Instead, use the olverload that take a
4306 QMetaObject::Connection
4311 bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject)
4313 if (sender == 0 || (receiver == 0 && slot != 0)) {
4314 qWarning("QObject::disconnect: Unexpected null parameter");
4318 int signal_index = -1;
4320 void *args[] = { &signal_index, signal };
4321 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4322 if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4323 qWarning("QObject::disconnect: signal not found in %s", senderMetaObject->className());
4326 int signalOffset, methodOffset;
4327 computeOffsets(senderMetaObject, &signalOffset, &methodOffset);
4328 signal_index += signalOffset;
4331 return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
4334 /*! \class QMetaObject::Connection
4335 Represents a handle to a signal-slot connection.
4336 It can be used to disconnect that connection, or check if
4337 the connection was successful
4339 \sa QObject::disconnect
4343 Create a copy of the handle to the connection
4345 QMetaObject::Connection::Connection(const QMetaObject::Connection &other) : d_ptr(other.d_ptr)
4348 static_cast<QObjectPrivate::Connection *>(d_ptr)->ref();
4351 QMetaObject::Connection& QMetaObject::Connection::operator=(const QMetaObject::Connection& other)
4353 if (other.d_ptr != d_ptr) {
4355 static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4356 d_ptr = other.d_ptr;
4358 static_cast<QObjectPrivate::Connection *>(other.d_ptr)->ref();
4363 QMetaObject::Connection::Connection() : d_ptr(0) {}
4365 QMetaObject::Connection::~Connection()
4368 static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4372 \fn QMetaObject::Connection::operator bool() const
4374 Returns true if the connection is valid.
4376 The connection is valid if the call to QObject::connect succeeded.
4377 The connection is invalid if QObject::connect was not able to find
4378 the signal or the slot, or if the arguments do not match.
4381 QObject::QSlotObjectBase::~QSlotObjectBase()
4385 bool QObject::QSlotObjectBase::compare(void** )
4393 #include "moc_qobject.cpp"