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);
2235 signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj);
2237 if (signalIndex < sizeof(d->connectedSignals) * 8)
2238 return d->isSignalConnected(signalIndex);
2240 QMutexLocker locker(signalSlotLock(this));
2241 if (d->connectionLists) {
2242 if (signalIndex < uint(d->connectionLists->count())) {
2243 const QObjectPrivate::Connection *c =
2244 d->connectionLists->at(signalIndex).first;
2248 c = c->nextConnectionList;
2258 This helper function calculates signal and method index for the given
2259 member in the specified class.
2262 \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2264 \li If specified member is not a member of obj instance class (or one of
2265 its parent classes) then both signalIndex and methodIndex are set to -1.
2268 This function is used by QObject::connect and QObject::disconnect which
2269 are working with QMetaMethod.
2271 \a signalIndex is set to the signal index of member. If the member
2272 specified is not signal this variable is set to -1.
2274 \a methodIndex is set to the method index of the member. If the
2275 member is not a method of the object specified by the \a obj argument this
2276 variable is set to -1.
2278 void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2279 const QMetaMethod &member,
2280 int *signalIndex, int *methodIndex)
2284 if (!obj || !member.mobj)
2286 const QMetaObject *m = obj->metaObject();
2287 // Check that member is member of obj class
2288 while (m != 0 && m != member.mobj)
2292 *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2296 computeOffsets(m, &signalOffset, &methodOffset);
2298 *methodIndex += methodOffset;
2299 if (member.methodType() == QMetaMethod::Signal) {
2300 *signalIndex = originalClone(m, *signalIndex);
2301 *signalIndex += signalOffset;
2307 static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2308 const QMetaObject *receiver, const QMetaMethod &method)
2310 if (signal.attributes() & QMetaMethod::Compatibility) {
2311 if (!(method.attributes() & QMetaMethod::Compatibility))
2312 qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2313 sender->className(), signal.methodSignature().constData());
2314 } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2315 method.methodType() == QMetaMethod::Signal) {
2316 qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2317 sender->className(), signal.methodSignature().constData(),
2318 receiver->className(), method.methodSignature().constData());
2325 Creates a connection of the given \a type from the \a signal in
2326 the \a sender object to the \a method in the \a receiver object.
2327 Returns a handle to the connection that can be used to disconnect
2330 You must use the \c SIGNAL() and \c SLOT() macros when specifying
2331 the \a signal and the \a method, for example:
2333 \snippet code/src_corelib_kernel_qobject.cpp 22
2335 This example ensures that the label always displays the current
2336 scroll bar value. Note that the signal and slots parameters must not
2337 contain any variable names, only the type. E.g. the following would
2338 not work and return false:
2340 \snippet code/src_corelib_kernel_qobject.cpp 23
2342 A signal can also be connected to another signal:
2344 \snippet code/src_corelib_kernel_qobject.cpp 24
2346 In this example, the \c MyWidget constructor relays a signal from
2347 a private member variable, and makes it available under a name
2348 that relates to \c MyWidget.
2350 A signal can be connected to many slots and signals. Many signals
2351 can be connected to one slot.
2353 If a signal is connected to several slots, the slots are activated
2354 in the same order as the order the connection was made, when the
2357 The function returns a handle to a connection if it successfully
2358 connects the signal to the slot. The Connection handle will be invalid
2359 if it cannot create the connection, for example, if QObject is unable
2360 to verify the existence of either \a signal or \a method, or if their
2361 signatures aren't compatible.
2362 You can check if the QMetaObject::Connection is valid by casting it to a bool.
2364 By default, a signal is emitted for every connection you make;
2365 two signals are emitted for duplicate connections. You can break
2366 all of these connections with a single disconnect() call.
2367 If you pass the Qt::UniqueConnection \a type, the connection will only
2368 be made if it is not a duplicate. If there is already a duplicate
2369 (exact same signal to the exact same slot on the same objects),
2370 the connection will fail and connect will return an invalid QMetaObject::Connection.
2372 The optional \a type parameter describes the type of connection
2373 to establish. In particular, it determines whether a particular
2374 signal is delivered to a slot immediately or queued for delivery
2375 at a later time. If the signal is queued, the parameters must be
2376 of types that are known to Qt's meta-object system, because Qt
2377 needs to copy the arguments to store them in an event behind the
2378 scenes. If you try to use a queued connection and get the error
2381 \snippet code/src_corelib_kernel_qobject.cpp 25
2383 call qRegisterMetaType() to register the data type before you
2384 establish the connection.
2386 \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE()
2388 QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
2389 const QObject *receiver, const char *method,
2390 Qt::ConnectionType type)
2392 if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2393 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2394 sender ? sender->metaObject()->className() : "(null)",
2395 (signal && *signal) ? signal+1 : "(null)",
2396 receiver ? receiver->metaObject()->className() : "(null)",
2397 (method && *method) ? method+1 : "(null)");
2398 return QMetaObject::Connection(0);
2400 QByteArray tmp_signal_name;
2402 if (!check_signal_macro(sender, signal, "connect", "bind"))
2403 return QMetaObject::Connection(0);
2404 const QMetaObject *smeta = sender->metaObject();
2405 const char *signal_arg = signal;
2406 ++signal; //skip code
2407 QArgumentTypeArray signalTypes;
2408 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2409 QByteArray signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2410 int signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2411 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2412 if (signal_index < 0) {
2413 // check for normalized signatures
2414 tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2415 signal = tmp_signal_name.constData() + 1;
2417 signalTypes.clear();
2418 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2419 smeta = sender->metaObject();
2420 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2421 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2423 if (signal_index < 0) {
2424 err_method_notfound(sender, signal_arg, "connect");
2425 err_info_about_objects("connect", sender, receiver);
2426 return QMetaObject::Connection(0);
2428 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2429 signal_index += QMetaObjectPrivate::signalOffset(smeta);
2431 QByteArray tmp_method_name;
2432 int membcode = extract_code(method);
2434 if (!check_method_code(membcode, receiver, method, "connect"))
2435 return QMetaObject::Connection(0);
2436 const char *method_arg = method;
2437 ++method; // skip code
2439 QByteArray methodName;
2440 QArgumentTypeArray methodTypes;
2441 const QMetaObject *rmeta = receiver->metaObject();
2442 int method_index_relative = -1;
2443 Q_ASSERT(QMetaObjectPrivate::get(rmeta)->revision >= 7);
2446 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2447 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2450 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2451 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2454 if (method_index_relative < 0) {
2455 // check for normalized methods
2456 tmp_method_name = QMetaObject::normalizedSignature(method);
2457 method = tmp_method_name.constData();
2459 methodTypes.clear();
2460 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2461 // rmeta may have been modified above
2462 rmeta = receiver->metaObject();
2465 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2466 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2469 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2470 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2475 if (method_index_relative < 0) {
2476 err_method_notfound(receiver, method_arg, "connect");
2477 err_info_about_objects("connect", sender, receiver);
2478 return QMetaObject::Connection(0);
2481 if (!QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
2482 methodTypes.size(), methodTypes.constData())) {
2483 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2484 "\n %s::%s --> %s::%s",
2485 sender->metaObject()->className(), signal,
2486 receiver->metaObject()->className(), method);
2487 return QMetaObject::Connection(0);
2491 if ((type == Qt::QueuedConnection)
2492 && !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
2493 return QMetaObject::Connection(0);
2497 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
2498 QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2499 check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2501 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2502 sender, signal_index, smeta, receiver, method_index_relative, rmeta ,type, types));
2509 Creates a connection of the given \a type from the \a signal in
2510 the \a sender object to the \a method in the \a receiver object.
2511 Returns a handle to the connection that can be used to disconnect
2514 The Connection handle will be invalid if it cannot create the
2515 connection, for example, the parameters were invalid.
2516 You can check if the QMetaObject::Connection is valid by casting it to a bool.
2518 This function works in the same way as
2519 connect(const QObject *sender, const char *signal,
2520 const QObject *receiver, const char *method,
2521 Qt::ConnectionType type)
2522 but it uses QMetaMethod to specify signal and method.
2524 \sa connect(const QObject *sender, const char *signal,
2525 const QObject *receiver, const char *method,
2526 Qt::ConnectionType type)
2528 QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
2529 const QObject *receiver, const QMetaMethod &method,
2530 Qt::ConnectionType type)
2534 || signal.methodType() != QMetaMethod::Signal
2535 || method.methodType() == QMetaMethod::Constructor) {
2536 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2537 sender ? sender->metaObject()->className() : "(null)",
2538 signal.methodSignature().constData(),
2539 receiver ? receiver->metaObject()->className() : "(null)",
2540 method.methodSignature().constData() );
2541 return QMetaObject::Connection(0);
2548 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2549 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2552 const QMetaObject *smeta = sender->metaObject();
2553 const QMetaObject *rmeta = receiver->metaObject();
2554 if (signal_index == -1) {
2555 qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2556 signal.methodSignature().constData(), smeta->className());
2557 return QMetaObject::Connection(0);
2559 if (method_index == -1) {
2560 qWarning("QObject::connect: Can't find method %s on instance of class %s",
2561 method.methodSignature().constData(), rmeta->className());
2562 return QMetaObject::Connection(0);
2565 if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
2566 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2567 "\n %s::%s --> %s::%s",
2568 smeta->className(), signal.methodSignature().constData(),
2569 rmeta->className(), method.methodSignature().constData());
2570 return QMetaObject::Connection(0);
2574 if ((type == Qt::QueuedConnection)
2575 && !(types = queuedConnectionTypes(signal.parameterTypes())))
2576 return QMetaObject::Connection(0);
2579 check_and_warn_compat(smeta, signal, rmeta, method);
2581 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2582 sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
2587 \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2591 Connects \a signal from the \a sender object to this object's \a
2594 Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2596 Every connection you make emits a signal, so duplicate connections emit
2597 two signals. You can break a connection using disconnect().
2605 Disconnects \a signal in object \a sender from \a method in object
2606 \a receiver. Returns true if the connection is successfully broken;
2607 otherwise returns false.
2609 A signal-slot connection is removed when either of the objects
2610 involved are destroyed.
2612 disconnect() is typically used in three ways, as the following
2613 examples demonstrate.
2615 \li Disconnect everything connected to an object's signals:
2617 \snippet code/src_corelib_kernel_qobject.cpp 26
2619 equivalent to the non-static overloaded function
2621 \snippet code/src_corelib_kernel_qobject.cpp 27
2623 \li Disconnect everything connected to a specific signal:
2625 \snippet code/src_corelib_kernel_qobject.cpp 28
2627 equivalent to the non-static overloaded function
2629 \snippet code/src_corelib_kernel_qobject.cpp 29
2631 \li Disconnect a specific receiver:
2633 \snippet code/src_corelib_kernel_qobject.cpp 30
2635 equivalent to the non-static overloaded function
2637 \snippet code/src_corelib_kernel_qobject.cpp 31
2641 0 may be used as a wildcard, meaning "any signal", "any receiving
2642 object", or "any slot in the receiving object", respectively.
2644 The \a sender may never be 0. (You cannot disconnect signals from
2645 more than one object in a single call.)
2647 If \a signal is 0, it disconnects \a receiver and \a method from
2648 any signal. If not, only the specified signal is disconnected.
2650 If \a receiver is 0, it disconnects anything connected to \a
2651 signal. If not, slots in objects other than \a receiver are not
2654 If \a method is 0, it disconnects anything that is connected to \a
2655 receiver. If not, only slots named \a method will be disconnected,
2656 and all other slots are left alone. The \a method must be 0 if \a
2657 receiver is left out, so you cannot disconnect a
2658 specifically-named slot on all objects.
2662 bool QObject::disconnect(const QObject *sender, const char *signal,
2663 const QObject *receiver, const char *method)
2665 if (sender == 0 || (receiver == 0 && method != 0)) {
2666 qWarning("QObject::disconnect: Unexpected null parameter");
2670 const char *signal_arg = signal;
2671 QByteArray signal_name;
2672 bool signal_found = false;
2675 signal_name = QMetaObject::normalizedSignature(signal);
2676 signal = signal_name.constData();
2677 } QT_CATCH (const std::bad_alloc &) {
2678 // if the signal is already normalized, we can continue.
2679 if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2683 if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
2685 signal++; // skip code
2688 QByteArray method_name;
2689 const char *method_arg = method;
2691 bool method_found = false;
2694 method_name = QMetaObject::normalizedSignature(method);
2695 method = method_name.constData();
2696 } QT_CATCH(const std::bad_alloc &) {
2697 // if the method is already normalized, we can continue.
2698 if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
2702 membcode = extract_code(method);
2703 if (!check_method_code(membcode, receiver, method, "disconnect"))
2705 method++; // skip code
2708 /* We now iterate through all the sender's and receiver's meta
2709 * objects in order to also disconnect possibly shadowed signals
2710 * and slots with the same signature.
2713 const QMetaObject *smeta = sender->metaObject();
2714 QByteArray signalName;
2715 QArgumentTypeArray signalTypes;
2716 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2718 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2719 QByteArray methodName;
2720 QArgumentTypeArray methodTypes;
2721 Q_ASSERT(!receiver || QMetaObjectPrivate::get(receiver->metaObject())->revision >= 7);
2723 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2725 int signal_index = -1;
2727 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2728 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2729 if (signal_index < 0)
2731 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2732 signal_index += QMetaObjectPrivate::signalOffset(smeta);
2733 signal_found = true;
2737 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
2739 const QMetaObject *rmeta = receiver->metaObject();
2741 int method_index = QMetaObjectPrivate::indexOfMethod(
2742 rmeta, methodName, methodTypes.size(), methodTypes.constData());
2743 if (method_index >= 0)
2744 while (method_index < rmeta->methodOffset())
2745 rmeta = rmeta->superClass();
2746 if (method_index < 0)
2748 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
2749 method_found = true;
2750 } while ((rmeta = rmeta->superClass()));
2752 } while (signal && (smeta = smeta->superClass()));
2754 if (signal && !signal_found) {
2755 err_method_notfound(sender, signal_arg, "disconnect");
2756 err_info_about_objects("disconnect", sender, receiver);
2757 } else if (method && !method_found) {
2758 err_method_notfound(receiver, method_arg, "disconnect");
2759 err_info_about_objects("disconnect", sender, receiver);
2763 const_cast<QObject*>(sender)->disconnectNotify(QMetaMethod());
2771 Disconnects \a signal in object \a sender from \a method in object
2772 \a receiver. Returns true if the connection is successfully broken;
2773 otherwise returns false.
2775 This function provides the same possibilities like
2776 disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2777 but uses QMetaMethod to represent the signal and the method to be disconnected.
2779 Additionally this function returnsfalse and no signals and slots disconnected
2783 \li \a signal is not a member of sender class or one of its parent classes.
2785 \li \a method is not a member of receiver class or one of its parent classes.
2787 \li \a signal instance represents not a signal.
2791 QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
2792 In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
2793 method should also be QMetaMethod(). \a sender parameter should be never 0.
2795 \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2797 bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
2798 const QObject *receiver, const QMetaMethod &method)
2800 if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
2801 qWarning("QObject::disconnect: Unexpected null parameter");
2805 if(signal.methodType() != QMetaMethod::Signal) {
2806 qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
2807 "disconnect","unbind",
2808 sender->metaObject()->className(), signal.methodSignature().constData());
2813 if(method.methodType() == QMetaMethod::Constructor) {
2814 qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
2815 receiver->metaObject()->className(), method.methodSignature().constData());
2820 // Reconstructing SIGNAL() macro result for signal.methodSignature() string
2821 QByteArray signalSignature;
2823 signalSignature.reserve(signal.methodSignature().size()+1);
2824 signalSignature.append((char)(QSIGNAL_CODE + '0'));
2825 signalSignature.append(signal.methodSignature());
2832 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2833 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2835 // If we are here sender is not null. If signal is not null while signal_index
2836 // is -1 then this signal is not a member of sender.
2837 if (signal.mobj && signal_index == -1) {
2838 qWarning("QObject::disconect: signal %s not found on class %s",
2839 signal.methodSignature().constData(), sender->metaObject()->className());
2842 // If this condition is true then method is not a member of receeiver.
2843 if (receiver && method.mobj && method_index == -1) {
2844 qWarning("QObject::disconect: method %s not found on class %s",
2845 method.methodSignature().constData(), receiver->metaObject()->className());
2849 if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
2852 if (!signal.isValid()) {
2853 // The signal is a wildcard, meaning all signals were disconnected.
2854 // QMetaObjectPrivate::disconnect() doesn't call disconnectNotify()
2855 // per connection in this case. Call it once now, with an invalid
2856 // QMetaMethod as argument, as documented.
2857 const_cast<QObject*>(sender)->disconnectNotify(signal);
2865 \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method) const
2866 \overload disconnect()
2868 Disconnects \a signal from \a method of \a receiver.
2870 A signal-slot connection is removed when either of the objects
2871 involved are destroyed.
2875 \fn bool QObject::disconnect(const QObject *receiver, const char *method) const
2876 \overload disconnect()
2878 Disconnects all signals in this object from \a receiver's \a
2881 A signal-slot connection is removed when either of the objects
2882 involved are destroyed.
2889 This virtual function is called when something has been connected
2890 to \a signal in this object.
2892 If you want to compare \a signal with a specific signal, you can
2893 use QMetaMethod::fromSignal() as follows:
2895 \snippet code/src_corelib_kernel_qobject.cpp 32
2897 \warning This function violates the object-oriented principle of
2898 modularity. However, it might be useful when you need to perform
2899 expensive initialization only if something is connected to a
2902 \sa connect(), disconnectNotify()
2905 void QObject::connectNotify(const QMetaMethod &signal)
2913 This virtual function is called when something has been
2914 disconnected from \a signal in this object.
2916 See connectNotify() for an example of how to compare
2917 \a signal with a specific signal.
2919 If all signals were disconnected from this object (e.g., the
2920 signal argument to disconnect() was 0), disconnectNotify()
2921 is only called once, and the \a signal will be an invalid
2922 QMetaMethod (QMetaMethod::isValid() returns false).
2924 \warning This function violates the object-oriented principle of
2925 modularity. However, it might be useful for optimizing access to
2926 expensive resources.
2928 \sa disconnect(), connectNotify()
2931 void QObject::disconnectNotify(const QMetaMethod &signal)
2937 convert a signal index from the method range to the signal range
2939 static int methodIndexToSignalIndex(const QMetaObject **base, int signal_index)
2941 if (signal_index < 0)
2942 return signal_index;
2943 const QMetaObject *metaObject = *base;
2944 while (metaObject && metaObject->methodOffset() > signal_index)
2945 metaObject = metaObject->superClass();
2948 int signalOffset, methodOffset;
2949 computeOffsets(metaObject, &signalOffset, &methodOffset);
2950 if (signal_index < metaObject->methodCount())
2951 signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
2953 signal_index = signal_index - methodOffset + signalOffset;
2956 return signal_index;
2960 \a types is a 0-terminated vector of meta types for queued
2963 if \a signal_index is -1, then we effectively connect *all* signals
2964 from the sender to the receiver's slot
2966 QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_index,
2967 const QObject *receiver, int method_index, int type, int *types)
2969 const QMetaObject *smeta = sender->metaObject();
2970 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
2971 return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
2972 receiver, method_index,
2973 0, //FIXME, we could speed this connection up by computing the relative index
2978 Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
2980 method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
2982 the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
2984 QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
2985 int signal_index, const QMetaObject *smeta,
2986 const QObject *receiver, int method_index,
2987 const QMetaObject *rmeta, int type, int *types)
2989 QObject *s = const_cast<QObject *>(sender);
2990 QObject *r = const_cast<QObject *>(receiver);
2992 int method_offset = rmeta ? rmeta->methodOffset() : 0;
2993 Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
2994 QObjectPrivate::StaticMetaCallFunction callFunction =
2995 rmeta ? rmeta->d.static_metacall : 0;
2997 QOrderedMutexLocker locker(signalSlotLock(sender),
2998 signalSlotLock(receiver));
3000 if (type & Qt::UniqueConnection) {
3001 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3002 if (connectionLists && connectionLists->count() > signal_index) {
3003 const QObjectPrivate::Connection *c2 =
3004 (*connectionLists)[signal_index].first;
3006 int method_index_absolute = method_index + method_offset;
3009 if (c2->receiver == receiver && c2->method() == method_index_absolute)
3011 c2 = c2->nextConnectionList;
3014 type &= Qt::UniqueConnection - 1;
3017 QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
3020 c->method_relative = method_index;
3021 c->method_offset = method_offset;
3022 c->connectionType = type;
3023 c->isSlotObject = false;
3024 c->argumentTypes.store(types);
3025 c->nextConnectionList = 0;
3026 c->callFunction = callFunction;
3028 QObjectPrivate::get(s)->addConnection(signal_index, c.data());
3031 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3032 if (smethod.isValid())
3033 s->connectNotify(smethod);
3040 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3041 const QObject *receiver, int method_index)
3043 const QMetaObject *smeta = sender->metaObject();
3044 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3045 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3046 receiver, method_index, 0);
3051 Disconnect a single signal connection. If QMetaObject::connect() has been called
3052 multiple times for the same sender, signal_index, receiver and method_index only
3053 one of these connections will be removed.
3055 bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3056 const QObject *receiver, int method_index)
3058 const QMetaObject *smeta = sender->metaObject();
3059 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3060 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3061 receiver, method_index, 0,
3062 QMetaObjectPrivate::DisconnectOne);
3066 Helper function to remove the connection from the senders list and setting the receivers to 0
3068 bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
3069 const QObject *receiver, int method_index, void **slot,
3070 QMutex *senderMutex, DisconnectType disconnectType)
3072 bool success = false;
3075 && (receiver == 0 || (c->receiver == receiver
3076 && (method_index < 0 || c->method() == method_index)
3077 && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
3078 bool needToUnlock = false;
3079 QMutex *receiverMutex = 0;
3081 receiverMutex = signalSlotLock(c->receiver);
3082 // need to relock this receiver and sender in the correct order
3083 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3088 c->next->prev = c->prev;
3092 receiverMutex->unlock();
3098 if (disconnectType == DisconnectOne)
3101 c = c->nextConnectionList;
3107 Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3109 bool QMetaObjectPrivate::disconnect(const QObject *sender,
3110 int signal_index, const QMetaObject *smeta,
3111 const QObject *receiver, int method_index, void **slot,
3112 DisconnectType disconnectType)
3117 QObject *s = const_cast<QObject *>(sender);
3119 QMutex *senderMutex = signalSlotLock(sender);
3120 QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
3121 QOrderedMutexLocker locker(senderMutex, receiverMutex);
3123 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3124 if (!connectionLists)
3127 // prevent incoming connections changing the connectionLists while unlocked
3128 ++connectionLists->inUse;
3130 bool success = false;
3131 if (signal_index < 0) {
3132 // remove from all connection lists
3133 for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
3134 QObjectPrivate::Connection *c =
3135 (*connectionLists)[sig_index].first;
3136 if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3138 connectionLists->dirty = true;
3141 } else if (signal_index < connectionLists->count()) {
3142 QObjectPrivate::Connection *c =
3143 (*connectionLists)[signal_index].first;
3144 if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
3146 connectionLists->dirty = true;
3150 --connectionLists->inUse;
3151 Q_ASSERT(connectionLists->inUse >= 0);
3152 if (connectionLists->orphaned && !connectionLists->inUse)
3153 delete connectionLists;
3157 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3158 if (smethod.isValid())
3159 s->disconnectNotify(smethod);
3166 \fn void QMetaObject::connectSlotsByName(QObject *object)
3168 Searches recursively for all child objects of the given \a object, and connects
3169 matching signals from them to slots of \a object that follow the following form:
3171 \snippet code/src_corelib_kernel_qobject.cpp 33
3173 Let's assume our object has a child object of type QPushButton with
3174 the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3175 button's \c{clicked()} signal would be:
3177 \snippet code/src_corelib_kernel_qobject.cpp 34
3179 \sa QObject::setObjectName()
3181 void QMetaObject::connectSlotsByName(QObject *o)
3185 const QMetaObject *mo = o->metaObject();
3187 const QObjectList list = o->findChildren<QObject *>(QString());
3188 for (int i = 0; i < mo->methodCount(); ++i) {
3189 QByteArray slotSignature = mo->method(i).methodSignature();
3190 const char *slot = slotSignature.constData();
3192 if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3194 bool foundIt = false;
3195 for(int j = 0; j < list.count(); ++j) {
3196 const QObject *co = list.at(j);
3197 QByteArray objName = co->objectName().toLatin1();
3198 int len = objName.length();
3199 if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
3201 const QMetaObject *smeta;
3202 int sigIndex = co->d_func()->signalIndex(slot + len + 4, &smeta);
3203 if (sigIndex < 0) { // search for compatible signals
3204 const QMetaObject *smo = co->metaObject();
3205 int slotlen = qstrlen(slot + len + 4) - 1;
3206 for (int k = 0; k < QMetaObjectPrivate::absoluteSignalCount(smo); ++k) {
3207 QMetaMethod method = QMetaObjectPrivate::signal(smo, k);
3208 if (!qstrncmp(method.methodSignature().constData(), slot + len + 4, slotlen)) {
3209 smeta = method.enclosingMetaObject();
3218 if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
3224 // we found our slot, now skip all overloads
3225 while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3227 } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3228 qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3233 static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3235 const int *argumentTypes = c->argumentTypes.load();
3236 if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) {
3237 QMetaMethod m = sender->metaObject()->method(signal);
3238 argumentTypes = queuedConnectionTypes(m.parameterTypes());
3239 if (!argumentTypes) // cannot queue arguments
3240 argumentTypes = &DIRECT_CONNECTION_ONLY;
3241 if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
3242 if (argumentTypes != &DIRECT_CONNECTION_ONLY)
3243 delete [] argumentTypes;
3244 argumentTypes = c->argumentTypes.load();
3247 if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3249 int nargs = 1; // include return type
3250 while (argumentTypes[nargs-1])
3252 int *types = (int *) malloc(nargs*sizeof(int));
3254 void **args = (void **) malloc(nargs*sizeof(void *));
3256 types[0] = 0; // return type
3257 args[0] = 0; // return value
3258 for (int n = 1; n < nargs; ++n)
3259 args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]);
3260 QMetaCallEvent *ev = c->isSlotObject ?
3261 new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
3262 new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
3263 QCoreApplication::postEvent(c->receiver, ev);
3268 void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
3273 computeOffsets(m, &signalOffset, &methodOffset);
3274 activate(sender, methodOffset, signalOffset, local_signal_index, argv);
3279 void QMetaObject::activate(QObject *sender, int methodOffset, int signalOffset, int local_signal_index,
3282 int signal_index = signalOffset + local_signal_index;
3284 if (sender->d_func()->declarativeData && QAbstractDeclarativeData::signalEmitted)
3285 QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
3286 methodOffset + local_signal_index, argv);
3288 if (!sender->d_func()->isSignalConnected(signal_index))
3289 return; // nothing connected to these signals, and no spy
3291 if (sender->d_func()->blockSig)
3294 int signal_absolute_index = methodOffset + local_signal_index;
3296 void *empty_argv[] = { 0 };
3297 if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
3298 qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
3299 argv ? argv : empty_argv);
3302 Qt::HANDLE currentThreadId = QThread::currentThreadId();
3305 QMutexLocker locker(signalSlotLock(sender));
3306 struct ConnectionListsRef {
3307 QObjectConnectionListVector *connectionLists;
3308 ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
3310 if (connectionLists)
3311 ++connectionLists->inUse;
3313 ~ConnectionListsRef()
3315 if (!connectionLists)
3318 --connectionLists->inUse;
3319 Q_ASSERT(connectionLists->inUse >= 0);
3320 if (connectionLists->orphaned) {
3321 if (!connectionLists->inUse)
3322 delete connectionLists;
3326 QObjectConnectionListVector *operator->() const { return connectionLists; }
3328 ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
3329 if (!connectionLists.connectionLists) {
3331 if (qt_signal_spy_callback_set.signal_end_callback != 0)
3332 qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3336 const QObjectPrivate::ConnectionList *list;
3337 if (signal_index < connectionLists->count())
3338 list = &connectionLists->at(signal_index);
3340 list = &connectionLists->allsignals;
3343 QObjectPrivate::Connection *c = list->first;
3345 // We need to check against last here to ensure that signals added
3346 // during the signal emission are not emitted in this emission.
3347 QObjectPrivate::Connection *last = list->last;
3353 QObject * const receiver = c->receiver;
3354 const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
3356 // determine if this connection should be sent immediately or
3357 // put into the event queue
3358 if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
3359 || (c->connectionType == Qt::QueuedConnection)) {
3360 queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
3362 #ifndef QT_NO_THREAD
3363 } else if (c->connectionType == Qt::BlockingQueuedConnection) {
3365 if (receiverInSameThread) {
3366 qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: "
3367 "Sender is %s(%p), receiver is %s(%p)",
3368 sender->metaObject()->className(), sender,
3369 receiver->metaObject()->className(), receiver);
3371 QSemaphore semaphore;
3372 QMetaCallEvent *ev = c->isSlotObject ?
3373 new QMetaCallEvent(c->slotObj, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore) :
3374 new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_absolute_index, 0, 0, argv ? argv : empty_argv, &semaphore);
3375 QCoreApplication::postEvent(receiver, ev);
3376 semaphore.acquire();
3382 QConnectionSenderSwitcher sw;
3384 if (receiverInSameThread) {
3385 sw.switchSender(receiver, sender, signal_absolute_index);
3387 const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
3388 const int method_relative = c->method_relative;
3389 if (c->isSlotObject) {
3390 QExplicitlySharedDataPointer<QObject::QSlotObjectBase> obj(c->slotObj);
3392 obj->call(receiver, argv ? argv : empty_argv);
3394 } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
3395 //we compare the vtable to make sure we are not in the destructor of the object.
3397 if (qt_signal_spy_callback_set.slot_begin_callback != 0)
3398 qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
3400 callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
3402 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3403 qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
3406 const int method = method_relative + c->method_offset;
3409 if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
3410 qt_signal_spy_callback_set.slot_begin_callback(receiver,
3412 argv ? argv : empty_argv);
3415 metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
3417 if (qt_signal_spy_callback_set.slot_end_callback != 0)
3418 qt_signal_spy_callback_set.slot_end_callback(receiver, method);
3423 if (connectionLists->orphaned)
3425 } while (c != last && (c = c->nextConnectionList) != 0);
3427 if (connectionLists->orphaned)
3429 } while (list != &connectionLists->allsignals &&
3430 //start over for all signals;
3431 ((list = &connectionLists->allsignals), true));
3435 if (qt_signal_spy_callback_set.signal_end_callback != 0)
3436 qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3441 signal_index comes from indexOfMethod()
3443 void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
3445 const QMetaObject *mo = sender->metaObject();
3446 while (mo->methodOffset() > signal_index)
3447 mo = mo->superClass();
3448 activate(sender, mo, signal_index - mo->methodOffset(), argv);
3452 Implementation of QObject::senderSignalIndex()
3454 int QObjectPrivate::senderSignalIndex() const
3457 QMutexLocker locker(signalSlotLock(q));
3461 for (QObjectPrivate::Connection *c = senders; c; c = c->next) {
3462 if (c->sender == currentSender->sender)
3463 return currentSender->signal;
3470 Returns the signal index used in the internal connectionLists vector.
3472 It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
3473 while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
3475 If \a meta is not 0, it is set to the meta-object where the signal was found.
3477 int QObjectPrivate::signalIndex(const char *signalName,
3478 const QMetaObject **meta) const
3481 const QMetaObject *base = q->metaObject();
3482 Q_ASSERT(QMetaObjectPrivate::get(base)->revision >= 7);
3483 QArgumentTypeArray types;
3484 QByteArray name = QMetaObjectPrivate::decodeMethodSignature(signalName, types);
3485 int relative_index = QMetaObjectPrivate::indexOfSignalRelative(
3486 &base, name, types.size(), types.constData());
3487 if (relative_index < 0)
3488 return relative_index;
3489 relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
3492 return relative_index + QMetaObjectPrivate::signalOffset(base);
3495 /*****************************************************************************
3497 *****************************************************************************/
3499 #ifndef QT_NO_PROPERTIES
3502 Sets the value of the object's \a name property to \a value.
3504 If the property is defined in the class using Q_PROPERTY then
3505 true is returned on success and false otherwise. If the property
3506 is not defined using Q_PROPERTY, and therefore not listed in the
3507 meta-object, it is added as a dynamic property and false is returned.
3509 Information about all available properties is provided through the
3510 metaObject() and dynamicPropertyNames().
3512 Dynamic properties can be queried again using property() and can be
3513 removed by setting the property value to an invalid QVariant.
3514 Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent
3515 to be sent to the object.
3517 \b{Note:} Dynamic properties starting with "_q_" are reserved for internal
3520 \sa property(), metaObject(), dynamicPropertyNames()
3522 bool QObject::setProperty(const char *name, const QVariant &value)
3525 const QMetaObject* meta = metaObject();
3529 int id = meta->indexOfProperty(name);
3532 d->extraData = new QObjectPrivate::ExtraData;
3534 const int idx = d->extraData->propertyNames.indexOf(name);
3536 if (!value.isValid()) {
3539 d->extraData->propertyNames.removeAt(idx);
3540 d->extraData->propertyValues.removeAt(idx);
3543 d->extraData->propertyNames.append(name);
3544 d->extraData->propertyValues.append(value);
3546 d->extraData->propertyValues[idx] = value;
3550 QDynamicPropertyChangeEvent ev(name);
3551 QCoreApplication::sendEvent(this, &ev);
3555 QMetaProperty p = meta->property(id);
3557 if (!p.isWritable())
3558 qWarning("%s::setProperty: Property \"%s\" invalid,"
3559 " read-only or does not exist", metaObject()->className(), name);
3561 return p.write(this, value);
3565 Returns the value of the object's \a name property.
3567 If no such property exists, the returned variant is invalid.
3569 Information about all available properties is provided through the
3570 metaObject() and dynamicPropertyNames().
3572 \sa setProperty(), QVariant::isValid(), metaObject(), dynamicPropertyNames()
3574 QVariant QObject::property(const char *name) const
3577 const QMetaObject* meta = metaObject();
3581 int id = meta->indexOfProperty(name);
3585 const int i = d->extraData->propertyNames.indexOf(name);
3586 return d->extraData->propertyValues.value(i);
3588 QMetaProperty p = meta->property(id);
3590 if (!p.isReadable())
3591 qWarning("%s::property: Property \"%s\" invalid or does not exist",
3592 metaObject()->className(), name);
3594 return p.read(this);
3600 Returns the names of all properties that were dynamically added to
3601 the object using setProperty().
3603 QList<QByteArray> QObject::dynamicPropertyNames() const
3607 return d->extraData->propertyNames;
3608 return QList<QByteArray>();
3611 #endif // QT_NO_PROPERTIES
3614 /*****************************************************************************
3615 QObject debugging output routines.
3616 *****************************************************************************/
3618 static void dumpRecursive(int level, QObject *object)
3620 #if defined(QT_DEBUG)
3623 buf.fill(' ', level / 2 * 8);
3626 QString name = object->objectName();
3627 QString flags = QLatin1String("");
3629 if (qApp->focusWidget() == object)
3631 if (object->isWidgetType()) {
3632 QWidget * w = (QWidget *)object;
3633 if (w->isVisible()) {
3634 QString t("<%1,%2,%3,%4>");
3635 flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
3641 qDebug("%s%s::%s %s", (const char*)buf, object->metaObject()->className(), name.toLocal8Bit().data(),
3642 flags.toLatin1().data());
3643 QObjectList children = object->children();
3644 if (!children.isEmpty()) {
3645 for (int i = 0; i < children.size(); ++i)
3646 dumpRecursive(level+1, children.at(i));
3656 Dumps a tree of children to the debug output.
3658 This function is useful for debugging, but does nothing if the
3659 library has been compiled in release mode (i.e. without debugging
3662 \sa dumpObjectInfo()
3665 void QObject::dumpObjectTree()
3667 dumpRecursive(0, this);
3671 Dumps information about signal connections, etc. for this object
3672 to the debug output.
3674 This function is useful for debugging, but does nothing if the
3675 library has been compiled in release mode (i.e. without debugging
3678 \sa dumpObjectTree()
3681 void QObject::dumpObjectInfo()
3683 #if defined(QT_DEBUG)
3684 qDebug("OBJECT %s::%s", metaObject()->className(),
3685 objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
3688 QMutexLocker locker(signalSlotLock(this));
3690 // first, look for connections where this object is the sender
3691 qDebug(" SIGNALS OUT");
3693 if (d->connectionLists) {
3694 for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) {
3695 const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
3696 qDebug(" signal: %s", signal.methodSignature().constData());
3699 const QObjectPrivate::Connection *c =
3700 d->connectionLists->at(signal_index).first;
3703 qDebug(" <Disconnected receiver>");
3704 c = c->nextConnectionList;
3707 const QMetaObject *receiverMetaObject = c->receiver->metaObject();
3708 const QMetaMethod method = receiverMetaObject->method(c->method());
3709 qDebug(" --> %s::%s %s",
3710 receiverMetaObject->className(),
3711 c->receiver->objectName().isEmpty() ? "unnamed" : qPrintable(c->receiver->objectName()),
3712 method.methodSignature().constData());
3713 c = c->nextConnectionList;
3717 qDebug( " <None>" );
3720 // now look for connections where this object is the receiver
3721 qDebug(" SIGNALS IN");
3724 for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
3725 const QMetaMethod slot = metaObject()->method(s->method());
3726 qDebug(" <-- %s::%s %s",
3727 s->sender->metaObject()->className(),
3728 s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
3729 slot.methodSignature().constData());
3737 #ifndef QT_NO_USERDATA
3740 uint QObject::registerUserData()
3742 static int user_data_registration = 0;
3743 return user_data_registration++;
3748 QObjectUserData::~QObjectUserData()
3754 void QObject::setUserData(uint id, QObjectUserData* data)
3758 d->extraData = new QObjectPrivate::ExtraData;
3760 if (d->extraData->userData.size() <= (int) id)
3761 d->extraData->userData.resize((int) id + 1);
3762 d->extraData->userData[id] = data;
3767 QObjectUserData* QObject::userData(uint id) const
3772 if ((int)id < d->extraData->userData.size())
3773 return d->extraData->userData.at(id);
3777 #endif // QT_NO_USERDATA
3780 #ifndef QT_NO_DEBUG_STREAM
3781 QDebug operator<<(QDebug dbg, const QObject *o) {
3783 return dbg << "QObject(0x0) ";
3784 dbg.nospace() << o->metaObject()->className() << '(' << (void *)o;
3785 if (!o->objectName().isEmpty())
3786 dbg << ", name = " << o->objectName();
3793 \macro Q_CLASSINFO(Name, Value)
3796 This macro associates extra information to the class, which is
3797 available using QObject::metaObject(). Except for the ActiveQt
3798 extension, Qt doesn't use this information.
3800 The extra information takes the form of a \a Name string and a \a
3801 Value literal string.
3805 \snippet code/src_corelib_kernel_qobject.cpp 35
3807 \sa QMetaObject::classInfo()
3811 \macro Q_INTERFACES(...)
3814 This macro tells Qt which interfaces the class implements. This
3815 is used when implementing plugins.
3819 \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
3821 \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
3823 See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
3824 Basic Tools} example for details.
3826 \sa Q_DECLARE_INTERFACE(), Q_EXPORT_PLUGIN2(), {How to Create Qt Plugins}
3830 \macro Q_PROPERTY(...)
3833 This macro is used for declaring properties in classes that
3834 inherit QObject. Properties behave like class data members, but
3835 they have additional features accessible through the \l
3836 {Meta-Object System}.
3838 \snippet code/src_corelib_kernel_qobject.cpp 36
3840 The property name and type and the \c READ function are required.
3841 The type can be any type supported by QVariant, or it can be a
3842 user-defined type. The other items are optional, but a \c WRITE
3843 function is common. The attributes default to true except \c USER,
3844 which defaults to false.
3848 \snippet code/src_corelib_kernel_qobject.cpp 37
3850 For more details about how to use this macro, and a more detailed
3851 example of its use, see the discussion on \l {Qt's Property System}.
3853 \sa {Qt's Property System}
3860 This macro registers one or several enum types to the meta-object
3865 \snippet code/src_corelib_kernel_qobject.cpp 38
3867 If you want to register an enum that is declared in another class,
3868 the enum must be fully qualified with the name of the class
3869 defining it. In addition, the class \e defining the enum has to
3870 inherit QObject as well as declare the enum using Q_ENUMS().
3872 \sa {Qt's Property System}
3879 This macro registers one or several \l{QFlags}{flags types} to the
3880 meta-object system. It is typically used in a class definition to declare
3881 that values of a given enum can be used as flags and combined using the
3882 bitwise OR operator.
3884 For example, in QLibrary, the \l{QLibrary::LoadHints}{LoadHints} flag is
3885 declared in the following way:
3887 \snippet code/src_corelib_kernel_qobject.cpp 39a
3889 The declaration of the flags themselves is performed in the public section
3890 of the QLibrary class itself, using the \l Q_DECLARE_FLAGS() macro:
3892 \snippet code/src_corelib_kernel_qobject.cpp 39b
3894 \note This macro takes care of registering individual flag values
3895 with the meta-object system, so it is unnecessary to use Q_ENUMS()
3896 in addition to this macro.
3898 \sa {Qt's Property System}
3905 The Q_OBJECT macro must appear in the private section of a class
3906 definition that declares its own signals and slots or that uses
3907 other services provided by Qt's meta-object system.
3911 \snippet signalsandslots/signalsandslots.h 1
3913 \snippet signalsandslots/signalsandslots.h 2
3914 \snippet signalsandslots/signalsandslots.h 3
3916 \note This macro requires the class to be a subclass of QObject. Use
3917 Q_GADGET instead of Q_OBJECT to enable the meta object system's support
3918 for enums in a class that is not a QObject subclass. Q_GADGET makes a
3919 class member, \c{staticMetaObject}, available.
3920 \c{staticMetaObject} is of type QMetaObject and provides access to the
3921 enums declared with Q_ENUMS.
3922 Q_GADGET is provided only for C++.
3924 \sa {Meta-Object System}, {Signals and Slots}, {Qt's Property System}
3931 Use this macro to replace the \c signals keyword in class
3932 declarations, when you want to use Qt Signals and Slots with a
3933 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3935 The macro is normally used when \c no_keywords is specified with
3936 the \c CONFIG variable in the \c .pro file, but it can be used
3937 even when \c no_keywords is \e not specified.
3944 This is an additional macro that allows you to mark a single
3945 function as a signal. It can be quite useful, especially when you
3946 use a 3rd-party source code parser which doesn't understand a \c
3947 signals or \c Q_SIGNALS groups.
3949 Use this macro to replace the \c signals keyword in class
3950 declarations, when you want to use Qt Signals and Slots with a
3951 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3953 The macro is normally used when \c no_keywords is specified with
3954 the \c CONFIG variable in the \c .pro file, but it can be used
3955 even when \c no_keywords is \e not specified.
3962 Use this macro to replace the \c slots keyword in class
3963 declarations, when you want to use Qt Signals and Slots with a
3964 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3966 The macro is normally used when \c no_keywords is specified with
3967 the \c CONFIG variable in the \c .pro file, but it can be used
3968 even when \c no_keywords is \e not specified.
3975 This is an additional macro that allows you to mark a single
3976 function as a slot. It can be quite useful, especially when you
3977 use a 3rd-party source code parser which doesn't understand a \c
3978 slots or \c Q_SLOTS groups.
3980 Use this macro to replace the \c slots keyword in class
3981 declarations, when you want to use Qt Signals and Slots with a
3982 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3984 The macro is normally used when \c no_keywords is specified with
3985 the \c CONFIG variable in the \c .pro file, but it can be used
3986 even when \c no_keywords is \e not specified.
3993 Use this macro to replace the \c emit keyword for emitting
3994 signals, when you want to use Qt Signals and Slots with a
3995 \l{3rd Party Signals and Slots} {3rd party signal/slot mechanism}.
3997 The macro is normally used when \c no_keywords is specified with
3998 the \c CONFIG variable in the \c .pro file, but it can be used
3999 even when \c no_keywords is \e not specified.
4006 Apply this macro to definitions of member functions to allow them to
4007 be invoked via the meta-object system. The macro is written before
4008 the return type, as shown in the following example:
4010 \snippet qmetaobject-invokable/window.h Window class with invokable method
4012 The \c invokableMethod() function is marked up using Q_INVOKABLE, causing
4013 it to be registered with the meta-object system and enabling it to be
4014 invoked using QMetaObject::invokeMethod().
4015 Since \c normalMethod() function is not registered in this way, it cannot
4016 be invoked using QMetaObject::invokeMethod().
4020 \typedef QObjectList
4023 Synonym for QList<QObject *>.
4026 void qDeleteInEventHandler(QObject *o)
4032 \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
4036 Creates a connection of the given \a type from the \a signal in
4037 the \a sender object to the \a method in the \a receiver object.
4038 Returns a handle to the connection that can be used to disconnect
4041 The signal must be a function declared as a signal in the header.
4042 The slot function can be any member function that can be connected
4044 A slot can be connected to a given signal if the signal has at
4045 least as many arguments as the slot, and there is an implicit
4046 conversion between the types of the corresponding arguments in the
4047 signal and the slot.
4051 \snippet code/src_corelib_kernel_qobject.cpp 44
4053 This example ensures that the label always displays the current
4056 A signal can be connected to many slots and signals. Many signals
4057 can be connected to one slot.
4059 If a signal is connected to several slots, the slots are activated
4060 in the same order as the order the connection was made, when the
4063 The function returns an handle to a connection if it successfully
4064 connects the signal to the slot. The Connection handle will be invalid
4065 if it cannot create the connection, for example, if QObject is unable
4066 to verify the existence of \a signal (if it was not declared as a signal)
4067 You can check if the QMetaObject::Connection is valid by casting it to a bool.
4069 By default, a signal is emitted for every connection you make;
4070 two signals are emitted for duplicate connections. You can break
4071 all of these connections with a single disconnect() call.
4072 If you pass the Qt::UniqueConnection \a type, the connection will only
4073 be made if it is not a duplicate. If there is already a duplicate
4074 (exact same signal to the exact same slot on the same objects),
4075 the connection will fail and connect will return an invalid QMetaObject::Connection.
4077 The optional \a type parameter describes the type of connection
4078 to establish. In particular, it determines whether a particular
4079 signal is delivered to a slot immediately or queued for delivery
4080 at a later time. If the signal is queued, the parameters must be
4081 of types that are known to Qt's meta-object system, because Qt
4082 needs to copy the arguments to store them in an event behind the
4083 scenes. If you try to use a queued connection and get the error
4086 \snippet code/src_corelib_kernel_qobject.cpp 25
4088 make sure to declare the argument type with Q_DECLARE_METATYPE
4093 \fn QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
4098 Creates a connection of the given \a type from the \a signal in
4099 the \a sender object to the \a functor and returns a handle to the connection
4101 The signal must be a function declared as a signal in the header.
4102 The slot function can be any function or functor that can be connected
4104 A function can be connected to a given signal if the signal as at
4105 least as many argument as the slot. A functor can be connected to a signal
4106 if they have exactly the same number of arguments. There must exist implicit
4107 conversion between the types of the corresponding arguments in the
4108 signal and the slot.
4112 \snippet code/src_corelib_kernel_qobject.cpp 45
4114 If your compiler support C++11 lambda expressions, you can use them:
4116 \snippet code/src_corelib_kernel_qobject.cpp 46
4118 The connection will automatically disconnect if the sender is destroyed.
4123 Implementation of the template version of connect
4125 \a sender is the sender object
4126 \a signal is a pointer to a pointer to a member signal of the sender
4127 \a receiver is the receiver object, may not be null, will be equal to sender when
4128 connecting to a static function or a functor
4129 \a slot a pointer only used when using Qt::UniqueConnection
4130 \a type the Qt::ConnctionType passed as argument to connect
4131 \a types an array of integer with the metatype id of the parametter of the signal
4132 to be used with queued connection
4133 must stay valid at least for the whole time of the connection, this function
4134 do not take ownership. typically static data.
4135 If null, then the types will be computed when the signal is emit in a queued
4136 connection from the types from the signature.
4137 \a senderMetaObject is the metaobject used to lookup the signal, the signal must be in
4140 QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
4141 const QObject *receiver, void **slot,
4142 QObject::QSlotObjectBase *slotObj, Qt::ConnectionType type,
4143 const int *types, const QMetaObject *senderMetaObject)
4145 if (!sender || !signal || !slotObj || !senderMetaObject) {
4146 qWarning("QObject::connect: invalid null parametter");
4147 if (slotObj && !slotObj->ref.deref())
4149 return QMetaObject::Connection();
4151 int signal_index = -1;
4152 void *args[] = { &signal_index, signal };
4153 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4154 if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4155 qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
4156 if (!slotObj->ref.deref())
4158 return QMetaObject::Connection(0);
4160 signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
4162 QObject *s = const_cast<QObject *>(sender);
4163 QObject *r = const_cast<QObject *>(receiver);
4165 QOrderedMutexLocker locker(signalSlotLock(sender),
4166 signalSlotLock(receiver));
4168 if (type & Qt::UniqueConnection) {
4169 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
4170 if (connectionLists && connectionLists->count() > signal_index) {
4171 const QObjectPrivate::Connection *c2 =
4172 (*connectionLists)[signal_index].first;
4175 if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
4176 if (!slotObj->ref.deref())
4178 return QMetaObject::Connection();
4180 c2 = c2->nextConnectionList;
4183 type = static_cast<Qt::ConnectionType>(type ^ Qt::UniqueConnection);
4186 QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
4189 c->slotObj = slotObj;
4190 c->connectionType = type;
4191 c->isSlotObject = true;
4193 c->argumentTypes.store(types);
4194 c->ownArgumentTypes = false;
4197 QObjectPrivate::get(s)->addConnection(signal_index, c.data());
4198 QMetaObject::Connection ret(c.take());
4201 QMetaMethod method = QMetaObjectPrivate::signal(senderMetaObject, signal_index);
4202 Q_ASSERT(method.isValid());
4203 s->connectNotify(method);
4209 Disconnect a connection.
4211 If the \a connection is invalid or has already been disconnected, do nothing
4216 bool QObject::disconnect(const QMetaObject::Connection &connection)
4218 QObjectPrivate::Connection *c = static_cast<QObjectPrivate::Connection *>(connection.d_ptr);
4220 if (!c || !c->receiver)
4223 QMutex *senderMutex = signalSlotLock(c->sender);
4224 QMutex *receiverMutex = signalSlotLock(c->receiver);
4225 QOrderedMutexLocker locker(senderMutex, receiverMutex);
4227 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists;
4228 Q_ASSERT(connectionLists);
4229 connectionLists->dirty = true;
4233 c->next->prev = c->prev;
4235 // disconnectNotify() not called (the signal index is unknown).
4240 /*! \fn bool QObject::disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
4241 \overload diconnect()
4244 Disconnects \a signal in object \a sender from \a method in object
4245 \a receiver. Returns true if the connection is successfully broken;
4246 otherwise returns false.
4248 A signal-slot connection is removed when either of the objects
4249 involved are destroyed.
4251 disconnect() is typically used in three ways, as the following
4252 examples demonstrate.
4254 \li Disconnect everything connected to an object's signals:
4256 \snippet code/src_corelib_kernel_qobject.cpp 26
4258 \li Disconnect everything connected to a specific signal:
4260 \snippet code/src_corelib_kernel_qobject.cpp 47
4262 \li Disconnect a specific receiver:
4264 \snippet code/src_corelib_kernel_qobject.cpp 30
4266 \li Disconnect a connection from one specific signal to a specific slot:
4268 \snippet code/src_corelib_kernel_qobject.cpp 48
4273 0 may be used as a wildcard, meaning "any signal", "any receiving
4274 object", or "any slot in the receiving object", respectively.
4276 The \a sender may never be 0. (You cannot disconnect signals from
4277 more than one object in a single call.)
4279 If \a signal is 0, it disconnects \a receiver and \a method from
4280 any signal. If not, only the specified signal is disconnected.
4282 If \a receiver is 0, it disconnects anything connected to \a
4283 signal. If not, slots in objects other than \a receiver are not
4286 If \a method is 0, it disconnects anything that is connected to \a
4287 receiver. If not, only slots named \a method will be disconnected,
4288 and all other slots are left alone. The \a method must be 0 if \a
4289 receiver is left out, so you cannot disconnect a
4290 specifically-named slot on all objects.
4292 \note It is not possible to use this overload to diconnect signals
4293 connected to functors or lambda expressions. That is because it is not
4294 possible to compare them. Instead, use the olverload that take a
4295 QMetaObject::Connection
4300 bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot, const QMetaObject *senderMetaObject)
4302 if (sender == 0 || (receiver == 0 && slot != 0)) {
4303 qWarning("QObject::disconnect: Unexpected null parameter");
4307 int signal_index = -1;
4309 void *args[] = { &signal_index, signal };
4310 senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
4311 if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
4312 qWarning("QObject::disconnect: signal not found in %s", senderMetaObject->className());
4315 signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
4318 return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
4321 /*! \class QMetaObject::Connection
4322 Represents a handle to a signal-slot connection.
4323 It can be used to disconnect that connection, or check if
4324 the connection was successful
4326 \sa QObject::disconnect
4330 Create a copy of the handle to the connection
4332 QMetaObject::Connection::Connection(const QMetaObject::Connection &other) : d_ptr(other.d_ptr)
4335 static_cast<QObjectPrivate::Connection *>(d_ptr)->ref();
4338 QMetaObject::Connection& QMetaObject::Connection::operator=(const QMetaObject::Connection& other)
4340 if (other.d_ptr != d_ptr) {
4342 static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4343 d_ptr = other.d_ptr;
4345 static_cast<QObjectPrivate::Connection *>(other.d_ptr)->ref();
4350 QMetaObject::Connection::Connection() : d_ptr(0) {}
4352 QMetaObject::Connection::~Connection()
4355 static_cast<QObjectPrivate::Connection *>(d_ptr)->deref();
4359 \fn QMetaObject::Connection::operator bool() const
4361 Returns true if the connection is valid.
4363 The connection is valid if the call to QObject::connect succeeded.
4364 The connection is invalid if QObject::connect was not able to find
4365 the signal or the slot, or if the arguments do not match.
4368 QObject::QSlotObjectBase::~QSlotObjectBase()
4372 bool QObject::QSlotObjectBase::compare(void** )
4380 #include "moc_qobject.cpp"