1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include "qobject_p.h"
44 #include "qmetaobject_p.h"
46 #include "qabstracteventdispatcher.h"
47 #include "qcoreapplication.h"
48 #include "qcoreapplication_p.h"
50 #include "qmetaobject.h"
53 #include <private/qthread_p.h>
57 #include <qvarlengtharray.h>
59 #include <qsemaphore.h>
60 #include <qsharedpointer.h>
62 #include <private/qorderedmutexlocker_p.h>
63 #include <private/qmutexpool_p.h>
72 static int DIRECT_CONNECTION_ONLY = 0;
74 static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
76 int *types = new int [typeNames.count() + 1];
78 for (int i = 0; i < typeNames.count(); ++i) {
79 const QByteArray typeName = typeNames.at(i);
80 if (typeName.endsWith('*'))
81 types[i] = QMetaType::VoidStar;
83 types[i] = QMetaType::type(typeName);
86 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
87 "(Make sure '%s' is registered using qRegisterMetaType().)",
88 typeName.constData(), typeName.constData());
93 types[typeNames.count()] = 0;
98 static QBasicAtomicPointer<QMutexPool> signalSlotMutexes = Q_BASIC_ATOMIC_INITIALIZER(0);
99 static QBasicAtomicInt objectCount = Q_BASIC_ATOMIC_INITIALIZER(0);
102 * mutex to be locked when accessing the connectionlists or the senders list
104 static inline QMutex *signalSlotLock(const QObject *o)
106 if (!signalSlotMutexes) {
107 QMutexPool *mp = new QMutexPool;
108 if (!signalSlotMutexes.testAndSetOrdered(0, mp)) {
112 return signalSlotMutexes->get(o);
115 extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
120 extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
122 if(!objectCount.deref()) {
123 QMutexPool *old = signalSlotMutexes.fetchAndStoreAcquire(0);
128 void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
129 void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
130 void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0;
132 QObjectData::~QObjectData() {}
134 QObjectPrivate::QObjectPrivate(int version)
135 : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
137 if (version != QObjectPrivateVersion)
138 qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
139 version, QObjectPrivateVersion);
141 // QObjectData initialization
143 parent = 0; // no parent yet. It is set by setParent()
144 isWidget = false; // assume not a widget object
145 pendTimer = false; // no timers yet
146 blockSig = false; // not blocking signals
147 wasDeleted = false; // double-delete catcher
148 sendChildEvents = true; // if we should send ChildInsert and ChildRemove events to parent
149 receiveChildEvents = true;
152 connectedSignals[0] = connectedSignals[1] = 0;
153 inThreadChangeEvent = false;
154 #ifdef QT_JAMBI_BUILD
155 inEventHandler = false;
162 QObjectPrivate::~QObjectPrivate()
165 // unregister pending timers
166 if (threadData->eventDispatcher)
167 threadData->eventDispatcher->unregisterTimers(q_ptr);
171 QCoreApplication::removePostedEvents(q_ptr, 0);
175 delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
176 #ifdef QT_JAMBI_BUILD
180 #ifndef QT_NO_USERDATA
182 qDeleteAll(extraData->userData);
188 #ifdef QT_JAMBI_BUILD
189 int *QObjectPrivate::setDeleteWatch(QObjectPrivate *d, int *w) {
190 int *old = d->deleteWatch;
196 void QObjectPrivate::resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch) {
198 d->deleteWatch = oldWatch;
201 *oldWatch = deleteWatch;
206 void QObjectPrivate::sendPendingChildInsertedEvents()
209 for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {
210 QObject *c = pendingChildInsertedEvents.at(i).data();
211 if (!c || c->parent() != q)
213 QChildEvent childEvent(QEvent::ChildInserted, c);
214 QCoreApplication::sendEvent(q, &childEvent);
216 pendingChildInsertedEvents.clear();
223 For a given metaobject, compute the signal offset, and the method offset (including signals)
225 static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int *methodOffset)
227 *signalOffset = *methodOffset = 0;
228 const QMetaObject *m = metaobject->d.superdata;
230 const QMetaObjectPrivate *d = QMetaObjectPrivate::get(m);
231 *methodOffset += d->methodCount;
232 *signalOffset += (d->revision >= 4) ? d->signalCount : d->methodCount;
233 /*Before Qt 4.6 (revision 4), the signalCount information was not generated by moc.
234 so for compatibility we consider all the method as slot for old moc output*/
240 This vector contains the all connections from an object.
242 Each object may have one vector containing the lists of
243 connections for a given signal. The index in the vector correspond
244 to the signal index. The signal index is the one returned by
245 QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal).
246 Negative index means connections to all signals.
248 This vector is protected by the object mutex (signalSlotMutexes())
250 Each Connection is also part of a 'senders' linked list. The mutex
251 of the receiver must be locked when touching the pointers of this
254 class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList>
257 bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse
258 bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
259 int inUse; //number of functions that are currently accessing this object or its connections
260 QObjectPrivate::ConnectionList allsignals;
262 QObjectConnectionListVector()
263 : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0)
266 QObjectPrivate::ConnectionList &operator[](int at)
270 return QVector<QObjectPrivate::ConnectionList>::operator[](at);
274 // Used by QAccessibleWidget
275 bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
278 int signal_index = signalIndex(signal);
279 if (signal_index < 0)
281 QMutexLocker locker(signalSlotLock(q));
282 if (connectionLists) {
283 if (signal_index < connectionLists->count()) {
284 const QObjectPrivate::Connection *c =
285 connectionLists->at(signal_index).first;
288 if (c->receiver == receiver)
290 c = c->nextConnectionList;
297 // Used by QAccessibleWidget
298 QObjectList QObjectPrivate::receiverList(const char *signal) const
301 QObjectList returnValue;
302 int signal_index = signalIndex(signal);
303 if (signal_index < 0)
305 QMutexLocker locker(signalSlotLock(q));
306 if (connectionLists) {
307 if (signal_index < connectionLists->count()) {
308 const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
312 returnValue << c->receiver;
313 c = c->nextConnectionList;
320 // Used by QAccessibleWidget
321 QObjectList QObjectPrivate::senderList() const
323 QObjectList returnValue;
324 QMutexLocker locker(signalSlotLock(q_func()));
325 for (Connection *c = senders; c; c = c->next)
326 returnValue << c->sender;
330 void QObjectPrivate::addConnection(int signal, Connection *c)
332 if (!connectionLists)
333 connectionLists = new QObjectConnectionListVector();
334 if (signal >= connectionLists->count())
335 connectionLists->resize(signal + 1);
337 ConnectionList &connectionList = (*connectionLists)[signal];
338 if (connectionList.last) {
339 connectionList.last->nextConnectionList = c;
341 connectionList.first = c;
343 connectionList.last = c;
345 cleanConnectionLists();
348 void QObjectPrivate::cleanConnectionLists()
350 if (connectionLists->dirty && !connectionLists->inUse) {
351 // remove broken connections
352 for (int signal = -1; signal < connectionLists->count(); ++signal) {
353 QObjectPrivate::ConnectionList &connectionList =
354 (*connectionLists)[signal];
356 // Set to the last entry in the connection list that was *not*
357 // deleted. This is needed to update the list's last pointer
358 // at the end of the cleanup.
359 QObjectPrivate::Connection *last = 0;
361 QObjectPrivate::Connection **prev = &connectionList.first;
362 QObjectPrivate::Connection *c = *prev;
366 prev = &c->nextConnectionList;
369 QObjectPrivate::Connection *next = c->nextConnectionList;
376 // Correct the connection list's last pointer.
377 // As conectionList.last could equal last, this could be a noop
378 connectionList.last = last;
380 connectionLists->dirty = false;
384 typedef QMultiHash<QObject *, QObject **> GuardHash;
385 Q_GLOBAL_STATIC(GuardHash, guardHash)
386 Q_GLOBAL_STATIC(QMutex, guardHashLock)
390 void QMetaObject::addGuard(QObject **ptr)
394 GuardHash *hash = guardHash();
399 QMutexLocker locker(guardHashLock());
400 QObjectPrivate::get(*ptr)->hasGuards = true;
401 hash->insert(*ptr, ptr);
406 void QMetaObject::removeGuard(QObject **ptr)
410 GuardHash *hash = guardHash();
411 /* check that the hash is empty - otherwise we might detach
412 the shared_null hash, which will alloc, which is not nice */
413 if (!hash || hash->isEmpty())
415 QMutexLocker locker(guardHashLock());
416 if (!*ptr) //check again, under the lock
418 GuardHash::iterator it = hash->find(*ptr);
419 const GuardHash::iterator end = hash->end();
420 bool more = false; //if the QObject has more pointer attached to it.
421 for (; it.key() == *ptr && it != end; ++it) {
422 if (it.value() == ptr) {
423 it = hash->erase(it);
424 if (!more) more = (it != end && it.key() == *ptr);
430 QObjectPrivate::get(*ptr)->hasGuards = false;
435 void QMetaObject::changeGuard(QObject **ptr, QObject *o)
437 GuardHash *hash = guardHash();
442 QMutexLocker locker(guardHashLock());
444 hash->insert(o, ptr);
445 QObjectPrivate::get(o)->hasGuards = true;
448 bool more = false; //if the QObject has more pointer attached to it.
449 GuardHash::iterator it = hash->find(*ptr);
450 const GuardHash::iterator end = hash->end();
451 for (; it.key() == *ptr && it != end; ++it) {
452 if (it.value() == ptr) {
453 it = hash->erase(it);
454 if (!more) more = (it != end && it.key() == *ptr);
460 QObjectPrivate::get(*ptr)->hasGuards = false;
467 void QObjectPrivate::clearGuards(QObject *object)
473 mutex = guardHashLock();
474 } QT_CATCH(const std::bad_alloc &) {
475 // do nothing in case of OOM - code below is safe
478 /* check that the hash is empty - otherwise we might detach
479 the shared_null hash, which will alloc, which is not nice */
480 if (hash && !hash->isEmpty()) {
481 QMutexLocker locker(mutex);
482 GuardHash::iterator it = hash->find(object);
483 const GuardHash::iterator end = hash->end();
484 while (it.key() == object && it != end) {
486 it = hash->erase(it);
493 QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
494 const QObject *sender, int signalId,
495 int nargs, int *types, void **args, QSemaphore *semaphore)
496 : QEvent(MetaCall), sender_(sender), signalId_(signalId),
497 nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
498 callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
503 QMetaCallEvent::~QMetaCallEvent()
506 for (int i = 0; i < nargs_; ++i) {
507 if (types_[i] && args_[i])
508 QMetaType::destroy(types_[i], args_[i]);
515 semaphore_->release();
521 void QMetaCallEvent::placeMetaCall(QObject *object)
524 callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_);
526 QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_);
532 \brief The QObject class is the base class of all Qt objects.
538 QObject is the heart of the Qt \l{Object Model}. The central
539 feature in this model is a very powerful mechanism for seamless
540 object communication called \l{signals and slots}. You can
541 connect a signal to a slot with connect() and destroy the
542 connection with disconnect(). To avoid never ending notification
543 loops you can temporarily block signals with blockSignals(). The
544 protected functions connectNotify() and disconnectNotify() make
545 it possible to track connections.
547 QObjects organize themselves in \l {Object Trees & Ownership}
548 {object trees}. When you create a QObject with another object as
549 parent, the object will automatically add itself to the parent's
550 children() list. The parent takes ownership of the object; i.e.,
551 it will automatically delete its children in its destructor. You
552 can look for an object by name and optionally type using
553 findChild() or findChildren().
555 Every object has an objectName() and its class name can be found
556 via the corresponding metaObject() (see QMetaObject::className()).
557 You can determine whether the object's class inherits another
558 class in the QObject inheritance hierarchy by using the
561 When an object is deleted, it emits a destroyed() signal. You can
562 catch this signal to avoid dangling references to QObjects.
564 QObjects can receive events through event() and filter the events
565 of other objects. See installEventFilter() and eventFilter() for
566 details. A convenience handler, childEvent(), can be reimplemented
567 to catch child events.
569 Events are delivered in the thread in which the object was
570 created; see \l{Thread Support in Qt} and thread() for details.
571 Note that event processing is not done at all for QObjects with no
572 thread affinity (thread() returns zero). Use the moveToThread()
573 function to change the thread affinity for an object and its
574 children (the object cannot be moved if it has a parent).
576 Last but not least, QObject provides the basic timer support in
577 Qt; see QTimer for high-level support for timers.
579 Notice that the Q_OBJECT macro is mandatory for any object that
580 implements signals, slots or properties. You also need to run the
581 \l{moc}{Meta Object Compiler} on the source file. We strongly
582 recommend the use of this macro in all subclasses of QObject
583 regardless of whether or not they actually use signals, slots and
584 properties, since failure to do so may lead certain functions to
585 exhibit strange behavior.
587 All Qt widgets inherit QObject. The convenience function
588 isWidgetType() returns whether an object is actually a widget. It
590 \l{qobject_cast()}{qobject_cast}<QWidget *>(\e{obj}) or
591 \e{obj}->\l{inherits()}{inherits}("QWidget").
593 Some QObject functions, e.g. children(), return a QObjectList.
594 QObjectList is a typedef for QList<QObject *>.
596 \target No copy constructor
597 \section1 No copy constructor or assignment operator
599 QObject has neither a copy constructor nor an assignment operator.
600 This is by design. Actually, they are declared, but in a
601 \c{private} section with the macro Q_DISABLE_COPY(). In fact, all
602 Qt classes derived from QObject (direct or indirect) use this
603 macro to declare their copy constructor and assignment operator to
604 be private. The reasoning is found in the discussion on
605 \l{Identity vs Value} {Identity vs Value} on the Qt \l{Object
608 The main consequence is that you should use pointers to QObject
609 (or to your QObject subclass) where you might otherwise be tempted
610 to use your QObject subclass as a value. For example, without a
611 copy constructor, you can't use a subclass of QObject as the value
612 to be stored in one of the container classes. You must store
615 \section1 Auto-Connection
617 Qt's meta-object system provides a mechanism to automatically connect
618 signals and slots between QObject subclasses and their children. As long
619 as objects are defined with suitable object names, and slots follow a
620 simple naming convention, this connection can be performed at run-time
621 by the QMetaObject::connectSlotsByName() function.
623 \l uic generates code that invokes this function to enable
624 auto-connection to be performed between widgets on forms created
625 with \QD. More information about using auto-connection with \QD is
626 given in the \l{Using a Designer UI File in Your Application} section of
629 \section1 Dynamic Properties
631 From Qt 4.2, dynamic properties can be added to and removed from QObject
632 instances at run-time. Dynamic properties do not need to be declared at
633 compile-time, yet they provide the same advantages as static properties
634 and are manipulated using the same API - using property() to read them
635 and setProperty() to write them.
637 From Qt 4.3, dynamic properties are supported by
638 \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
639 and both standard Qt widgets and user-created forms can be given dynamic
642 \section1 Internationalization (i18n)
644 All QObject subclasses support Qt's translation features, making it possible
645 to translate an application's user interface into different languages.
647 To make user-visible text translatable, it must be wrapped in calls to
648 the tr() function. This is explained in detail in the
649 \l{Writing Source Code for Translation} document.
651 \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
652 \sa {Object Trees & Ownership}
658 Returns a pointer to the object named \a name that inherits \a
659 type and with a given \a parent.
661 Returns 0 if there is no such child.
663 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 0
666 void *qt_find_obj_child(QObject *parent, const char *type, const QString &name)
668 QObjectList list = parent->children();
669 if (list.size() == 0) return 0;
670 for (int i = 0; i < list.size(); ++i) {
671 QObject *obj = list.at(i);
672 if (name == obj->objectName() && obj->inherits(type))
679 /*****************************************************************************
680 QObject member functions
681 *****************************************************************************/
683 // check the constructor's parent thread argument
684 static bool check_parent_thread(QObject *parent,
685 QThreadData *parentThreadData,
686 QThreadData *currentThreadData)
688 if (parent && parentThreadData != currentThreadData) {
689 QThread *parentThread = parentThreadData->thread;
690 QThread *currentThread = currentThreadData->thread;
691 qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
692 "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
693 parent->metaObject()->className(),
695 parentThread ? parentThread->metaObject()->className() : "QThread",
697 currentThread ? currentThread->metaObject()->className() : "QThread",
705 Constructs an object with parent object \a parent.
707 The parent of an object may be viewed as the object's owner. For
708 instance, a \l{QDialog}{dialog box} is the parent of the \gui OK
709 and \gui Cancel buttons it contains.
711 The destructor of a parent object destroys all child objects.
713 Setting \a parent to 0 constructs an object with no parent. If the
714 object is a widget, it will become a top-level window.
716 \sa parent(), findChild(), findChildren()
719 QObject::QObject(QObject *parent)
720 : d_ptr(new QObjectPrivate)
724 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
725 d->threadData->ref();
728 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
732 d->threadData->deref();
744 Creates a new QObject with the given \a parent and object \a name.
746 QObject::QObject(QObject *parent, const char *name)
747 : d_ptr(new QObjectPrivate)
750 qt_addObject(d_ptr->q_ptr = this);
751 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
752 d->threadData->ref();
754 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
758 setObjectName(QString::fromAscii(name));
764 QObject::QObject(QObjectPrivate &dd, QObject *parent)
769 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
770 d->threadData->ref();
773 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
778 d->parent->d_func()->children.append(this);
780 // no events sent here, this is done at the end of the QWidget constructor
785 d->threadData->deref();
793 Destroys the object, deleting all its child objects.
795 All signals to and from the object are automatically disconnected, and
796 any pending posted events for the object are removed from the event
797 queue. However, it is often safer to use deleteLater() rather than
798 deleting a QObject subclass directly.
800 \warning All child objects are deleted. If any of these objects
801 are on the stack or global, sooner or later your program will
802 crash. We do not recommend holding pointers to child objects from
803 outside the parent. If you still do, the destroyed() signal gives
804 you an opportunity to detect when an object is destroyed.
806 \warning Deleting a QObject while pending events are waiting to
807 be delivered can cause a crash. You must not delete the QObject
808 directly if it exists in a different thread than the one currently
809 executing. Use deleteLater() instead, which will cause the event
810 loop to delete the object after all pending events have been
819 d->wasDeleted = true;
820 d->blockSig = 0; // unblock signals so we always emit destroyed()
822 if (d->hasGuards && !d->isWidget) {
823 // set all QPointers for this object to zero - note that
824 // ~QWidget() does this for us, so we don't have to do it twice
825 QObjectPrivate::clearGuards(this);
828 if (d->sharedRefcount) {
829 if (d->sharedRefcount->strongref > 0) {
830 qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash.");
831 // but continue deleting, it's too late to stop anyway
834 // indicate to all QWeakPointers that this QObject has now been deleted
835 d->sharedRefcount->strongref = 0;
836 if (!d->sharedRefcount->weakref.deref())
837 delete d->sharedRefcount;
841 if (d->isSignalConnected(0)) {
843 emit destroyed(this);
845 // all the signal/slots connections are still in place - if we don't
846 // quit now, we will crash pretty soon.
847 qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
852 if (d->declarativeData)
853 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
855 // set ref to zero to indicate that this object has been deleted
856 if (d->currentSender != 0)
857 d->currentSender->ref = 0;
858 d->currentSender = 0;
860 if (d->connectionLists || d->senders) {
861 QMutex *signalSlotMutex = signalSlotLock(this);
862 QMutexLocker locker(signalSlotMutex);
864 // disconnect all receivers
865 if (d->connectionLists) {
866 ++d->connectionLists->inUse;
867 int connectionListsCount = d->connectionLists->count();
868 for (int signal = -1; signal < connectionListsCount; ++signal) {
869 QObjectPrivate::ConnectionList &connectionList =
870 (*d->connectionLists)[signal];
872 while (QObjectPrivate::Connection *c = connectionList.first) {
874 connectionList.first = c->nextConnectionList;
879 QMutex *m = signalSlotLock(c->receiver);
880 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
884 if (c->next) c->next->prev = c->prev;
889 connectionList.first = c->nextConnectionList;
894 if (!--d->connectionLists->inUse) {
895 delete d->connectionLists;
897 d->connectionLists->orphaned = true;
899 d->connectionLists = 0;
902 // disconnect all senders
903 QObjectPrivate::Connection *node = d->senders;
905 QObject *sender = node->sender;
906 QMutex *m = signalSlotLock(sender);
908 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
909 //the node has maybe been removed while the mutex was unlocked in relock?
910 if (!node || node->sender != sender) {
915 QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
917 senderLists->dirty = true;
925 if (!d->children.isEmpty())
928 qt_removeObject(this);
930 if (d->parent) // remove it from parent object
931 d->setParent_helper(0);
933 #ifdef QT_JAMBI_BUILD
934 if (d->inEventHandler) {
935 qWarning("QObject: Do not delete object, '%s', during its event handler!",
936 objectName().isNull() ? "unnamed" : qPrintable(objectName()));
941 QObjectPrivate::Connection::~Connection()
943 if (argumentTypes != &DIRECT_CONNECTION_ONLY)
944 delete [] static_cast<int *>(argumentTypes);
949 \fn QMetaObject *QObject::metaObject() const
951 Returns a pointer to the meta-object of this object.
953 A meta-object contains information about a class that inherits
954 QObject, e.g. class name, superclass name, properties, signals and
955 slots. Every QObject subclass that contains the Q_OBJECT macro will have a
958 The meta-object information is required by the signal/slot
959 connection mechanism and the property system. The inherits()
960 function also makes use of the meta-object.
962 If you have no pointer to an actual object instance but still
963 want to access the meta-object of a class, you can use \l
968 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 1
974 \variable QObject::staticMetaObject
976 This variable stores the meta-object for the class.
978 A meta-object contains information about a class that inherits
979 QObject, e.g. class name, superclass name, properties, signals and
980 slots. Every class that contains the Q_OBJECT macro will also have
983 The meta-object information is required by the signal/slot
984 connection mechanism and the property system. The inherits()
985 function also makes use of the meta-object.
987 If you have a pointer to an object, you can use metaObject() to
988 retrieve the meta-object associated with that object.
992 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 2
997 /*! \fn T *qobject_cast<T *>(QObject *object)
1000 Returns the given \a object cast to type T if the object is of type
1001 T (or of a subclass); otherwise returns 0. If \a object is 0 then
1002 it will also return 0.
1004 The class T must inherit (directly or indirectly) QObject and be
1005 declared with the \l Q_OBJECT macro.
1007 A class is considered to inherit itself.
1011 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 3
1013 The qobject_cast() function behaves similarly to the standard C++
1014 \c dynamic_cast(), with the advantages that it doesn't require
1015 RTTI support and it works across dynamic library boundaries.
1017 qobject_cast() can also be used in conjunction with interfaces;
1018 see the \l{tools/plugandpaint}{Plug & Paint} example for details.
1020 \warning If T isn't declared with the Q_OBJECT macro, this
1021 function's return value is undefined.
1023 \sa QObject::inherits()
1027 \fn bool QObject::inherits(const char *className) const
1029 Returns true if this object is an instance of a class that
1030 inherits \a className or a QObject subclass that inherits \a
1031 className; otherwise returns false.
1033 A class is considered to inherit itself.
1037 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 4
1039 If you need to determine whether an object is an instance of a particular
1040 class for the purpose of casting it, consider using qobject_cast<Type *>(object)
1043 \sa metaObject(), qobject_cast()
1047 \property QObject::objectName
1049 \brief the name of this object
1051 You can find an object by name (and type) using findChild(). You can
1052 find a set of objects with findChildren().
1054 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5
1056 By default, this property contains an empty string.
1058 \sa metaObject(), QMetaObject::className()
1061 QString QObject::objectName() const
1064 return d->objectName;
1068 Sets the object's name to \a name.
1070 void QObject::setObjectName(const QString &name)
1073 bool objectNameChanged = d->declarativeData && d->objectName != name;
1075 d->objectName = name;
1077 if (objectNameChanged)
1078 d->declarativeData->objectNameChanged(d->declarativeData, this);
1084 QObject::child is compat but needs to call itself recursively,
1085 that's why we need this helper.
1087 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
1088 bool recursiveSearch, const QObjectList &children)
1090 if (children.isEmpty())
1093 bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
1094 const QLatin1String oName(objName);
1095 for (int i = 0; i < children.size(); ++i) {
1096 QObject *obj = children.at(i);
1098 if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
1100 } else if ((!inheritsClass || obj->inherits(inheritsClass))
1101 && (!objName || obj->objectName() == oName))
1103 if (recursiveSearch && (obj = qChildHelper(objName, inheritsClass,
1104 recursiveSearch, obj->children())))
1112 Searches the children and optionally grandchildren of this object,
1113 and returns a child that is called \a objName that inherits \a
1114 inheritsClass. If \a inheritsClass is 0 (the default), any class
1117 If \a recursiveSearch is true (the default), child() performs a
1118 depth-first search of the object's children.
1120 If there is no such object, this function returns 0. If there are
1121 more than one, the first one found is returned.
1123 QObject* QObject::child(const char *objName, const char *inheritsClass,
1124 bool recursiveSearch) const
1127 return qChildHelper(objName, inheritsClass, recursiveSearch, d->children);
1132 \fn bool QObject::isWidgetType() const
1134 Returns true if the object is a widget; otherwise returns false.
1136 Calling this function is equivalent to calling
1137 inherits("QWidget"), except that it is much faster.
1142 This virtual function receives events to an object and should
1143 return true if the event \a e was recognized and processed.
1145 The event() function can be reimplemented to customize the
1146 behavior of an object.
1148 \sa installEventFilter(), timerEvent(), QApplication::sendEvent(),
1149 QApplication::postEvent(), QWidget::event()
1152 bool QObject::event(QEvent *e)
1154 switch (e->type()) {
1156 timerEvent((QTimerEvent*)e);
1160 case QEvent::ChildInsertedRequest:
1161 d_func()->sendPendingChildInsertedEvents();
1165 case QEvent::ChildAdded:
1166 case QEvent::ChildPolished:
1168 case QEvent::ChildInserted:
1170 case QEvent::ChildRemoved:
1171 childEvent((QChildEvent*)e);
1174 case QEvent::DeferredDelete:
1175 qDeleteInEventHandler(this);
1178 case QEvent::MetaCall:
1180 #ifdef QT_JAMBI_BUILD
1181 d_func()->inEventHandler = false;
1183 QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
1184 QObjectPrivate::Sender currentSender;
1185 currentSender.sender = const_cast<QObject*>(mce->sender());
1186 currentSender.signal = mce->signalId();
1187 currentSender.ref = 1;
1188 QObjectPrivate::Sender * const previousSender =
1189 QObjectPrivate::setCurrentSender(this, ¤tSender);
1190 #if defined(QT_NO_EXCEPTIONS)
1191 mce->placeMetaCall(this);
1194 mce->placeMetaCall(this);
1196 QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender);
1200 QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender);
1204 case QEvent::ThreadChange: {
1206 QThreadData *threadData = d->threadData;
1207 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1208 if (eventDispatcher) {
1209 QList<QPair<int, int> > timers = eventDispatcher->registeredTimers(this);
1210 if (!timers.isEmpty()) {
1211 // set inThreadChangeEvent to true to tell the dispatcher not to release out timer ids
1212 // back to the pool (since the timer ids are moving to a new thread).
1213 d->inThreadChangeEvent = true;
1214 eventDispatcher->unregisterTimers(this);
1215 d->inThreadChangeEvent = false;
1216 QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
1217 Q_ARG(void*, (new QList<QPair<int, int> >(timers))));
1224 if (e->type() >= QEvent::User) {
1234 \fn void QObject::timerEvent(QTimerEvent *event)
1236 This event handler can be reimplemented in a subclass to receive
1237 timer events for the object.
1239 QTimer provides a higher-level interface to the timer
1240 functionality, and also more general information about timers. The
1241 timer event is passed in the \a event parameter.
1243 \sa startTimer(), killTimer(), event()
1246 void QObject::timerEvent(QTimerEvent *)
1252 This event handler can be reimplemented in a subclass to receive
1253 child events. The event is passed in the \a event parameter.
1255 QEvent::ChildAdded and QEvent::ChildRemoved events are sent to
1256 objects when children are added or removed. In both cases you can
1257 only rely on the child being a QObject, or if isWidgetType()
1258 returns true, a QWidget. (This is because, in the
1259 \l{QEvent::ChildAdded}{ChildAdded} case, the child is not yet
1260 fully constructed, and in the \l{QEvent::ChildRemoved}{ChildRemoved}
1261 case it might have been destructed already).
1263 QEvent::ChildPolished events are sent to widgets when children
1264 are polished, or when polished children are added. If you receive
1265 a child polished event, the child's construction is usually
1266 completed. However, this is not guaranteed, and multiple polish
1267 events may be delivered during the execution of a widget's
1270 For every child widget, you receive one
1271 \l{QEvent::ChildAdded}{ChildAdded} event, zero or more
1272 \l{QEvent::ChildPolished}{ChildPolished} events, and one
1273 \l{QEvent::ChildRemoved}{ChildRemoved} event.
1275 The \l{QEvent::ChildPolished}{ChildPolished} event is omitted if
1276 a child is removed immediately after it is added. If a child is
1277 polished several times during construction and destruction, you
1278 may receive several child polished events for the same child,
1279 each time with a different virtual table.
1284 void QObject::childEvent(QChildEvent * /* event */)
1290 This event handler can be reimplemented in a subclass to receive
1291 custom events. Custom events are user-defined events with a type
1292 value at least as large as the QEvent::User item of the
1293 QEvent::Type enum, and is typically a QEvent subclass. The event
1294 is passed in the \a event parameter.
1298 void QObject::customEvent(QEvent * /* event */)
1305 Filters events if this object has been installed as an event
1306 filter for the \a watched object.
1308 In your reimplementation of this function, if you want to filter
1309 the \a event out, i.e. stop it being handled further, return
1310 true; otherwise return false.
1313 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 6
1315 Notice in the example above that unhandled events are passed to
1316 the base class's eventFilter() function, since the base class
1317 might have reimplemented eventFilter() for its own internal
1320 \warning If you delete the receiver object in this function, be
1321 sure to return true. Otherwise, Qt will forward the event to the
1322 deleted object and the program might crash.
1324 \sa installEventFilter()
1327 bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
1333 \fn bool QObject::signalsBlocked() const
1335 Returns true if signals are blocked; otherwise returns false.
1337 Signals are not blocked by default.
1343 If \a block is true, signals emitted by this object are blocked
1344 (i.e., emitting a signal will not invoke anything connected to it).
1345 If \a block is false, no such blocking will occur.
1347 The return value is the previous value of signalsBlocked().
1349 Note that the destroyed() signal will be emitted even if the signals
1350 for this object have been blocked.
1352 \sa signalsBlocked()
1355 bool QObject::blockSignals(bool block)
1358 bool previous = d->blockSig;
1359 d->blockSig = block;
1364 Returns the thread in which the object lives.
1368 QThread *QObject::thread() const
1370 return d_func()->threadData->thread;
1374 Changes the thread affinity for this object and its children. The
1375 object cannot be moved if it has a parent. Event processing will
1376 continue in the \a targetThread.
1378 To move an object to the main thread, use QApplication::instance()
1379 to retrieve a pointer to the current application, and then use
1380 QApplication::thread() to retrieve the thread in which the
1381 application lives. For example:
1383 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 7
1385 If \a targetThread is zero, all event processing for this object
1386 and its children stops.
1388 Note that all active timers for the object will be reset. The
1389 timers are first stopped in the current thread and restarted (with
1390 the same interval) in the \a targetThread. As a result, constantly
1391 moving an object between threads can postpone timer events
1394 A QEvent::ThreadChange event is sent to this object just before
1395 the thread affinity is changed. You can handle this event to
1396 perform any special processing. Note that any new events that are
1397 posted to this object will be handled in the \a targetThread.
1399 \warning This function is \e not thread-safe; the current thread
1400 must be same as the current thread affinity. In other words, this
1401 function can only "push" an object from the current thread to
1402 another thread, it cannot "pull" an object from any arbitrary
1403 thread to the current thread.
1407 void QObject::moveToThread(QThread *targetThread)
1411 if (d->threadData->thread == targetThread) {
1412 // object is already in this thread
1416 if (d->parent != 0) {
1417 qWarning("QObject::moveToThread: Cannot move objects with a parent");
1421 qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
1425 QThreadData *currentData = QThreadData::current();
1426 QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0);
1427 if (d->threadData->thread == 0 && currentData == targetData) {
1428 // one exception to the rule: we allow moving objects with no thread affinity to the current thread
1429 currentData = d->threadData;
1430 } else if (d->threadData != currentData) {
1431 qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
1432 "Cannot move to target thread (%p)\n",
1433 currentData->thread, d->threadData->thread, targetData->thread);
1436 qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. "
1437 "Check that all plugins are compiled against the right Qt binaries. Export "
1438 "DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.");
1445 d->moveToThread_helper();
1447 QOrderedMutexLocker locker(¤tData->postEventList.mutex,
1448 &targetData->postEventList.mutex);
1450 // keep currentData alive (since we've got it locked)
1454 d_func()->setThreadData_helper(currentData, targetData);
1458 // now currentData can commit suicide if it wants to
1459 currentData->deref();
1462 void QObjectPrivate::moveToThread_helper()
1465 QEvent e(QEvent::ThreadChange);
1466 QCoreApplication::sendEvent(q, &e);
1467 for (int i = 0; i < children.size(); ++i) {
1468 QObject *child = children.at(i);
1469 child->d_func()->moveToThread_helper();
1473 void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData)
1477 // move posted events
1478 int eventsMoved = 0;
1479 for (int i = 0; i < currentData->postEventList.size(); ++i) {
1480 const QPostEvent &pe = currentData->postEventList.at(i);
1483 if (pe.receiver == q) {
1484 // move this post event to the targetList
1485 targetData->postEventList.append(pe);
1486 const_cast<QPostEvent &>(pe).event = 0;
1490 if (eventsMoved > 0 && targetData->eventDispatcher) {
1491 targetData->canWait = false;
1492 targetData->eventDispatcher->wakeUp();
1495 // the current emitting thread shouldn't restore currentSender after calling moveToThread()
1497 currentSender->ref = 0;
1500 #ifdef QT_JAMBI_BUILD
1501 // the current event thread also shouldn't restore the delete watch
1502 inEventHandler = false;
1509 // set new thread data
1511 threadData->deref();
1512 threadData = targetData;
1514 for (int i = 0; i < children.size(); ++i) {
1515 QObject *child = children.at(i);
1516 child->d_func()->setThreadData_helper(currentData, targetData);
1520 void QObjectPrivate::_q_reregisterTimers(void *pointer)
1523 QList<QPair<int, int> > *timerList = reinterpret_cast<QList<QPair<int, int> > *>(pointer);
1524 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher;
1525 for (int i = 0; i < timerList->size(); ++i) {
1526 const QPair<int, int> &pair = timerList->at(i);
1527 eventDispatcher->registerTimer(pair.first, pair.second, q);
1534 // The timer flag hasTimer is set when startTimer is called.
1535 // It is not reset when killing the timer because more than
1536 // one timer might be active.
1540 Starts a timer and returns a timer identifier, or returns zero if
1541 it could not start a timer.
1543 A timer event will occur every \a interval milliseconds until
1544 killTimer() is called. If \a interval is 0, then the timer event
1545 occurs once every time there are no more window system events to
1548 The virtual timerEvent() function is called with the QTimerEvent
1549 event parameter class when a timer event occurs. Reimplement this
1550 function to get timer events.
1552 If multiple timers are running, the QTimerEvent::timerId() can be
1553 used to find out which timer was activated.
1557 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
1559 Note that QTimer's accuracy depends on the underlying operating
1560 system and hardware. Most platforms support an accuracy of 20
1561 milliseconds; some provide more. If Qt is unable to deliver the
1562 requested number of timer events, it will silently discard some.
1564 The QTimer class provides a high-level programming interface with
1565 single-shot timers and timer signals instead of events. There is
1566 also a QBasicTimer class that is more lightweight than QTimer and
1567 less clumsy than using timer IDs directly.
1569 \sa timerEvent(), killTimer(), QTimer::singleShot()
1572 int QObject::startTimer(int interval)
1577 qWarning("QObject::startTimer: QTimer cannot have a negative interval");
1581 d->pendTimer = true; // set timer flag
1583 if (!d->threadData->eventDispatcher) {
1584 qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread");
1587 return d->threadData->eventDispatcher->registerTimer(interval, this);
1591 Kills the timer with timer identifier, \a id.
1593 The timer identifier is returned by startTimer() when a timer
1596 \sa timerEvent(), startTimer()
1599 void QObject::killTimer(int id)
1602 if (d->threadData->eventDispatcher)
1603 d->threadData->eventDispatcher->unregisterTimer(id);
1608 \fn QObject *QObject::parent() const
1610 Returns a pointer to the parent object.
1616 \fn const QObjectList &QObject::children() const
1618 Returns a list of child objects.
1619 The QObjectList class is defined in the \c{<QObject>} header
1620 file as the following:
1622 \quotefromfile src/corelib/kernel/qobject.h
1623 \skipto /typedef .*QObjectList/
1624 \printuntil QObjectList
1626 The first child added is the \l{QList::first()}{first} object in
1627 the list and the last child added is the \l{QList::last()}{last}
1628 object in the list, i.e. new children are appended at the end.
1630 Note that the list order changes when QWidget children are
1631 \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A
1632 widget that is raised becomes the last object in the list, and a
1633 widget that is lowered becomes the first object in the list.
1635 \sa findChild(), findChildren(), parent(), setParent()
1639 static void objSearch(QObjectList &result,
1640 const QObjectList &list,
1641 const char *inheritsClass,
1643 const char *objName,
1647 for (int i = 0; i < list.size(); ++i) {
1648 QObject *obj = list.at(i);
1653 ok = obj->isWidgetType();
1654 else if (inheritsClass && !obj->inherits(inheritsClass))
1658 ok = (obj->objectName() == QLatin1String(objName));
1659 #ifndef QT_NO_REGEXP
1661 ok = (rx->indexIn(obj->objectName()) != -1);
1667 QObjectList clist = obj->children();
1668 if (!clist.isEmpty())
1669 objSearch(result, clist, inheritsClass,
1670 onlyWidgets, objName, rx, recurse);
1678 Searches the children and optionally grandchildren of this object,
1679 and returns a list of those objects that are named or that match
1680 \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
1681 (the default), all classes match. If \a objName is 0 (the
1682 default), all object names match.
1684 If \a regexpMatch is true (the default), \a objName is a regular
1685 expression that the objects's names must match. The syntax is that
1686 of a QRegExp. If \a regexpMatch is false, \a objName is a string
1687 and object names must match it exactly.
1689 Note that \a inheritsClass uses single inheritance from QObject,
1690 the way inherits() does. According to inherits(), QWidget
1691 inherits QObject but not QPaintDevice. This does not quite match
1692 reality, but is the best that can be done on the wide variety of
1693 compilers Qt supports.
1695 Finally, if \a recursiveSearch is true (the default), queryList()
1696 searches \e{n}th-generation as well as first-generation children.
1698 If all this seems a bit complex for your needs, the simpler
1699 child() function may be what you want.
1701 This somewhat contrived example disables all the buttons in this
1704 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 9
1706 \warning Delete the list as soon you have finished using it. The
1707 list contains pointers that may become invalid at almost any time
1708 without notice (as soon as the user closes a window you may have
1709 dangling pointers, for example).
1711 \sa child() children(), parent(), inherits(), objectName(), QRegExp
1714 QObjectList QObject::queryList(const char *inheritsClass,
1715 const char *objName,
1717 bool recursiveSearch) const
1721 bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
1722 #ifndef QT_NO_REGEXP
1723 if (regexpMatch && objName) { // regexp matching
1724 QRegExp rx(QString::fromLatin1(objName));
1725 objSearch(list, d->children, inheritsClass, onlyWidgets, 0, &rx, recursiveSearch);
1729 objSearch(list, d->children, inheritsClass, onlyWidgets, objName, 0, recursiveSearch);
1736 \fn T *QObject::findChild(const QString &name) const
1738 Returns the child of this object that can be cast into type T and
1739 that is called \a name, or 0 if there is no such object.
1740 Omitting the \a name argument causes all object names to be matched.
1741 The search is performed recursively.
1743 If there is more than one child matching the search, the most
1744 direct ancestor is returned. If there are several direct
1745 ancestors, it is undefined which one will be returned. In that
1746 case, findChildren() should be used.
1748 This example returns a child \l{QPushButton} of \c{parentWidget}
1749 named \c{"button1"}:
1751 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10
1753 This example returns a \l{QListWidget} child of \c{parentWidget}:
1755 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
1761 \fn QList<T> QObject::findChildren(const QString &name) const
1763 Returns all children of this object with the given \a name that can be
1764 cast to type T, or an empty list if there are no such objects.
1765 Omitting the \a name argument causes all object names to be matched.
1766 The search is performed recursively.
1768 The following example shows how to find a list of child \l{QWidget}s of
1769 the specified \c{parentWidget} named \c{widgetname}:
1771 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 12
1773 This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
1775 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
1781 \fn QList<T> QObject::findChildren(const QRegExp ®Exp) const
1782 \overload findChildren()
1784 Returns the children of this object that can be cast to type T
1785 and that have names matching the regular expression \a regExp,
1786 or an empty list if there are no such objects.
1787 The search is performed recursively.
1791 \fn T qFindChild(const QObject *obj, const QString &name)
1795 This function is equivalent to
1796 \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
1798 \note This function was provided as a workaround for MSVC 6
1799 which did not support member template functions. It is advised
1800 to use the other form in new code.
1802 \sa QObject::findChild()
1806 \fn QList<T> qFindChildren(const QObject *obj, const QString &name)
1810 This function is equivalent to
1811 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
1813 \note This function was provided as a workaround for MSVC 6
1814 which did not support member template functions. It is advised
1815 to use the other form in new code.
1817 \sa QObject::findChildren()
1821 \fn QList<T> qFindChildren(const QObject *obj, const QRegExp ®Exp)
1823 \overload qFindChildren()
1825 This function is equivalent to
1826 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp).
1828 \note This function was provided as a workaround for MSVC 6
1829 which did not support member template functions. It is advised
1830 to use the other form in new code.
1832 \sa QObject::findChildren()
1837 \fn T qFindChild(const QObject *obj, const QString &name = QString(), T dummy = 0)
1839 \overload qFindChildren()
1841 This function is equivalent to
1842 \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
1844 \note This function was provided as a workaround for MSVC 6
1845 which did not support member template functions. It is advised
1846 to use the other form in new code.
1848 \sa QObject::findChild()
1853 \fn QList<T> qFindChildren(const QObject *obj, const QString &name = QString(), T dummy = 0)
1855 \overload qFindChildren()
1857 This function is equivalent to
1858 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
1860 \note This function was provided as a workaround for MSVC 6
1861 which did not support member template functions. It is advised
1862 to use the other form in new code.
1864 \sa QObject::findChildren()
1870 void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
1871 const QMetaObject &mo, QList<void*> *list)
1873 if (!parent || !list)
1875 const QObjectList &children = parent->children();
1877 for (int i = 0; i < children.size(); ++i) {
1878 obj = children.at(i);
1881 if (re->indexIn(obj->objectName()) != -1)
1884 if (name.isNull() || obj->objectName() == name)
1888 qt_qFindChildren_helper(obj, name, re, mo, list);
1894 QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo)
1898 const QObjectList &children = parent->children();
1901 for (i = 0; i < children.size(); ++i) {
1902 obj = children.at(i);
1903 if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
1906 for (i = 0; i < children.size(); ++i) {
1907 obj = qt_qFindChild_helper(children.at(i), name, mo);
1915 Makes the object a child of \a parent.
1917 \sa QWidget::setParent()
1920 void QObject::setParent(QObject *parent)
1923 Q_ASSERT(!d->isWidget);
1924 d->setParent_helper(parent);
1927 void QObjectPrivate::deleteChildren()
1929 const bool reallyWasDeleted = wasDeleted;
1931 // delete children objects
1932 // don't use qDeleteAll as the destructor of the child might
1934 for (int i = 0; i < children.count(); ++i) {
1935 currentChildBeingDeleted = children.at(i);
1937 delete currentChildBeingDeleted;
1940 currentChildBeingDeleted = 0;
1941 wasDeleted = reallyWasDeleted;
1944 void QObjectPrivate::setParent_helper(QObject *o)
1950 QObjectPrivate *parentD = parent->d_func();
1951 if (parentD->wasDeleted && wasDeleted
1952 && parentD->currentChildBeingDeleted == q) {
1953 // don't do anything since QObjectPrivate::deleteChildren() already
1954 // cleared our entry in parentD->children.
1956 const int index = parentD->children.indexOf(q);
1957 if (parentD->wasDeleted) {
1958 parentD->children[index] = 0;
1960 parentD->children.removeAt(index);
1961 if (sendChildEvents && parentD->receiveChildEvents) {
1962 QChildEvent e(QEvent::ChildRemoved, q);
1963 QCoreApplication::sendEvent(parent, &e);
1970 // object hierarchies are constrained to a single thread
1971 if (threadData != parent->d_func()->threadData) {
1972 qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");
1976 parent->d_func()->children.append(q);
1977 if(sendChildEvents && parent->d_func()->receiveChildEvents) {
1979 QChildEvent e(QEvent::ChildAdded, q);
1980 QCoreApplication::sendEvent(parent, &e);
1982 if (QCoreApplicationPrivate::useQt3Support) {
1983 if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
1984 QCoreApplication::postEvent(parent,
1985 new QEvent(QEvent::ChildInsertedRequest),
1986 Qt::HighEventPriority);
1988 parent->d_func()->pendingChildInsertedEvents.append(q);
1994 if (!wasDeleted && declarativeData)
1995 QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
1999 \fn void QObject::installEventFilter(QObject *filterObj)
2001 Installs an event filter \a filterObj on this object. For example:
2002 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 14
2004 An event filter is an object that receives all events that are
2005 sent to this object. The filter can either stop the event or
2006 forward it to this object. The event filter \a filterObj receives
2007 events via its eventFilter() function. The eventFilter() function
2008 must return true if the event should be filtered, (i.e. stopped);
2009 otherwise it must return false.
2011 If multiple event filters are installed on a single object, the
2012 filter that was installed last is activated first.
2014 Here's a \c KeyPressEater class that eats the key presses of its
2017 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 15
2019 And here's how to install it on two widgets:
2021 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 16
2023 The QShortcut class, for example, uses this technique to intercept
2024 shortcut key presses.
2026 \warning If you delete the receiver object in your eventFilter()
2027 function, be sure to return true. If you return false, Qt sends
2028 the event to the deleted object and the program will crash.
2030 Note that the filtering object must be in the same thread as this
2031 object. If \a filterObj is in a different thread, this function does
2032 nothing. If either \a filterObj or this object are moved to a different
2033 thread after calling this function, the event filter will not be
2034 called until both objects have the same thread affinity again (it
2037 \sa removeEventFilter(), eventFilter(), event()
2040 void QObject::installEventFilter(QObject *obj)
2045 if (d->threadData != obj->d_func()->threadData) {
2046 qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
2050 // clean up unused items in the list
2051 d->eventFilters.removeAll((QObject*)0);
2052 d->eventFilters.removeAll(obj);
2053 d->eventFilters.prepend(obj);
2057 Removes an event filter object \a obj from this object. The
2058 request is ignored if such an event filter has not been installed.
2060 All event filters for this object are automatically removed when
2061 this object is destroyed.
2063 It is always safe to remove an event filter, even during event
2064 filter activation (i.e. from the eventFilter() function).
2066 \sa installEventFilter(), eventFilter(), event()
2069 void QObject::removeEventFilter(QObject *obj)
2072 for (int i = 0; i < d->eventFilters.count(); ++i) {
2073 if (d->eventFilters.at(i) == obj)
2074 d->eventFilters[i] = 0;
2080 \fn QObject::destroyed(QObject *obj)
2082 This signal is emitted immediately before the object \a obj is
2083 destroyed, and can not be blocked.
2085 All the objects's children are destroyed immediately after this
2088 \sa deleteLater(), QPointer
2092 Schedules this object for deletion.
2094 The object will be deleted when control returns to the event
2095 loop. If the event loop is not running when this function is
2096 called (e.g. deleteLater() is called on an object before
2097 QCoreApplication::exec()), the object will be deleted once the
2098 event loop is started.
2100 Note that entering and leaving a new event loop (e.g., by opening a modal
2101 dialog) will \e not perform the deferred deletion; for the object to be
2102 deleted, the control must return to the event loop from which
2103 deleteLater() was called.
2105 \bold{Note:} It is safe to call this function more than once; when the
2106 first deferred deletion event is delivered, any pending events for the
2107 object are removed from the event queue.
2109 \sa destroyed(), QPointer
2111 void QObject::deleteLater()
2113 QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
2117 \fn QString QObject::tr(const char *sourceText, const char *disambiguation, int n)
2120 Returns a translated version of \a sourceText, optionally based on a
2121 \a disambiguation string and value of \a n for strings containing plurals;
2122 otherwise returns \a sourceText itself if no appropriate translated string
2126 \snippet mainwindows/sdi/mainwindow.cpp implicit tr context
2129 If the same \a sourceText is used in different roles within the
2130 same context, an additional identifying string may be passed in
2131 \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
2132 the preferred way to pass comments to translators.
2136 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
2139 See \l{Writing Source Code for Translation} for a detailed description of
2140 Qt's translation mechanisms in general, and the
2141 \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
2142 section for information on disambiguation.
2144 \warning This method is reentrant only if all translators are
2145 installed \e before calling this method. Installing or removing
2146 translators while performing translations is not supported. Doing
2147 so will probably result in crashes or other undesirable behavior.
2149 \sa trUtf8(), QApplication::translate(), QTextCodec::setCodecForTr(), {Internationalization with Qt}
2153 \fn QString QObject::trUtf8(const char *sourceText, const char *disambiguation, int n)
2156 Returns a translated version of \a sourceText, or
2157 QString::fromUtf8(\a sourceText) if there is no appropriate
2158 version. It is otherwise identical to tr(\a sourceText, \a
2159 disambiguation, \a n).
2161 Note that using the Utf8 variants of the translation functions
2162 is not required if \c CODECFORTR is already set to UTF-8 in the
2163 qmake project file and QTextCodec::setCodecForTr("UTF-8") is
2166 \warning This method is reentrant only if all translators are
2167 installed \e before calling this method. Installing or removing
2168 translators while performing translations is not supported. Doing
2169 so will probably result in crashes or other undesirable behavior.
2171 \warning For portability reasons, we recommend that you use
2172 escape sequences for specifying non-ASCII characters in string
2173 literals to trUtf8(). For example:
2175 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 20
2177 \sa tr(), QApplication::translate(), {Internationalization with Qt}
2183 /*****************************************************************************
2185 *****************************************************************************/
2188 const int flagged_locations_count = 2;
2189 static const char* flagged_locations[flagged_locations_count] = {0};
2191 const char *qFlagLocation(const char *method)
2194 flagged_locations[idx] = method;
2195 idx = (idx+1) % flagged_locations_count;
2199 static int extract_code(const char *member)
2201 // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE
2202 return (((int)(*member) - '0') & 0x3);
2205 static const char * extract_location(const char *member)
2207 for (int i = 0; i < flagged_locations_count; ++i) {
2208 if (member == flagged_locations[i]) {
2209 // signature includes location information after the first null-terminator
2210 const char *location = member + qstrlen(member) + 1;
2211 if (*location != '\0')
2219 static bool check_signal_macro(const QObject *sender, const char *signal,
2220 const char *func, const char *op)
2222 int sigcode = extract_code(signal);
2223 if (sigcode != QSIGNAL_CODE) {
2224 if (sigcode == QSLOT_CODE)
2225 qWarning("Object::%s: Attempt to %s non-signal %s::%s",
2226 func, op, sender->metaObject()->className(), signal+1);
2228 qWarning("Object::%s: Use the SIGNAL macro to %s %s::%s",
2229 func, op, sender->metaObject()->className(), signal);
2235 static bool check_method_code(int code, const QObject *object,
2236 const char *method, const char *func)
2238 if (code != QSLOT_CODE && code != QSIGNAL_CODE) {
2239 qWarning("Object::%s: Use the SLOT or SIGNAL macro to "
2240 "%s %s::%s", func, func, object->metaObject()->className(), method);
2246 static void err_method_notfound(const QObject *object,
2247 const char *method, const char *func)
2249 const char *type = "method";
2250 switch (extract_code(method)) {
2251 case QSLOT_CODE: type = "slot"; break;
2252 case QSIGNAL_CODE: type = "signal"; break;
2254 const char *loc = extract_location(method);
2255 if (strchr(method,')') == 0) // common typing mistake
2256 qWarning("Object::%s: Parentheses expected, %s %s::%s%s%s",
2257 func, type, object->metaObject()->className(), method+1,
2258 loc ? " in ": "", loc ? loc : "");
2260 qWarning("Object::%s: No such %s %s::%s%s%s",
2261 func, type, object->metaObject()->className(), method+1,
2262 loc ? " in ": "", loc ? loc : "");
2267 static void err_info_about_objects(const char * func,
2268 const QObject * sender,
2269 const QObject * receiver)
2271 QString a = sender ? sender->objectName() : QString();
2272 QString b = receiver ? receiver->objectName() : QString();
2274 qWarning("Object::%s: (sender name: '%s')", func, a.toLocal8Bit().data());
2276 qWarning("Object::%s: (receiver name: '%s')", func, b.toLocal8Bit().data());
2280 Returns a pointer to the object that sent the signal, if called in
2281 a slot activated by a signal; otherwise it returns 0. The pointer
2282 is valid only during the execution of the slot that calls this
2283 function from this object's thread context.
2285 The pointer returned by this function becomes invalid if the
2286 sender is destroyed, or if the slot is disconnected from the
2289 \warning This function violates the object-oriented principle of
2290 modularity. However, getting access to the sender might be useful
2291 when many signals are connected to a single slot.
2293 \warning As mentioned above, the return value of this function is
2294 not valid when the slot is called via a Qt::DirectConnection from
2295 a thread different from this object's thread. Do not use this
2296 function in this type of scenario.
2298 \sa senderSignalIndex(), QSignalMapper
2301 QObject *QObject::sender() const
2305 QMutexLocker locker(signalSlotLock(this));
2306 if (!d->currentSender)
2309 for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
2310 if (c->sender == d->currentSender->sender)
2311 return d->currentSender->sender;
2320 Returns the meta-method index of the signal that called the currently
2321 executing slot, which is a member of the class returned by sender().
2322 If called outside of a slot activated by a signal, -1 is returned.
2324 For signals with default parameters, this function will always return
2325 the index with all parameters, regardless of which was used with
2326 connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
2327 will have two different indexes (with and without the parameter), but
2328 this function will always return the index with a parameter. This does
2329 not apply when overloading signals with different parameters.
2331 \warning This function violates the object-oriented principle of
2332 modularity. However, getting access to the signal index might be useful
2333 when many signals are connected to a single slot.
2335 \warning The return value of this function is not valid when the slot
2336 is called via a Qt::DirectConnection from a thread different from this
2337 object's thread. Do not use this function in this type of scenario.
2339 \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method()
2342 int QObject::senderSignalIndex() const
2346 QMutexLocker locker(signalSlotLock(this));
2347 if (!d->currentSender)
2350 for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
2351 if (c->sender == d->currentSender->sender)
2352 return d->currentSender->signal;
2359 Returns the number of receivers connected to the \a signal.
2361 Since both slots and signals can be used as receivers for signals,
2362 and the same connections can be made many times, the number of
2363 receivers is the same as the number of connections made from this
2366 When calling this function, you can use the \c SIGNAL() macro to
2367 pass a specific signal:
2369 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 21
2371 As the code snippet above illustrates, you can use this function
2372 to avoid emitting a signal that nobody listens to.
2374 \warning This function violates the object-oriented principle of
2375 modularity. However, it might be useful when you need to perform
2376 expensive initialization only if something is connected to a
2380 int QObject::receivers(const char *signal) const
2385 QByteArray signal_name = QMetaObject::normalizedSignature(signal);
2386 signal = signal_name;
2388 if (!check_signal_macro(this, signal, "receivers", "bind"))
2391 signal++; // skip code
2392 int signal_index = d->signalIndex(signal);
2393 if (signal_index < 0) {
2395 err_method_notfound(this, signal-1, "receivers");
2401 QMutexLocker locker(signalSlotLock(this));
2402 if (d->connectionLists) {
2403 if (signal_index < d->connectionLists->count()) {
2404 const QObjectPrivate::Connection *c =
2405 d->connectionLists->at(signal_index).first;
2407 receivers += c->receiver ? 1 : 0;
2408 c = c->nextConnectionList;
2419 This helper function calculates signal and method index for the given
2420 member in the specified class.
2423 \o If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2425 \o If specified member is not a member of obj instance class (or one of
2426 its parent classes) then both signalIndex and methodIndex are set to -1.
2429 This function is used by QObject::connect and QObject::disconnect which
2430 are working with QMetaMethod.
2432 \a signalIndex is set to the signal index of member. If the member
2433 specified is not signal this variable is set to -1.
2435 \a methodIndex is set to the method index of the member. If the
2436 member is not a method of the object specified by the \a obj argument this
2437 variable is set to -1.
2439 void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2440 const QMetaMethod &member,
2441 int *signalIndex, int *methodIndex)
2445 if (!obj || !member.mobj)
2447 const QMetaObject *m = obj->metaObject();
2448 // Check that member is member of obj class
2449 while (m != 0 && m != member.mobj)
2453 *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2457 computeOffsets(m, &signalOffset, &methodOffset);
2459 *methodIndex += methodOffset;
2460 if (member.methodType() == QMetaMethod::Signal) {
2461 *signalIndex = originalClone(m, *signalIndex);
2462 *signalIndex += signalOffset;
2468 static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2469 const QMetaObject *receiver, const QMetaMethod &method)
2471 if (signal.attributes() & QMetaMethod::Compatibility) {
2472 if (!(method.attributes() & QMetaMethod::Compatibility))
2473 qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2474 sender->className(), signal.signature());
2475 } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2476 method.methodType() == QMetaMethod::Signal) {
2477 qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2478 sender->className(), signal.signature(),
2479 receiver->className(), method.signature());
2486 Creates a connection of the given \a type from the \a signal in
2487 the \a sender object to the \a method in the \a receiver object.
2488 Returns true if the connection succeeds; otherwise returns false.
2490 You must use the \c SIGNAL() and \c SLOT() macros when specifying
2491 the \a signal and the \a method, for example:
2493 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 22
2495 This example ensures that the label always displays the current
2496 scroll bar value. Note that the signal and slots parameters must not
2497 contain any variable names, only the type. E.g. the following would
2498 not work and return false:
2500 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 23
2502 A signal can also be connected to another signal:
2504 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 24
2506 In this example, the \c MyWidget constructor relays a signal from
2507 a private member variable, and makes it available under a name
2508 that relates to \c MyWidget.
2510 A signal can be connected to many slots and signals. Many signals
2511 can be connected to one slot.
2513 If a signal is connected to several slots, the slots are activated
2514 in the same order as the order the connection was made, when the
2517 The function returns true if it successfully connects the signal
2518 to the slot. It will return false if it cannot create the
2519 connection, for example, if QObject is unable to verify the
2520 existence of either \a signal or \a method, or if their signatures
2523 By default, a signal is emitted for every connection you make;
2524 two signals are emitted for duplicate connections. You can break
2525 all of these connections with a single disconnect() call.
2526 If you pass the Qt::UniqueConnection \a type, the connection will only
2527 be made if it is not a duplicate. If there is already a duplicate
2528 (exact same signal to the exact same slot on the same objects),
2529 the connection will fail and connect will return false.
2531 The optional \a type parameter describes the type of connection
2532 to establish. In particular, it determines whether a particular
2533 signal is delivered to a slot immediately or queued for delivery
2534 at a later time. If the signal is queued, the parameters must be
2535 of types that are known to Qt's meta-object system, because Qt
2536 needs to copy the arguments to store them in an event behind the
2537 scenes. If you try to use a queued connection and get the error
2540 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 25
2542 call qRegisterMetaType() to register the data type before you
2543 establish the connection.
2545 \sa disconnect(), sender(), qRegisterMetaType()
2548 bool QObject::connect(const QObject *sender, const char *signal,
2549 const QObject *receiver, const char *method,
2550 Qt::ConnectionType type)
2553 const void *cbdata[] = { sender, signal, receiver, method, &type };
2554 if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
2559 bool warnCompat = true;
2561 if (type == Qt::AutoCompatConnection) {
2562 type = Qt::AutoConnection;
2568 if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2569 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2570 sender ? sender->metaObject()->className() : "(null)",
2571 (signal && *signal) ? signal+1 : "(null)",
2572 receiver ? receiver->metaObject()->className() : "(null)",
2573 (method && *method) ? method+1 : "(null)");
2576 QByteArray tmp_signal_name;
2578 if (!check_signal_macro(sender, signal, "connect", "bind"))
2580 const QMetaObject *smeta = sender->metaObject();
2581 const char *signal_arg = signal;
2582 ++signal; //skip code
2583 int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2584 if (signal_index < 0) {
2585 // check for normalized signatures
2586 tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2587 signal = tmp_signal_name.constData() + 1;
2589 smeta = sender->metaObject();
2590 signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2592 if (signal_index < 0) {
2593 // re-use tmp_signal_name and signal from above
2595 smeta = sender->metaObject();
2596 signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
2598 if (signal_index < 0) {
2599 err_method_notfound(sender, signal_arg, "connect");
2600 err_info_about_objects("connect", sender, receiver);
2603 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2604 int signalOffset, methodOffset;
2605 computeOffsets(smeta, &signalOffset, &methodOffset);
2606 int signal_absolute_index = signal_index + methodOffset;
2607 signal_index += signalOffset;
2609 QByteArray tmp_method_name;
2610 int membcode = extract_code(method);
2612 if (!check_method_code(membcode, receiver, method, "connect"))
2614 const char *method_arg = method;
2615 ++method; // skip code
2617 const QMetaObject *rmeta = receiver->metaObject();
2618 int method_index_relative = -1;
2621 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
2624 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
2628 if (method_index_relative < 0) {
2629 // check for normalized methods
2630 tmp_method_name = QMetaObject::normalizedSignature(method);
2631 method = tmp_method_name.constData();
2633 // rmeta may have been modified above
2634 rmeta = receiver->metaObject();
2637 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, false);
2638 if (method_index_relative < 0)
2639 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(&rmeta, method, true);
2642 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
2643 if (method_index_relative < 0)
2644 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, true);
2649 if (method_index_relative < 0) {
2650 err_method_notfound(receiver, method_arg, "connect");
2651 err_info_about_objects("connect", sender, receiver);
2655 if (!QMetaObject::checkConnectArgs(signal, method)) {
2656 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2657 "\n %s::%s --> %s::%s",
2658 sender->metaObject()->className(), signal,
2659 receiver->metaObject()->className(), method);
2664 if ((type == Qt::QueuedConnection)
2665 && !(types = queuedConnectionTypes(smeta->method(signal_absolute_index).parameterTypes())))
2670 QMetaMethod smethod = smeta->method(signal_absolute_index);
2671 QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2672 check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2675 if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index_relative, rmeta ,type, types))
2677 const_cast<QObject*>(sender)->connectNotify(signal - 1);
2684 Creates a connection of the given \a type from the \a signal in
2685 the \a sender object to the \a method in the \a receiver object.
2686 Returns true if the connection succeeds; otherwise returns false.
2688 This function works in the same way as
2689 connect(const QObject *sender, const char *signal,
2690 const QObject *receiver, const char *method,
2691 Qt::ConnectionType type)
2692 but it uses QMetaMethod to specify signal and method.
2694 \sa connect(const QObject *sender, const char *signal,
2695 const QObject *receiver, const char *method,
2696 Qt::ConnectionType type)
2698 bool QObject::connect(const QObject *sender, const QMetaMethod &signal,
2699 const QObject *receiver, const QMetaMethod &method,
2700 Qt::ConnectionType type)
2703 bool warnCompat = true;
2705 if (type == Qt::AutoCompatConnection) {
2706 type = Qt::AutoConnection;
2714 || signal.methodType() != QMetaMethod::Signal
2715 || method.methodType() == QMetaMethod::Constructor) {
2716 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2717 sender ? sender->metaObject()->className() : "(null)",
2719 receiver ? receiver->metaObject()->className() : "(null)",
2720 method.signature() );
2724 // Reconstructing SIGNAL() macro result for signal.signature() string
2725 QByteArray signalSignature;
2726 signalSignature.reserve(qstrlen(signal.signature())+1);
2727 signalSignature.append((char)(QSIGNAL_CODE + '0'));
2728 signalSignature.append(signal.signature());
2731 QByteArray methodSignature;
2732 methodSignature.reserve(qstrlen(method.signature())+1);
2733 methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
2734 : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0 + '0'));
2735 methodSignature.append(method.signature());
2736 const void *cbdata[] = { sender, signalSignature.constData(), receiver, methodSignature.constData(), &type };
2737 if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
2746 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2747 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2750 const QMetaObject *smeta = sender->metaObject();
2751 const QMetaObject *rmeta = receiver->metaObject();
2752 if (signal_index == -1) {
2753 qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2754 signal.signature(), smeta->className());
2757 if (method_index == -1) {
2758 qWarning("QObject::connect: Can't find method %s on instance of class %s",
2759 method.signature(), rmeta->className());
2763 if (!QMetaObject::checkConnectArgs(signal.signature(), method.signature())) {
2764 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2765 "\n %s::%s --> %s::%s",
2766 smeta->className(), signal.signature(),
2767 rmeta->className(), method.signature());
2772 if ((type == Qt::QueuedConnection)
2773 && !(types = queuedConnectionTypes(signal.parameterTypes())))
2778 check_and_warn_compat(smeta, signal, rmeta, method);
2780 if (!QMetaObjectPrivate::connect(sender, signal_index, receiver, method_index, 0, type, types))
2783 const_cast<QObject*>(sender)->connectNotify(signalSignature.constData());
2788 \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2792 Connects \a signal from the \a sender object to this object's \a
2795 Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2797 Every connection you make emits a signal, so duplicate connections emit
2798 two signals. You can break a connection using disconnect().
2806 Disconnects \a signal in object \a sender from \a method in object
2807 \a receiver. Returns true if the connection is successfully broken;
2808 otherwise returns false.
2810 A signal-slot connection is removed when either of the objects
2811 involved are destroyed.
2813 disconnect() is typically used in three ways, as the following
2814 examples demonstrate.
2816 \i Disconnect everything connected to an object's signals:
2818 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
2820 equivalent to the non-static overloaded function
2822 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 27
2824 \i Disconnect everything connected to a specific signal:
2826 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 28
2828 equivalent to the non-static overloaded function
2830 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 29
2832 \i Disconnect a specific receiver:
2834 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
2836 equivalent to the non-static overloaded function
2838 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 31
2842 0 may be used as a wildcard, meaning "any signal", "any receiving
2843 object", or "any slot in the receiving object", respectively.
2845 The \a sender may never be 0. (You cannot disconnect signals from
2846 more than one object in a single call.)
2848 If \a signal is 0, it disconnects \a receiver and \a method from
2849 any signal. If not, only the specified signal is disconnected.
2851 If \a receiver is 0, it disconnects anything connected to \a
2852 signal. If not, slots in objects other than \a receiver are not
2855 If \a method is 0, it disconnects anything that is connected to \a
2856 receiver. If not, only slots named \a method will be disconnected,
2857 and all other slots are left alone. The \a method must be 0 if \a
2858 receiver is left out, so you cannot disconnect a
2859 specifically-named slot on all objects.
2863 bool QObject::disconnect(const QObject *sender, const char *signal,
2864 const QObject *receiver, const char *method)
2866 if (sender == 0 || (receiver == 0 && method != 0)) {
2867 qWarning("Object::disconnect: Unexpected null parameter");
2872 const void *cbdata[] = { sender, signal, receiver, method };
2873 if (QInternal::activateCallbacks(QInternal::DisconnectCallback, (void **) cbdata))
2877 const char *signal_arg = signal;
2878 QByteArray signal_name;
2879 bool signal_found = false;
2882 signal_name = QMetaObject::normalizedSignature(signal);
2883 signal = signal_name.constData();
2884 } QT_CATCH (const std::bad_alloc &) {
2885 // if the signal is already normalized, we can continue.
2886 if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2890 if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
2892 signal++; // skip code
2895 QByteArray method_name;
2896 const char *method_arg = method;
2898 bool method_found = false;
2901 method_name = QMetaObject::normalizedSignature(method);
2902 method = method_name.constData();
2903 } QT_CATCH(const std::bad_alloc &) {
2904 // if the method is already normalized, we can continue.
2905 if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
2909 membcode = extract_code(method);
2910 if (!check_method_code(membcode, receiver, method, "disconnect"))
2912 method++; // skip code
2915 /* We now iterate through all the sender's and receiver's meta
2916 * objects in order to also disconnect possibly shadowed signals
2917 * and slots with the same signature.
2920 const QMetaObject *smeta = sender->metaObject();
2922 int signal_index = -1;
2924 signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
2925 if (signal_index < 0)
2926 signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
2927 if (signal_index < 0)
2929 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2930 int signalOffset, methodOffset;
2931 computeOffsets(smeta, &signalOffset, &methodOffset);
2932 signal_index += signalOffset;
2933 signal_found = true;
2937 res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, -1);
2939 const QMetaObject *rmeta = receiver->metaObject();
2941 int method_index = rmeta->indexOfMethod(method);
2942 if (method_index >= 0)
2943 while (method_index < rmeta->methodOffset())
2944 rmeta = rmeta->superClass();
2945 if (method_index < 0)
2947 res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index);
2948 method_found = true;
2949 } while ((rmeta = rmeta->superClass()));
2951 } while (signal && (smeta = smeta->superClass()));
2953 if (signal && !signal_found) {
2954 err_method_notfound(sender, signal_arg, "disconnect");
2955 err_info_about_objects("disconnect", sender, receiver);
2956 } else if (method && !method_found) {
2957 err_method_notfound(receiver, method_arg, "disconnect");
2958 err_info_about_objects("disconnect", sender, receiver);
2961 const_cast<QObject*>(sender)->disconnectNotify(signal ? (signal - 1) : 0);
2968 Disconnects \a signal in object \a sender from \a method in object
2969 \a receiver. Returns true if the connection is successfully broken;
2970 otherwise returns false.
2972 This function provides the same posibilities like
2973 disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2974 but uses QMetaMethod to represent the signal and the method to be disconnected.
2976 Additionally this function returnsfalse and no signals and slots disconnected
2980 \i \a signal is not a member of sender class or one of its parent classes.
2982 \i \a method is not a member of receiver class or one of its parent classes.
2984 \i \a signal instance represents not a signal.
2988 QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
2989 In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
2990 method shoud also be QMetaMethod(). \a sender parameter should be never 0.
2992 \see disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
2994 bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
2995 const QObject *receiver, const QMetaMethod &method)
2997 if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
2998 qWarning("Object::disconnect: Unexpected null parameter");
3002 if(signal.methodType() != QMetaMethod::Signal) {
3003 qWarning("Object::%s: Attempt to %s non-signal %s::%s",
3004 "disconnect","unbind",
3005 sender->metaObject()->className(), signal.signature());
3010 if(method.methodType() == QMetaMethod::Constructor) {
3011 qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
3012 receiver->metaObject()->className(), method.signature());
3017 // Reconstructing SIGNAL() macro result for signal.signature() string
3018 QByteArray signalSignature;
3020 signalSignature.reserve(qstrlen(signal.signature())+1);
3021 signalSignature.append((char)(QSIGNAL_CODE + '0'));
3022 signalSignature.append(signal.signature());
3026 QByteArray methodSignature;
3028 methodSignature.reserve(qstrlen(method.signature())+1);
3029 methodSignature.append((char)(method.methodType() == QMetaMethod::Slot ? QSLOT_CODE
3030 : method.methodType() == QMetaMethod::Signal ? QSIGNAL_CODE : 0 + '0'));
3031 methodSignature.append(method.signature());
3033 const void *cbdata[] = { sender, signal.mobj ? signalSignature.constData() : 0,
3034 receiver, method.mobj ? methodSignature.constData() : 0 };
3035 if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
3043 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
3044 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
3046 // If we are here sender is not null. If signal is not null while signal_index
3047 // is -1 then this signal is not a member of sender.
3048 if (signal.mobj && signal_index == -1) {
3049 qWarning("QObject::disconect: signal %s not found on class %s",
3050 signal.signature(), sender->metaObject()->className());
3053 // If this condition is true then method is not a member of receeiver.
3054 if (receiver && method.mobj && method_index == -1) {
3055 qWarning("QObject::disconect: method %s not found on class %s",
3056 method.signature(), receiver->metaObject()->className());
3060 if (!QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index))
3063 const_cast<QObject*>(sender)->disconnectNotify(method.mobj ? signalSignature.constData() : 0);
3070 \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method)
3071 \overload disconnect()
3073 Disconnects \a signal from \a method of \a receiver.
3075 A signal-slot connection is removed when either of the objects
3076 involved are destroyed.
3080 \fn bool QObject::disconnect(const QObject *receiver, const char *method)
3081 \overload disconnect()
3083 Disconnects all signals in this object from \a receiver's \a
3086 A signal-slot connection is removed when either of the objects
3087 involved are destroyed.
3092 \fn void QObject::connectNotify(const char *signal)
3094 This virtual function is called when something has been connected
3095 to \a signal in this object.
3097 If you want to compare \a signal with a specific signal, use
3098 QLatin1String and the \c SIGNAL() macro as follows:
3100 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 32
3102 If the signal contains multiple parameters or parameters that
3103 contain spaces, call QMetaObject::normalizedSignature() on
3104 the result of the \c SIGNAL() macro.
3106 \warning This function violates the object-oriented principle of
3107 modularity. However, it might be useful when you need to perform
3108 expensive initialization only if something is connected to a
3111 \sa connect(), disconnectNotify()
3114 void QObject::connectNotify(const char *)
3119 \fn void QObject::disconnectNotify(const char *signal)
3121 This virtual function is called when something has been
3122 disconnected from \a signal in this object.
3124 See connectNotify() for an example of how to compare
3125 \a signal with a specific signal.
3127 \warning This function violates the object-oriented principle of
3128 modularity. However, it might be useful for optimizing access to
3129 expensive resources.
3131 \sa disconnect(), connectNotify()
3134 void QObject::disconnectNotify(const char *)
3139 convert a signal index from the method range to the signal range
3141 static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index)
3143 if (signal_index < 0)
3144 return signal_index;
3145 while (metaObject && metaObject->methodOffset() > signal_index)
3146 metaObject = metaObject->superClass();
3149 int signalOffset, methodOffset;
3150 computeOffsets(metaObject, &signalOffset, &methodOffset);
3151 if (signal_index < metaObject->methodCount())
3152 signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
3154 signal_index = signal_index - methodOffset + signalOffset;
3156 return signal_index;
3160 \a types is a 0-terminated vector of meta types for queued
3163 if \a signal_index is -1, then we effectively connect *all* signals
3164 from the sender to the receiver's slot
3166 bool QMetaObject::connect(const QObject *sender, int signal_index,
3167 const QObject *receiver, int method_index, int type, int *types)
3169 signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3170 return QMetaObjectPrivate::connect(sender, signal_index,
3171 receiver, method_index,
3172 0, //FIXME, we could speed this connection up by computing the relative index
3177 Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3179 method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index
3181 bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
3182 const QObject *receiver, int method_index,
3183 const QMetaObject *rmeta, int type, int *types)
3185 QObject *s = const_cast<QObject *>(sender);
3186 QObject *r = const_cast<QObject *>(receiver);
3188 int method_offset = rmeta ? rmeta->methodOffset() : 0;
3189 QObjectPrivate::StaticMetaCallFunction callFunction =
3190 (rmeta && QMetaObjectPrivate::get(rmeta)->revision >= 6 && rmeta->d.extradata)
3191 ? reinterpret_cast<const QMetaObjectExtraData *>(rmeta->d.extradata)->static_metacall : 0;
3193 QOrderedMutexLocker locker(signalSlotLock(sender),
3194 signalSlotLock(receiver));
3196 if (type & Qt::UniqueConnection) {
3197 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3198 if (connectionLists && connectionLists->count() > signal_index) {
3199 const QObjectPrivate::Connection *c2 =
3200 (*connectionLists)[signal_index].first;
3202 int method_index_absolute = method_index + method_offset;
3205 if (c2->receiver == receiver && c2->method() == method_index_absolute)
3207 c2 = c2->nextConnectionList;
3210 type &= Qt::UniqueConnection - 1;
3213 QObjectPrivate::Connection *c = new QObjectPrivate::Connection;
3216 c->method_relative = method_index;
3217 c->method_offset = method_offset;
3218 c->connectionType = type;
3219 c->argumentTypes = types;
3220 c->nextConnectionList = 0;
3221 c->callFunction = callFunction;
3224 QObjectPrivate::get(s)->addConnection(signal_index, c);
3230 c->prev = &(QObjectPrivate::get(r)->senders);
3234 c->next->prev = &c->next;
3236 QObjectPrivate *const sender_d = QObjectPrivate::get(s);
3237 if (signal_index < 0) {
3238 sender_d->connectedSignals[0] = sender_d->connectedSignals[1] = ~0;
3239 } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) {
3240 sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f));
3248 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3249 const QObject *receiver, int method_index)
3251 signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3252 return QMetaObjectPrivate::disconnect(sender, signal_index,
3253 receiver, method_index);
3258 Disconnect a single signal connection. If QMetaObject::connect() has been called
3259 multiple times for the same sender, signal_index, receiver and method_index only
3260 one of these connections will be removed.
3262 bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3263 const QObject *receiver, int method_index)
3265 signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
3266 return QMetaObjectPrivate::disconnect(sender, signal_index,
3267 receiver, method_index,
3268 QMetaObjectPrivate::DisconnectOne);
3272 Helper function to remove the connection from the senders list and setting the receivers to 0
3274 bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
3275 const QObject *receiver, int method_index,
3276 QMutex *senderMutex, DisconnectType disconnectType)
3278 bool success = false;
3281 && (receiver == 0 || (c->receiver == receiver
3282 && (method_index < 0 || c->method() == method_index)))) {
3283 bool needToUnlock = false;
3284 QMutex *receiverMutex = 0;
3286 receiverMutex = signalSlotLock(c->receiver);
3287 // need to relock this receiver and sender in the correct order
3288 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3293 c->next->prev = c->prev;
3297 receiverMutex->unlockInline();
3303 if (disconnectType == DisconnectOne)
3306 c = c->nextConnectionList;
3312 Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3314 bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
3315 const QObject *receiver, int method_index,
3316 DisconnectType disconnectType)
3321 QObject *s = const_cast<QObject *>(sender);
3323 QMutex *senderMutex = signalSlotLock(sender);
3324 QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0;
3325 QOrderedMutexLocker locker(senderMutex, receiverMutex);
3327 QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
3328 if (!connectionLists)
3331 // prevent incoming connections changing the connectionLists while unlocked
3332 ++connectionLists->inUse;
3334 bool success = false;
3335 if (signal_index < 0) {
3336 // remove from all connection lists
3337 for (signal_index = -1; signal_index < connectionLists->count(); ++signal_index) {
3338 QObjectPrivate::Connection *c =
3339 (*connectionLists)[signal_index].first;
3340 if (disconnectHelper(c, receiver, method_index, senderMutex, disconnectType)) {
3342 connectionLists->dirty = true;
3345 } else if (signal_index < connectionLists->count()) {
3346 QObjectPrivate::Connection *c =
3347 (*connectionLists)[signal_index].first;
3348 if (disconnectHelper(c, receiver, method_index, senderMutex, disconnectType)) {
3350 connectionLists->dirty = true;
3354 --connectionLists->inUse;
3355 Q_ASSERT(connectionLists->inUse >= 0);
3356 if (connectionLists->orphaned && !connectionLists->inUse)
3357 delete connectionLists;
3363 \fn void QMetaObject::connectSlotsByName(QObject *object)
3365 Searches recursively for all child objects of the given \a object, and connects
3366 matching signals from them to slots of \a object that follow the following form:
3368 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 33
3370 Let's assume our object has a child object of type QPushButton with
3371 the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3372 button's \c{clicked()} signal would be:
3374 \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 34
3376 \sa QObject::setObjectName()
3378 void QMetaObject::connectSlotsByName(QObject *o)
3382 const QMetaObject *mo = o->metaObject();
3384 const QObjectList list = o->findChildren<QObject *>(QString());
3385 for (int i = 0; i < mo->methodCount(); ++i) {
3386 const char *slot = mo->method(i).signature();
3388 if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3390 bool foundIt = false;
3391 for(int j = 0; j < list.count(); ++j) {
3392 const QObject *co = list.at(j);
3393 QByteArray objName = co->objectName().toAscii();
3394 int len = objName.length();
3395 if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
3397 int sigIndex = co->d_func()->signalIndex(slot + len + 4);
3398 if (sigIndex < 0) { // search for compatible signals
3399 const QMetaObject *smo = co->metaObject();
3400 int slotlen = qstrlen(slot + len + 4) - 1;
3401 for (int k = 0; k < co->metaObject()->methodCount(); ++k) {
3402 QMetaMethod method = smo->method(k);
3403 if (method.methodType() != QMetaMethod::Signal)
3406 if (!qstrncmp(method.signature(), slot + len + 4, slotlen)) {
3407 int signalOffset, methodOffset;
3408 computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset);
3409 sigIndex = k + - methodOffset + signalOffset;
3416 if (QMetaObjectPrivate::connect(co, sigIndex, o, i)) {
3422 // we found our slot, now skip all overloads
3423 while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3425 } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3426 qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3431 static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3433 if (!c->argumentTypes && c->argumentTypes != &DIRECT_CONNECTION_ONLY) {
3434 QMetaMethod m = sender->metaObject()->method(signal);
3435 int *tmp = queuedConnectionTypes(m.parameterTypes());
3436 if (!tmp) // cannot queue arguments
3437 tmp = &DIRECT_CONNECTION_ONLY;
3438 if (!c->argumentTypes.testAndSetOrdered(0, tmp)) {
3439 if (tmp != &DIRECT_CONNECTION_ONLY)
3443 if (c->argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3445 int nargs = 1; // include return type
3446 while (c->argumentTypes[nargs-1])
3448 int *types = (int *) qMalloc(nargs*sizeof(int));
3450 void **args = (void **) qMalloc(nargs*sizeof(void *));
3452 types[0] = 0; // return type
3453 args[0] = 0; // return value
3454 for (int n = 1; n < nargs; ++n)
3455 args[n] = QMetaType::construct((types[n] = c->argumentTypes[n-1]), argv[n]);
3456 QCoreApplication::postEvent(c->receiver, new QMetaCallEvent(c->method_offset,
3459 sender, signal, nargs,
3466 Used to be called from QMetaObject::activate(QObject *, QMetaObject *, int, int, void **) before Qt 4.6
3468 void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal_index, void **argv)
3470 Q_UNUSED(to_signal_index);
3471 activate(sender, from_signal_index, argv);
3476 void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
3481 computeOffsets(m, &signalOffset, &methodOffset);
3483 int signal_index = signalOffset + local_signal_index;
3485 if (!sender->d_func()->isSignalConnected(signal_index))
3486 return; // nothing connected to these signals, and no spy
3488 if (sender->d_func()->blockSig)
3491 int signal_absolute_index = methodOffset + local_signal_index;
3493 void *empty_argv[] = { 0 };
3494 if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
3495 qt_signal_spy_callback_set.signal_begin_callback(sender, signal_absolute_index,
3496 argv ? argv : empty_argv);
3499 Qt::HANDLE currentThreadId = QThread::currentThreadId();
3501 QMutexLocker locker(signalSlotLock(sender));
3502 QObjectConnectionListVector *connectionLists = sender->d_func()->connectionLists;
3503 if (!connectionLists) {
3505 if (qt_signal_spy_callback_set.signal_end_callback != 0)
3506 qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
3509 ++connectionLists->inUse;
3512 const QObjectPrivate::ConnectionList *list;
3513 if (signal_index < connectionLists->count())
3514 list = &connectionLists->at(signal_index);
3516 list = &connectionLists->allsignals;
3519 QObjectPrivate::Connection *c = list->first;
3521 // We need to check against last here to ensure that signals added
3522 // during the signal emission are not emitted in this emission.
3523 QObjectPrivate::Connection *last = list->last;
3529 QObject * const receiver = c->receiver;
3530 const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId;
3532 // determine if this connection should be sent immediately or
3533 // put into the event queue
3534 if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
3535 || (c->connectionType == Qt::QueuedConnection)) {
3536 queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);