1/****************************************************************************
2**
3** Copyright (C) 2019 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
6** Contact: https://www.qt.io/licensing/
7**
8** This file is part of the QtCore module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial License Usage
12** Licensees holding valid commercial Qt licenses may use this file in
13** accordance with the commercial license agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and The Qt Company. For licensing terms
16** and conditions see https://www.qt.io/terms-conditions. For further
17** information use the contact form at https://www.qt.io/contact-us.
18**
19** GNU Lesser General Public License Usage
20** Alternatively, this file may be used under the terms of the GNU Lesser
21** General Public License version 3 as published by the Free Software
22** Foundation and appearing in the file LICENSE.LGPL3 included in the
23** packaging of this file. Please review the following information to
24** ensure the GNU Lesser General Public License version 3 requirements
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26**
27** GNU General Public License Usage
28** Alternatively, this file may be used under the terms of the GNU
29** General Public License version 2.0 or (at your option) the GNU General
30** Public license version 3 or any later version approved by the KDE Free
31** Qt Foundation. The licenses are as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33** included in the packaging of this file. Please review the following
34** information to ensure the GNU General Public License requirements will
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36** https://www.gnu.org/licenses/gpl-3.0.html.
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qobject.h"
43#include "qobject_p.h"
44#include "qmetaobject_p.h"
45
46#include "qabstracteventdispatcher.h"
47#include "qabstracteventdispatcher_p.h"
48#include "qcoreapplication.h"
49#include "qcoreapplication_p.h"
50#include "qvariant.h"
51#include "qmetaobject.h"
52#include <qregexp.h>
53#if QT_CONFIG(regularexpression)
54# include <qregularexpression.h>
55#endif
56#include <qthread.h>
57#include <private/qthread_p.h>
58#include <qdebug.h>
59#include <qpair.h>
60#include <qvarlengtharray.h>
61#include <qset.h>
62#if QT_CONFIG(thread)
63#include <qsemaphore.h>
64#endif
65#include <qsharedpointer.h>
66
67#include <private/qorderedmutexlocker_p.h>
68#include <private/qhooks_p.h>
69#include <qtcore_tracepoints_p.h>
70
71#include <new>
72
73#include <ctype.h>
74#include <limits.h>
75
76QT_BEGIN_NAMESPACE
77
78static int DIRECT_CONNECTION_ONLY = 0;
79
80Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
81
82void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
83{
84 qt_signal_spy_callback_set.store(callback_set);
85}
86
87QDynamicMetaObjectData::~QDynamicMetaObjectData()
88{
89}
90
91QAbstractDynamicMetaObject::~QAbstractDynamicMetaObject()
92{
93}
94
95
96struct QSlotObjectBaseDeleter { // for use with QScopedPointer<QSlotObjectBase,...>
97 static void cleanup(QtPrivate::QSlotObjectBase *slot) {
98 if (slot) slot->destroyIfLastRef();
99 }
100};
101static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
102{
103 int *types = new int [typeNames.count() + 1];
104 Q_CHECK_PTR(types);
105 for (int i = 0; i < typeNames.count(); ++i) {
106 const QByteArray typeName = typeNames.at(i);
107 if (typeName.endsWith('*'))
108 types[i] = QMetaType::VoidStar;
109 else
110 types[i] = QMetaType::type(typeName);
111
112 if (!types[i]) {
113 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
114 "(Make sure '%s' is registered using qRegisterMetaType().)",
115 typeName.constData(), typeName.constData());
116 delete [] types;
117 return 0;
118 }
119 }
120 types[typeNames.count()] = 0;
121
122 return types;
123}
124
125static int *queuedConnectionTypes(const QArgumentType *argumentTypes, int argc)
126{
127 QScopedArrayPointer<int> types(new int [argc + 1]);
128 for (int i = 0; i < argc; ++i) {
129 const QArgumentType &type = argumentTypes[i];
130 if (type.type())
131 types[i] = type.type();
132 else if (type.name().endsWith('*'))
133 types[i] = QMetaType::VoidStar;
134 else
135 types[i] = QMetaType::type(type.name());
136
137 if (!types[i]) {
138 qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"
139 "(Make sure '%s' is registered using qRegisterMetaType().)",
140 type.name().constData(), type.name().constData());
141 return 0;
142 }
143 }
144 types[argc] = 0;
145
146 return types.take();
147}
148
149static QBasicMutex _q_ObjectMutexPool[131];
150
151/**
152 * \internal
153 * mutex to be locked when accessing the connectionlists or the senders list
154 */
155static inline QBasicMutex *signalSlotLock(const QObject *o)
156{
157 return &_q_ObjectMutexPool[uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)];
158}
159
160#if QT_VERSION < 0x60000
161extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
162{}
163
164extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
165{}
166#endif
167
168void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
169void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
170void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
171void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
172int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
173bool (*QAbstractDeclarativeData::isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int) = 0;
174void (*QAbstractDeclarativeData::setWidgetParent)(QObject *, QObject *) = 0;
175
176QObjectData::~QObjectData() {}
177
178QMetaObject *QObjectData::dynamicMetaObject() const
179{
180 return metaObject->toDynamicMetaObject(q_ptr);
181}
182
183QObjectPrivate::QObjectPrivate(int version)
184 : threadData(0), currentChildBeingDeleted(0)
185{
186#ifdef QT_BUILD_INTERNAL
187 // Don't check the version parameter in internal builds.
188 // This allows incompatible versions to be loaded, possibly for testing.
189 Q_UNUSED(version);
190#else
191 if (Q_UNLIKELY(version != QObjectPrivateVersion))
192 qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
193 version, QObjectPrivateVersion);
194#endif
195
196 // QObjectData initialization
197 q_ptr = 0;
198 parent = 0; // no parent yet. It is set by setParent()
199 isWidget = false; // assume not a widget object
200 blockSig = false; // not blocking signals
201 wasDeleted = false; // double-delete catcher
202 isDeletingChildren = false; // set by deleteChildren()
203 sendChildEvents = true; // if we should send ChildAdded and ChildRemoved events to parent
204 receiveChildEvents = true;
205 postedEvents = 0;
206 extraData = 0;
207 metaObject = 0;
208 isWindow = false;
209 deleteLaterCalled = false;
210}
211
212QObjectPrivate::~QObjectPrivate()
213{
214 if (extraData && !extraData->runningTimers.isEmpty()) {
215 if (Q_LIKELY(threadData->thread == QThread::currentThread())) {
216 // unregister pending timers
217 if (threadData->hasEventDispatcher())
218 threadData->eventDispatcher.load()->unregisterTimers(q_ptr);
219
220 // release the timer ids back to the pool
221 for (int i = 0; i < extraData->runningTimers.size(); ++i)
222 QAbstractEventDispatcherPrivate::releaseTimerId(extraData->runningTimers.at(i));
223 } else {
224 qWarning("QObject::~QObject: Timers cannot be stopped from another thread");
225 }
226 }
227
228 if (postedEvents)
229 QCoreApplication::removePostedEvents(q_ptr, 0);
230
231 threadData->deref();
232
233 if (metaObject) metaObject->objectDestroyed(q_ptr);
234
235#ifndef QT_NO_USERDATA
236 if (extraData)
237 qDeleteAll(extraData->userData);
238#endif
239 delete extraData;
240}
241
242/*!
243 \internal
244 For a given metaobject, compute the signal offset, and the method offset (including signals)
245*/
246static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int *methodOffset)
247{
248 *signalOffset = *methodOffset = 0;
249 const QMetaObject *m = metaobject->d.superdata;
250 while (m) {
251 const QMetaObjectPrivate *d = QMetaObjectPrivate::get(m);
252 *methodOffset += d->methodCount;
253 Q_ASSERT(d->revision >= 4);
254 *signalOffset += d->signalCount;
255 m = m->d.superdata;
256 }
257}
258
259// Used by QAccessibleWidget
260bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
261{
262 Q_Q(const QObject);
263 int signal_index = signalIndex(signal);
264 ConnectionData *cd = connections.load();
265 if (signal_index < 0 || !cd)
266 return false;
267 QBasicMutexLocker locker(signalSlotLock(q));
268 if (signal_index < cd->signalVectorCount()) {
269 const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
270
271 while (c) {
272 if (c->receiver.load() == receiver)
273 return true;
274 c = c->nextConnectionList.load();
275 }
276 }
277 return false;
278}
279
280// Used by QAccessibleWidget
281QObjectList QObjectPrivate::receiverList(const char *signal) const
282{
283 QObjectList returnValue;
284 int signal_index = signalIndex(signal);
285 ConnectionData *cd = connections.load();
286 if (signal_index < 0 || !cd)
287 return returnValue;
288 if (signal_index < cd->signalVectorCount()) {
289 const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
290
291 while (c) {
292 QObject *r = c->receiver.load();
293 if (r)
294 returnValue << r;
295 c = c->nextConnectionList.load();
296 }
297 }
298 return returnValue;
299}
300
301// Used by QAccessibleWidget
302QObjectList QObjectPrivate::senderList() const
303{
304 QObjectList returnValue;
305 ConnectionData *cd = connections.load();
306 if (cd) {
307 QBasicMutexLocker locker(signalSlotLock(q_func()));
308 for (Connection *c = cd->senders; c; c = c->next)
309 returnValue << c->sender;
310 }
311 return returnValue;
312}
313
314/*!
315 \internal
316 Add the connection \a c to the list of connections of the sender's object
317 for the specified \a signal
318
319 The signalSlotLock() of the sender and receiver must be locked while calling
320 this function
321
322 Will also add the connection in the sender's list of the receiver.
323 */
324void QObjectPrivate::addConnection(int signal, Connection *c)
325{
326 Q_ASSERT(c->sender == q_ptr);
327 ensureConnectionData();
328 ConnectionData *cd = connections.load();
329 cd->resizeSignalVector(signal + 1);
330
331 ConnectionList &connectionList = cd->connectionsForSignal(signal);
332 if (connectionList.last.load()) {
333 Q_ASSERT(connectionList.last.load()->receiver.load());
334 connectionList.last.load()->nextConnectionList.store(c);
335 } else {
336 connectionList.first.store(c);
337 }
338 c->id = ++cd->currentConnectionId;
339 c->prevConnectionList = connectionList.last.load();
340 connectionList.last.store(c);
341
342 QObjectPrivate *rd = QObjectPrivate::get(c->receiver.load());
343 rd->ensureConnectionData();
344
345 c->prev = &(rd->connections.load()->senders);
346 c->next = *c->prev;
347 *c->prev = c;
348 if (c->next)
349 c->next->prev = &c->next;
350}
351
352void QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection *c)
353{
354 Q_ASSERT(c->receiver.load());
355 ConnectionList &connections = signalVector.load()->at(c->signal_index);
356 c->receiver.store(nullptr);
357 QThreadData *td = c->receiverThreadData.load();
358 if (td)
359 td->deref();
360 c->receiverThreadData.store(nullptr);
361
362#ifndef QT_NO_DEBUG
363 bool found = false;
364 for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
365 if (cc == c) {
366 found = true;
367 break;
368 }
369 }
370 Q_ASSERT(found);
371#endif
372
373 // remove from the senders linked list
374 *c->prev = c->next;
375 if (c->next)
376 c->next->prev = c->prev;
377 c->prev = nullptr;
378
379 if (connections.first.load() == c)
380 connections.first.store(c->nextConnectionList.load());
381 if (connections.last.load() == c)
382 connections.last.store(c->prevConnectionList);
383 Q_ASSERT(signalVector.load()->at(c->signal_index).first.load() != c);
384 Q_ASSERT(signalVector.load()->at(c->signal_index).last.load() != c);
385
386 // keep c->nextConnectionList intact, as it might still get accessed by activate
387 Connection *n = c->nextConnectionList.load();
388 if (n)
389 n->prevConnectionList = c->prevConnectionList;
390 if (c->prevConnectionList)
391 c->prevConnectionList->nextConnectionList.store(n);
392 c->prevConnectionList = nullptr;
393
394 Q_ASSERT(c != orphaned.load());
395 // add c to orphanedConnections
396 c->nextInOrphanList = orphaned.load();
397 orphaned.store(c);
398
399#ifndef QT_NO_DEBUG
400 found = false;
401 for (Connection *cc = connections.first.load(); cc; cc = cc->nextConnectionList.load()) {
402 if (cc == c) {
403 found = true;
404 break;
405 }
406 }
407 Q_ASSERT(!found);
408#endif
409
410}
411
412void QObjectPrivate::ConnectionData::cleanOrphanedConnectionsImpl(QObject *sender)
413{
414 ConnectionOrSignalVector *c = nullptr;
415 {
416 QBasicMutexLocker l(signalSlotLock(sender));
417 if (ref > 1)
418 return;
419
420 // Since ref == 1, no activate() is in process since we locked the mutex. That implies,
421 // that nothing can reference the orphaned connection objects anymore and they can
422 // be safely deleted
423 c = orphaned.load();
424 orphaned.store(nullptr);
425 }
426 deleteOrphaned(c);
427}
428
429void QObjectPrivate::ConnectionData::deleteOrphaned(QObjectPrivate::ConnectionOrSignalVector *o)
430{
431 while (o) {
432 QObjectPrivate::ConnectionOrSignalVector *next = nullptr;
433 if (SignalVector *v = ConnectionOrSignalVector::asSignalVector(o)) {
434 next = v->nextInOrphanList;
435 free(v);
436 } else {
437 QObjectPrivate::Connection *c = static_cast<Connection *>(o);
438 next = c->nextInOrphanList;
439 Q_ASSERT(!c->receiver.load());
440 Q_ASSERT(!c->prev);
441 c->freeSlotObject();
442 c->deref();
443 }
444 o = next;
445 }
446}
447
448/*! \internal
449
450 Returns \c true if the signal with index \a signal_index from object \a sender is connected.
451
452 \a signal_index must be the index returned by QObjectPrivate::signalIndex;
453*/
454bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) const
455{
456 if (checkDeclarative && isDeclarativeSignalConnected(signalIndex))
457 return true;
458
459 ConnectionData *cd = connections.load();
460 if (!cd)
461 return false;
462 SignalVector *signalVector = cd->signalVector.load();
463 if (!signalVector)
464 return false;
465
466 if (signalVector->at(-1).first.load())
467 return true;
468
469 if (signalIndex < uint(cd->signalVectorCount())) {
470 const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.load();
471 while (c) {
472 if (c->receiver.load())
473 return true;
474 c = c->nextConnectionList.load();
475 }
476 }
477 return false;
478}
479
480bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const
481{
482 ConnectionData *cd = connections.load();
483 if (!cd)
484 return false;
485 SignalVector *signalVector = cd->signalVector.load();
486 if (!signalVector)
487 return false;
488
489 if (signalVector->at(-1).first)
490 return true;
491
492 if (signalIndex < uint(cd->signalVectorCount())) {
493 const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first;
494 return c != nullptr;
495 }
496 return false;
497}
498
499/*!
500 \internal
501 */
502QAbstractMetaCallEvent::~QAbstractMetaCallEvent()
503{
504#if QT_CONFIG(thread)
505 if (semaphore_)
506 semaphore_->release();
507#endif
508}
509
510/*!
511 \internal
512 */
513QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QObjectPrivate::StaticMetaCallFunction callFunction,
514 const QObject *sender, int signalId,
515 int nargs, int *types, void **args, QSemaphore *semaphore)
516 : QAbstractMetaCallEvent(sender, signalId, semaphore),
517 slotObj_(nullptr), nargs_(nargs), types_(types), args_(args),
518 callFunction_(callFunction), method_offset_(method_offset), method_relative_(method_relative)
519{ }
520
521/*!
522 \internal
523 */
524QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId,
525 int nargs, int *types, void **args, QSemaphore *semaphore)
526 : QAbstractMetaCallEvent(sender, signalId, semaphore),
527 slotObj_(slotO), nargs_(nargs), types_(types), args_(args),
528 callFunction_(nullptr), method_offset_(0), method_relative_(ushort(-1))
529{
530 if (slotObj_)
531 slotObj_->ref();
532}
533
534/*!
535 \internal
536 */
537QMetaCallEvent::~QMetaCallEvent()
538{
539 if (types_) {
540 for (int i = 0; i < nargs_; ++i) {
541 if (types_[i] && args_[i])
542 QMetaType::destroy(types_[i], args_[i]);
543 }
544 free(types_);
545 free(args_);
546 }
547 if (slotObj_)
548 slotObj_->destroyIfLastRef();
549}
550
551/*!
552 \internal
553 */
554void QMetaCallEvent::placeMetaCall(QObject *object)
555{
556 if (slotObj_) {
557 slotObj_->call(object, args_);
558 } else if (callFunction_ && method_offset_ <= object->metaObject()->methodOffset()) {
559 callFunction_(object, QMetaObject::InvokeMetaMethod, method_relative_, args_);
560 } else {
561 QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method_offset_ + method_relative_, args_);
562 }
563}
564
565/*!
566 \class QSignalBlocker
567 \brief Exception-safe wrapper around QObject::blockSignals().
568 \since 5.3
569 \ingroup objectmodel
570 \inmodule QtCore
571
572 \reentrant
573
574 QSignalBlocker can be used wherever you would otherwise use a
575 pair of calls to blockSignals(). It blocks signals in its
576 constructor and in the destructor it resets the state to what
577 it was before the constructor ran.
578
579 \snippet code/src_corelib_kernel_qobject.cpp 53
580 is thus equivalent to
581 \snippet code/src_corelib_kernel_qobject.cpp 54
582
583 except the code using QSignalBlocker is safe in the face of
584 exceptions.
585
586 \sa QMutexLocker, QEventLoopLocker
587*/
588
589/*!
590 \fn QSignalBlocker::QSignalBlocker(QObject *object)
591
592 Constructor. Calls \a{object}->blockSignals(true).
593*/
594
595/*!
596 \fn QSignalBlocker::QSignalBlocker(QObject &object)
597 \overload
598
599 Calls \a{object}.blockSignals(true).
600*/
601
602/*!
603 \fn QSignalBlocker::QSignalBlocker(QSignalBlocker &&other)
604
605 Move-constructs a signal blocker from \a other. \a other will have
606 a no-op destructor, while repsonsibility for restoring the
607 QObject::signalsBlocked() state is transferred to the new object.
608*/
609
610/*!
611 \fn QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other)
612
613 Move-assigns this signal blocker from \a other. \a other will have
614 a no-op destructor, while repsonsibility for restoring the
615 QObject::signalsBlocked() state is transferred to this object.
616
617 The object's signals this signal blocker was blocking prior to
618 being moved to, if any, are unblocked \e except in the case where
619 both instances block the same object's signals and \c *this is
620 unblocked while \a other is not, at the time of the move.
621*/
622
623/*!
624 \fn QSignalBlocker::~QSignalBlocker()
625
626 Destructor. Restores the QObject::signalsBlocked() state to what it
627 was before the constructor ran, unless unblock() has been called
628 without a following reblock(), in which case it does nothing.
629*/
630
631/*!
632 \fn void QSignalBlocker::reblock()
633
634 Re-blocks signals after a previous unblock().
635
636 The numbers of reblock() and unblock() calls are not counted, so
637 every reblock() undoes any number of unblock() calls.
638*/
639
640/*!
641 \fn void QSignalBlocker::unblock()
642
643 Temporarily restores the QObject::signalsBlocked() state to what
644 it was before this QSignaBlocker's constructor ran. To undo, use
645 reblock().
646
647 The numbers of reblock() and unblock() calls are not counted, so
648 every unblock() undoes any number of reblock() calls.
649*/
650
651/*!
652 \class QObject
653 \inmodule QtCore
654 \brief The QObject class is the base class of all Qt objects.
655
656 \ingroup objectmodel
657
658 \reentrant
659
660 QObject is the heart of the Qt \l{Object Model}. The central
661 feature in this model is a very powerful mechanism for seamless
662 object communication called \l{signals and slots}. You can
663 connect a signal to a slot with connect() and destroy the
664 connection with disconnect(). To avoid never ending notification
665 loops you can temporarily block signals with blockSignals(). The
666 protected functions connectNotify() and disconnectNotify() make
667 it possible to track connections.
668
669 QObjects organize themselves in \l {Object Trees & Ownership}
670 {object trees}. When you create a QObject with another object as
671 parent, the object will automatically add itself to the parent's
672 children() list. The parent takes ownership of the object; i.e.,
673 it will automatically delete its children in its destructor. You
674 can look for an object by name and optionally type using
675 findChild() or findChildren().
676
677 Every object has an objectName() and its class name can be found
678 via the corresponding metaObject() (see QMetaObject::className()).
679 You can determine whether the object's class inherits another
680 class in the QObject inheritance hierarchy by using the
681 inherits() function.
682
683 When an object is deleted, it emits a destroyed() signal. You can
684 catch this signal to avoid dangling references to QObjects.
685
686 QObjects can receive events through event() and filter the events
687 of other objects. See installEventFilter() and eventFilter() for
688 details. A convenience handler, childEvent(), can be reimplemented
689 to catch child events.
690
691 Last but not least, QObject provides the basic timer support in
692 Qt; see QTimer for high-level support for timers.
693
694 Notice that the Q_OBJECT macro is mandatory for any object that
695 implements signals, slots or properties. You also need to run the
696 \l{moc}{Meta Object Compiler} on the source file. We strongly
697 recommend the use of this macro in all subclasses of QObject
698 regardless of whether or not they actually use signals, slots and
699 properties, since failure to do so may lead certain functions to
700 exhibit strange behavior.
701
702 All Qt widgets inherit QObject. The convenience function
703 isWidgetType() returns whether an object is actually a widget. It
704 is much faster than
705 \l{qobject_cast()}{qobject_cast}<QWidget *>(\e{obj}) or
706 \e{obj}->\l{inherits()}{inherits}("QWidget").
707
708 Some QObject functions, e.g. children(), return a QObjectList.
709 QObjectList is a typedef for QList<QObject *>.
710
711 \section1 Thread Affinity
712
713 A QObject instance is said to have a \e{thread affinity}, or that
714 it \e{lives} in a certain thread. When a QObject receives a
715 \l{Qt::QueuedConnection}{queued signal} or a \l{The Event
716 System#Sending Events}{posted event}, the slot or event handler
717 will run in the thread that the object lives in.
718
719 \note If a QObject has no thread affinity (that is, if thread()
720 returns zero), or if it lives in a thread that has no running event
721 loop, then it cannot receive queued signals or posted events.
722
723 By default, a QObject lives in the thread in which it is created.
724 An object's thread affinity can be queried using thread() and
725 changed using moveToThread().
726
727 All QObjects must live in the same thread as their parent. Consequently:
728
729 \list
730 \li setParent() will fail if the two QObjects involved live in
731 different threads.
732 \li When a QObject is moved to another thread, all its children
733 will be automatically moved too.
734 \li moveToThread() will fail if the QObject has a parent.
735 \li If QObjects are created within QThread::run(), they cannot
736 become children of the QThread object because the QThread does
737 not live in the thread that calls QThread::run().
738 \endlist
739
740 \note A QObject's member variables \e{do not} automatically become
741 its children. The parent-child relationship must be set by either
742 passing a pointer to the child's \l{QObject()}{constructor}, or by
743 calling setParent(). Without this step, the object's member variables
744 will remain in the old thread when moveToThread() is called.
745
746 \target No copy constructor
747 \section1 No Copy Constructor or Assignment Operator
748
749 QObject has neither a copy constructor nor an assignment operator.
750 This is by design. Actually, they are declared, but in a
751 \c{private} section with the macro Q_DISABLE_COPY(). In fact, all
752 Qt classes derived from QObject (direct or indirect) use this
753 macro to declare their copy constructor and assignment operator to
754 be private. The reasoning is found in the discussion on
755 \l{Identity vs Value} {Identity vs Value} on the Qt \l{Object
756 Model} page.
757
758 The main consequence is that you should use pointers to QObject
759 (or to your QObject subclass) where you might otherwise be tempted
760 to use your QObject subclass as a value. For example, without a
761 copy constructor, you can't use a subclass of QObject as the value
762 to be stored in one of the container classes. You must store
763 pointers.
764
765 \section1 Auto-Connection
766
767 Qt's meta-object system provides a mechanism to automatically connect
768 signals and slots between QObject subclasses and their children. As long
769 as objects are defined with suitable object names, and slots follow a
770 simple naming convention, this connection can be performed at run-time
771 by the QMetaObject::connectSlotsByName() function.
772
773 \l uic generates code that invokes this function to enable
774 auto-connection to be performed between widgets on forms created
775 with \e{Qt Designer}. More information about using auto-connection with \e{Qt Designer} is
776 given in the \l{Using a Designer UI File in Your Application} section of
777 the \e{Qt Designer} manual.
778
779 \section1 Dynamic Properties
780
781 From Qt 4.2, dynamic properties can be added to and removed from QObject
782 instances at run-time. Dynamic properties do not need to be declared at
783 compile-time, yet they provide the same advantages as static properties
784 and are manipulated using the same API - using property() to read them
785 and setProperty() to write them.
786
787 From Qt 4.3, dynamic properties are supported by
788 \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
789 and both standard Qt widgets and user-created forms can be given dynamic
790 properties.
791
792 \section1 Internationalization (I18n)
793
794 All QObject subclasses support Qt's translation features, making it possible
795 to translate an application's user interface into different languages.
796
797 To make user-visible text translatable, it must be wrapped in calls to
798 the tr() function. This is explained in detail in the
799 \l{Writing Source Code for Translation} document.
800
801 \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
802 \sa {Object Trees & Ownership}
803*/
804
805/*****************************************************************************
806 QObject member functions
807 *****************************************************************************/
808
809// check the constructor's parent thread argument
810static bool check_parent_thread(QObject *parent,
811 QThreadData *parentThreadData,
812 QThreadData *currentThreadData)
813{
814 if (parent && parentThreadData != currentThreadData) {
815 QThread *parentThread = parentThreadData->thread;
816 QThread *currentThread = currentThreadData->thread;
817 qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
818 "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
819 parent->metaObject()->className(),
820 parent,
821 parentThread ? parentThread->metaObject()->className() : "QThread",
822 parentThread,
823 currentThread ? currentThread->metaObject()->className() : "QThread",
824 currentThread);
825 return false;
826 }
827 return true;
828}
829
830/*!
831 Constructs an object with parent object \a parent.
832
833 The parent of an object may be viewed as the object's owner. For
834 instance, a \l{QDialog}{dialog box} is the parent of the \uicontrol{OK}
835 and \uicontrol{Cancel} buttons it contains.
836
837 The destructor of a parent object destroys all child objects.
838
839 Setting \a parent to 0 constructs an object with no parent. If the
840 object is a widget, it will become a top-level window.
841
842 \sa parent(), findChild(), findChildren()
843*/
844
845QObject::QObject(QObject *parent)
846 : d_ptr(new QObjectPrivate)
847{
848 Q_D(QObject);
849 d_ptr->q_ptr = this;
850 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
851 d->threadData->ref();
852 if (parent) {
853 QT_TRY {
854 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
855 parent = 0;
856 setParent(parent);
857 } QT_CATCH(...) {
858 d->threadData->deref();
859 QT_RETHROW;
860 }
861 }
862#if QT_VERSION < 0x60000
863 qt_addObject(this);
864#endif
865 if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
866 reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
867 Q_TRACE(QObject_ctor, this);
868}
869
870/*!
871 \internal
872 */
873QObject::QObject(QObjectPrivate &dd, QObject *parent)
874 : d_ptr(&dd)
875{
876 Q_D(QObject);
877 d_ptr->q_ptr = this;
878 d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
879 d->threadData->ref();
880 if (parent) {
881 QT_TRY {
882 if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
883 parent = 0;
884 if (d->isWidget) {
885 if (parent) {
886 d->parent = parent;
887 d->parent->d_func()->children.append(this);
888 }
889 // no events sent here, this is done at the end of the QWidget constructor
890 } else {
891 setParent(parent);
892 }
893 } QT_CATCH(...) {
894 d->threadData->deref();
895 QT_RETHROW;
896 }
897 }
898#if QT_VERSION < 0x60000
899 qt_addObject(this);
900#endif
901 if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
902 reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
903 Q_TRACE(QObject_ctor, this);
904}
905
906/*!
907 Destroys the object, deleting all its child objects.
908
909 All signals to and from the object are automatically disconnected, and
910 any pending posted events for the object are removed from the event
911 queue. However, it is often safer to use deleteLater() rather than
912 deleting a QObject subclass directly.
913
914 \warning All child objects are deleted. If any of these objects
915 are on the stack or global, sooner or later your program will
916 crash. We do not recommend holding pointers to child objects from
917 outside the parent. If you still do, the destroyed() signal gives
918 you an opportunity to detect when an object is destroyed.
919
920 \warning Deleting a QObject while pending events are waiting to
921 be delivered can cause a crash. You must not delete the QObject
922 directly if it exists in a different thread than the one currently
923 executing. Use deleteLater() instead, which will cause the event
924 loop to delete the object after all pending events have been
925 delivered to it.
926
927 \sa deleteLater()
928*/
929
930QObject::~QObject()
931{
932 Q_D(QObject);
933 d->wasDeleted = true;
934 d->blockSig = 0; // unblock signals so we always emit destroyed()
935
936 QtSharedPointer::ExternalRefCountData *sharedRefcount = d->sharedRefcount.load();
937 if (sharedRefcount) {
938 if (sharedRefcount->strongref.load() > 0) {
939 qWarning("QObject: shared QObject was deleted directly. The program is malformed and may crash.");
940 // but continue deleting, it's too late to stop anyway
941 }
942
943 // indicate to all QWeakPointers that this QObject has now been deleted
944 sharedRefcount->strongref.store(0);
945 if (!sharedRefcount->weakref.deref())
946 delete sharedRefcount;
947 }
948
949 if (!d->isWidget && d->isSignalConnected(0)) {
950 emit destroyed(this);
951 }
952
953 if (d->declarativeData) {
954 if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
955 if (QAbstractDeclarativeData::destroyed_qml1)
956 QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
957 } else {
958 if (QAbstractDeclarativeData::destroyed)
959 QAbstractDeclarativeData::destroyed(d->declarativeData, this);
960 }
961 }
962
963 QObjectPrivate::ConnectionData *cd = d->connections.load();
964 if (cd) {
965 if (cd->currentSender) {
966 cd->currentSender->receiverDeleted();
967 cd->currentSender = nullptr;
968 }
969
970 QBasicMutex *signalSlotMutex = signalSlotLock(this);
971 QBasicMutexLocker locker(signalSlotMutex);
972
973 // disconnect all receivers
974 int receiverCount = cd->signalVectorCount();
975 for (int signal = -1; signal < receiverCount; ++signal) {
976 QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal);
977
978 while (QObjectPrivate::Connection *c = connectionList.first.load()) {
979 Q_ASSERT(c->receiver);
980
981 QBasicMutex *m = signalSlotLock(c->receiver.load());
982 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
983 if (c->receiver) {
984 cd->removeConnection(c);
985 Q_ASSERT(connectionList.first.load() != c);
986 }
987 if (needToUnlock)
988 m->unlock();
989 }
990 }
991
992 /* Disconnect all senders:
993 */
994 while (QObjectPrivate::Connection *node = cd->senders) {
995 Q_ASSERT(node->receiver);
996 QObject *sender = node->sender;
997 // Send disconnectNotify before removing the connection from sender's connection list.
998 // This ensures any eventual destructor of sender will block on getting receiver's lock
999 // and not finish until we release it.
1000 sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
1001 QBasicMutex *m = signalSlotLock(sender);
1002 bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
1003 //the node has maybe been removed while the mutex was unlocked in relock?
1004 if (node != cd->senders) {
1005 // We hold the wrong mutex
1006 Q_ASSERT(needToUnlock);
1007 m->unlock();
1008 continue;
1009 }
1010
1011 QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load();
1012 Q_ASSERT(senderData);
1013
1014 QtPrivate::QSlotObjectBase *slotObj = nullptr;
1015 if (node->isSlotObject) {
1016 slotObj = node->slotObj;
1017 node->isSlotObject = false;
1018 }
1019
1020 senderData->removeConnection(node);
1021 if (needToUnlock)
1022 m->unlock();
1023
1024 if (slotObj) {
1025 locker.unlock();
1026 slotObj->destroyIfLastRef();
1027 locker.relock();
1028 }
1029 }
1030
1031 // invalidate all connections on the object and make sure
1032 // activate() will skip them
1033 cd->currentConnectionId.store(0);
1034 }
1035 if (cd && !cd->ref.deref())
1036 delete cd;
1037 d->connections.store(nullptr);
1038
1039 if (!d->children.isEmpty())
1040 d->deleteChildren();
1041
1042#if QT_VERSION < 0x60000
1043 qt_removeObject(this);
1044#endif
1045 if (Q_UNLIKELY(qtHookData[QHooks::RemoveQObject]))
1046 reinterpret_cast<QHooks::RemoveQObjectCallback>(qtHookData[QHooks::RemoveQObject])(this);
1047
1048 Q_TRACE(QObject_dtor, this);
1049
1050 if (d->parent) // remove it from parent object
1051 d->setParent_helper(0);
1052}
1053
1054QObjectPrivate::Connection::~Connection()
1055{
1056 if (ownArgumentTypes) {
1057 const int *v = argumentTypes.load();
1058 if (v != &DIRECT_CONNECTION_ONLY)
1059 delete [] v;
1060 }
1061 if (isSlotObject)
1062 slotObj->destroyIfLastRef();
1063}
1064
1065
1066/*!
1067 \fn const QMetaObject *QObject::metaObject() const
1068
1069 Returns a pointer to the meta-object of this object.
1070
1071 A meta-object contains information about a class that inherits
1072 QObject, e.g. class name, superclass name, properties, signals and
1073 slots. Every QObject subclass that contains the Q_OBJECT macro will have a
1074 meta-object.
1075
1076 The meta-object information is required by the signal/slot
1077 connection mechanism and the property system. The inherits()
1078 function also makes use of the meta-object.
1079
1080 If you have no pointer to an actual object instance but still
1081 want to access the meta-object of a class, you can use \l
1082 staticMetaObject.
1083
1084 Example:
1085
1086 \snippet code/src_corelib_kernel_qobject.cpp 1
1087
1088 \sa staticMetaObject
1089*/
1090
1091/*!
1092 \variable QObject::staticMetaObject
1093
1094 This variable stores the meta-object for the class.
1095
1096 A meta-object contains information about a class that inherits
1097 QObject, e.g. class name, superclass name, properties, signals and
1098 slots. Every class that contains the Q_OBJECT macro will also have
1099 a meta-object.
1100
1101 The meta-object information is required by the signal/slot
1102 connection mechanism and the property system. The inherits()
1103 function also makes use of the meta-object.
1104
1105 If you have a pointer to an object, you can use metaObject() to
1106 retrieve the meta-object associated with that object.
1107
1108 Example:
1109
1110 \snippet code/src_corelib_kernel_qobject.cpp 2
1111
1112 \sa metaObject()
1113*/
1114
1115/*!
1116 \fn template <class T> T qobject_cast(QObject *object)
1117 \fn template <class T> T qobject_cast(const QObject *object)
1118 \relates QObject
1119
1120 Returns the given \a object cast to type T if the object is of type
1121 T (or of a subclass); otherwise returns 0. If \a object is 0 then
1122 it will also return 0.
1123
1124 The class T must inherit (directly or indirectly) QObject and be
1125 declared with the \l Q_OBJECT macro.
1126
1127 A class is considered to inherit itself.
1128
1129 Example:
1130
1131 \snippet code/src_corelib_kernel_qobject.cpp 3
1132
1133 The qobject_cast() function behaves similarly to the standard C++
1134 \c dynamic_cast(), with the advantages that it doesn't require
1135 RTTI support and it works across dynamic library boundaries.
1136
1137 qobject_cast() can also be used in conjunction with interfaces;
1138 see the \l{tools/plugandpaint/app}{Plug & Paint} example for details.
1139
1140 \warning If T isn't declared with the Q_OBJECT macro, this
1141 function's return value is undefined.
1142
1143 \sa QObject::inherits()
1144*/
1145
1146/*!
1147 \fn bool QObject::inherits(const char *className) const
1148
1149 Returns \c true if this object is an instance of a class that
1150 inherits \a className or a QObject subclass that inherits \a
1151 className; otherwise returns \c false.
1152
1153 A class is considered to inherit itself.
1154
1155 Example:
1156
1157 \snippet code/src_corelib_kernel_qobject.cpp 4
1158
1159 If you need to determine whether an object is an instance of a particular
1160 class for the purpose of casting it, consider using qobject_cast<Type *>(object)
1161 instead.
1162
1163 \sa metaObject(), qobject_cast()
1164*/
1165
1166/*!
1167 \property QObject::objectName
1168
1169 \brief the name of this object
1170
1171 You can find an object by name (and type) using findChild().
1172 You can find a set of objects with findChildren().
1173
1174 \snippet code/src_corelib_kernel_qobject.cpp 5
1175
1176 By default, this property contains an empty string.
1177
1178 \sa metaObject(), QMetaObject::className()
1179*/
1180
1181QString QObject::objectName() const
1182{
1183 Q_D(const QObject);
1184 return d->extraData ? d->extraData->objectName : QString();
1185}
1186
1187/*
1188 Sets the object's name to \a name.
1189*/
1190void QObject::setObjectName(const QString &name)
1191{
1192 Q_D(QObject);
1193 if (!d->extraData)
1194 d->extraData = new QObjectPrivate::ExtraData;
1195
1196 if (d->extraData->objectName != name) {
1197 d->extraData->objectName = name;
1198 emit objectNameChanged(d->extraData->objectName, QPrivateSignal());
1199 }
1200}
1201
1202/*! \fn void QObject::objectNameChanged(const QString &objectName)
1203
1204 This signal is emitted after the object's name has been changed. The new object name is passed as \a objectName.
1205
1206 \sa QObject::objectName
1207*/
1208
1209/*!
1210 \fn bool QObject::isWidgetType() const
1211
1212 Returns \c true if the object is a widget; otherwise returns \c false.
1213
1214 Calling this function is equivalent to calling
1215 \c{inherits("QWidget")}, except that it is much faster.
1216*/
1217
1218/*!
1219 \fn bool QObject::isWindowType() const
1220
1221 Returns \c true if the object is a window; otherwise returns \c false.
1222
1223 Calling this function is equivalent to calling
1224 \c{inherits("QWindow")}, except that it is much faster.
1225*/
1226
1227/*!
1228 This virtual function receives events to an object and should
1229 return true if the event \a e was recognized and processed.
1230
1231 The event() function can be reimplemented to customize the
1232 behavior of an object.
1233
1234 Make sure you call the parent event class implementation
1235 for all the events you did not handle.
1236
1237 Example:
1238
1239 \snippet code/src_corelib_kernel_qobject.cpp 52
1240
1241 \sa installEventFilter(), timerEvent(), QCoreApplication::sendEvent(),
1242 QCoreApplication::postEvent()
1243*/
1244
1245bool QObject::event(QEvent *e)
1246{
1247 switch (e->type()) {
1248 case QEvent::Timer:
1249 timerEvent((QTimerEvent*)e);
1250 break;
1251
1252 case QEvent::ChildAdded:
1253 case QEvent::ChildPolished:
1254 case QEvent::ChildRemoved:
1255 childEvent((QChildEvent*)e);
1256 break;
1257
1258 case QEvent::DeferredDelete:
1259 qDeleteInEventHandler(this);
1260 break;
1261
1262 case QEvent::MetaCall:
1263 {
1264 QAbstractMetaCallEvent *mce = static_cast<QAbstractMetaCallEvent*>(e);
1265
1266 if (!d_func()->connections.load()) {
1267 QBasicMutexLocker locker(signalSlotLock(this));
1268 d_func()->ensureConnectionData();
1269 }
1270 QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId());
1271
1272 mce->placeMetaCall(this);
1273 break;
1274 }
1275
1276 case QEvent::ThreadChange: {
1277 Q_D(QObject);
1278 QThreadData *threadData = d->threadData;
1279 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
1280 if (eventDispatcher) {
1281 QList<QAbstractEventDispatcher::TimerInfo> timers = eventDispatcher->registeredTimers(this);
1282 if (!timers.isEmpty()) {
1283 // do not to release our timer ids back to the pool (since the timer ids are moving to a new thread).
1284 eventDispatcher->unregisterTimers(this);
1285 QMetaObject::invokeMethod(this, "_q_reregisterTimers", Qt::QueuedConnection,
1286 Q_ARG(void*, (new QList<QAbstractEventDispatcher::TimerInfo>(timers))));
1287 }
1288 }
1289 break;
1290 }
1291
1292 default:
1293 if (e->type() >= QEvent::User) {
1294 customEvent(e);
1295 break;
1296 }
1297 return false;
1298 }
1299 return true;
1300}
1301
1302/*!
1303 \fn void QObject::timerEvent(QTimerEvent *event)
1304
1305 This event handler can be reimplemented in a subclass to receive
1306 timer events for the object.
1307
1308 QTimer provides a higher-level interface to the timer
1309 functionality, and also more general information about timers. The
1310 timer event is passed in the \a event parameter.
1311
1312 \sa startTimer(), killTimer(), event()
1313*/
1314
1315void QObject::timerEvent(QTimerEvent *)
1316{
1317}
1318
1319
1320/*!
1321 This event handler can be reimplemented in a subclass to receive
1322 child events. The event is passed in the \a event parameter.
1323
1324 QEvent::ChildAdded and QEvent::ChildRemoved events are sent to
1325 objects when children are added or removed. In both cases you can
1326 only rely on the child being a QObject, or if isWidgetType()
1327 returns \c true, a QWidget. (This is because, in the
1328 \l{QEvent::ChildAdded}{ChildAdded} case, the child is not yet
1329 fully constructed, and in the \l{QEvent::ChildRemoved}{ChildRemoved}
1330 case it might have been destructed already).
1331
1332 QEvent::ChildPolished events are sent to widgets when children
1333 are polished, or when polished children are added. If you receive
1334 a child polished event, the child's construction is usually
1335 completed. However, this is not guaranteed, and multiple polish
1336 events may be delivered during the execution of a widget's
1337 constructor.
1338
1339 For every child widget, you receive one
1340 \l{QEvent::ChildAdded}{ChildAdded} event, zero or more
1341 \l{QEvent::ChildPolished}{ChildPolished} events, and one
1342 \l{QEvent::ChildRemoved}{ChildRemoved} event.
1343
1344 The \l{QEvent::ChildPolished}{ChildPolished} event is omitted if
1345 a child is removed immediately after it is added. If a child is
1346 polished several times during construction and destruction, you
1347 may receive several child polished events for the same child,
1348 each time with a different virtual table.
1349
1350 \sa event()
1351*/
1352
1353void QObject::childEvent(QChildEvent * /* event */)
1354{
1355}
1356
1357
1358/*!
1359 This event handler can be reimplemented in a subclass to receive
1360 custom events. Custom events are user-defined events with a type
1361 value at least as large as the QEvent::User item of the
1362 QEvent::Type enum, and is typically a QEvent subclass. The event
1363 is passed in the \a event parameter.
1364
1365 \sa event(), QEvent
1366*/
1367void QObject::customEvent(QEvent * /* event */)
1368{
1369}
1370
1371
1372
1373/*!
1374 Filters events if this object has been installed as an event
1375 filter for the \a watched object.
1376
1377 In your reimplementation of this function, if you want to filter
1378 the \a event out, i.e. stop it being handled further, return
1379 true; otherwise return false.
1380
1381 Example:
1382 \snippet code/src_corelib_kernel_qobject.cpp 6
1383
1384 Notice in the example above that unhandled events are passed to
1385 the base class's eventFilter() function, since the base class
1386 might have reimplemented eventFilter() for its own internal
1387 purposes.
1388
1389 Some events, such as \l QEvent::ShortcutOverride must be explicitly
1390 accepted (by calling \l {QEvent::}{accept()} on them) in order to prevent
1391 propagation.
1392
1393 \warning If you delete the receiver object in this function, be
1394 sure to return true. Otherwise, Qt will forward the event to the
1395 deleted object and the program might crash.
1396
1397 \sa installEventFilter()
1398*/
1399
1400bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
1401{
1402 return false;
1403}
1404
1405/*!
1406 \fn bool QObject::signalsBlocked() const
1407
1408 Returns \c true if signals are blocked; otherwise returns \c false.
1409
1410 Signals are not blocked by default.
1411
1412 \sa blockSignals(), QSignalBlocker
1413*/
1414
1415/*!
1416 If \a block is true, signals emitted by this object are blocked
1417 (i.e., emitting a signal will not invoke anything connected to it).
1418 If \a block is false, no such blocking will occur.
1419
1420 The return value is the previous value of signalsBlocked().
1421
1422 Note that the destroyed() signal will be emitted even if the signals
1423 for this object have been blocked.
1424
1425 Signals emitted while being blocked are not buffered.
1426
1427 \sa signalsBlocked(), QSignalBlocker
1428*/
1429
1430bool QObject::blockSignals(bool block) Q_DECL_NOTHROW
1431{
1432 Q_D(QObject);
1433 bool previous = d->blockSig;
1434 d->blockSig = block;
1435 return previous;
1436}
1437
1438/*!
1439 Returns the thread in which the object lives.
1440
1441 \sa moveToThread()
1442*/
1443QThread *QObject::thread() const
1444{
1445 return d_func()->threadData->thread;
1446}
1447
1448/*!
1449 Changes the thread affinity for this object and its children. The
1450 object cannot be moved if it has a parent. Event processing will
1451 continue in the \a targetThread.
1452
1453 To move an object to the main thread, use QApplication::instance()
1454 to retrieve a pointer to the current application, and then use
1455 QApplication::thread() to retrieve the thread in which the
1456 application lives. For example:
1457
1458 \snippet code/src_corelib_kernel_qobject.cpp 7
1459
1460 If \a targetThread is zero, all event processing for this object
1461 and its children stops.
1462
1463 Note that all active timers for the object will be reset. The
1464 timers are first stopped in the current thread and restarted (with
1465 the same interval) in the \a targetThread. As a result, constantly
1466 moving an object between threads can postpone timer events
1467 indefinitely.
1468
1469 A QEvent::ThreadChange event is sent to this object just before
1470 the thread affinity is changed. You can handle this event to
1471 perform any special processing. Note that any new events that are
1472 posted to this object will be handled in the \a targetThread.
1473
1474 \warning This function is \e not thread-safe; the current thread
1475 must be same as the current thread affinity. In other words, this
1476 function can only "push" an object from the current thread to
1477 another thread, it cannot "pull" an object from any arbitrary
1478 thread to the current thread.
1479
1480 \sa thread()
1481 */
1482void QObject::moveToThread(QThread *targetThread)
1483{
1484 Q_D(QObject);
1485
1486 if (d->threadData->thread == targetThread) {
1487 // object is already in this thread
1488 return;
1489 }
1490
1491 if (d->parent != 0) {
1492 qWarning("QObject::moveToThread: Cannot move objects with a parent");
1493 return;
1494 }
1495 if (d->isWidget) {
1496 qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
1497 return;
1498 }
1499
1500 QThreadData *currentData = QThreadData::current();
1501 QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr;
1502 if (d->threadData->thread == 0 && currentData == targetData) {
1503 // one exception to the rule: we allow moving objects with no thread affinity to the current thread
1504 currentData = d->threadData;
1505 } else if (d->threadData != currentData) {
1506 qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n"
1507 "Cannot move to target thread (%p)\n",
1508 currentData->thread.load(), d->threadData->thread.load(), targetData ? targetData->thread.load() : nullptr);
1509
1510#ifdef Q_OS_MAC
1511 qWarning("You might be loading two sets of Qt binaries into the same process. "
1512 "Check that all plugins are compiled against the right Qt binaries. Export "
1513 "DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.");
1514#endif
1515
1516 return;
1517 }
1518
1519 // prepare to move
1520 d->moveToThread_helper();
1521
1522 if (!targetData)
1523 targetData = new QThreadData(0);
1524
1525 // make sure nobody adds/removes connections to this object while we're moving it
1526 QMutexLocker l(signalSlotLock(this));
1527
1528 QOrderedMutexLocker locker(&currentData->postEventList.mutex,
1529 &targetData->postEventList.mutex);
1530
1531 // keep currentData alive (since we've got it locked)
1532 currentData->ref();
1533
1534 // move the object
1535 d_func()->setThreadData_helper(currentData, targetData);
1536
1537 locker.unlock();
1538
1539 // now currentData can commit suicide if it wants to
1540 currentData->deref();
1541}
1542
1543void QObjectPrivate::moveToThread_helper()
1544{
1545 Q_Q(QObject);
1546 QEvent e(QEvent::ThreadChange);
1547 QCoreApplication::sendEvent(q, &e);
1548 for (int i = 0; i < children.size(); ++i) {
1549 QObject *child = children.at(i);
1550 child->d_func()->moveToThread_helper();
1551 }
1552}
1553
1554void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData)
1555{
1556 Q_Q(QObject);
1557
1558 // move posted events
1559 int eventsMoved = 0;
1560 for (int i = 0; i < currentData->postEventList.size(); ++i) {
1561 const QPostEvent &pe = currentData->postEventList.at(i);
1562 if (!pe.event)
1563 continue;
1564 if (pe.receiver == q) {
1565 // move this post event to the targetList
1566 targetData->postEventList.addEvent(pe);
1567 const_cast<QPostEvent &>(pe).event = 0;
1568 ++eventsMoved;
1569 }
1570 }
1571 if (eventsMoved > 0 && targetData->hasEventDispatcher()) {
1572 targetData->canWait = false;
1573 targetData->eventDispatcher.load()->wakeUp();
1574 }
1575
1576 // the current emitting thread shouldn't restore currentSender after calling moveToThread()
1577 ConnectionData *cd = connections.load();
1578 if (cd) {
1579 if (cd->currentSender) {
1580 cd->currentSender->receiverDeleted();
1581 cd->currentSender = nullptr;
1582 }
1583
1584 // adjust the receiverThreadId values in the Connections
1585 if (cd) {
1586 auto *c = cd->senders;
1587 while (c) {
1588 QObject *r = c->receiver.load();
1589 if (r) {
1590 Q_ASSERT(r == q);
1591 targetData->ref();
1592 QThreadData *old = c->receiverThreadData.load();
1593 if (old)
1594 old->deref();
1595 c->receiverThreadData.store(targetData);
1596 }
1597 c = c->next;
1598 }
1599 }
1600
1601 }
1602
1603 // set new thread data
1604 targetData->ref();
1605 threadData->deref();
1606 threadData = targetData;
1607
1608 for (int i = 0; i < children.size(); ++i) {
1609 QObject *child = children.at(i);
1610 child->d_func()->setThreadData_helper(currentData, targetData);
1611 }
1612}
1613
1614void QObjectPrivate::_q_reregisterTimers(void *pointer)
1615{
1616 Q_Q(QObject);
1617 QList<QAbstractEventDispatcher::TimerInfo> *timerList = reinterpret_cast<QList<QAbstractEventDispatcher::TimerInfo> *>(pointer);
1618 QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher.load();
1619 for (int i = 0; i < timerList->size(); ++i) {
1620 const QAbstractEventDispatcher::TimerInfo &ti = timerList->at(i);
1621 eventDispatcher->registerTimer(ti.timerId, ti.interval, ti.timerType, q);
1622 }
1623 delete timerList;
1624}
1625
1626
1627//
1628// The timer flag hasTimer is set when startTimer is called.
1629// It is not reset when killing the timer because more than
1630// one timer might be active.
1631//
1632
1633/*!
1634 Starts a timer and returns a timer identifier, or returns zero if
1635 it could not start a timer.
1636
1637 A timer event will occur every \a interval milliseconds until
1638 killTimer() is called. If \a interval is 0, then the timer event
1639 occurs once every time there are no more window system events to
1640 process.
1641
1642 The virtual timerEvent() function is called with the QTimerEvent
1643 event parameter class when a timer event occurs. Reimplement this
1644 function to get timer events.
1645
1646 If multiple timers are running, the QTimerEvent::timerId() can be
1647 used to find out which timer was activated.
1648
1649 Example:
1650
1651 \snippet code/src_corelib_kernel_qobject.cpp 8
1652
1653 Note that QTimer's accuracy depends on the underlying operating system and
1654 hardware. The \a timerType argument allows you to customize the accuracy of
1655 the timer. See Qt::TimerType for information on the different timer types.
1656 Most platforms support an accuracy of 20 milliseconds; some provide more.
1657 If Qt is unable to deliver the requested number of timer events, it will
1658 silently discard some.
1659
1660 The QTimer class provides a high-level programming interface with
1661 single-shot timers and timer signals instead of events. There is
1662 also a QBasicTimer class that is more lightweight than QTimer and
1663 less clumsy than using timer IDs directly.
1664
1665 \sa timerEvent(), killTimer(), QTimer::singleShot()
1666*/
1667
1668int QObject::startTimer(int interval, Qt::TimerType timerType)
1669{
1670 Q_D(QObject);
1671
1672 if (Q_UNLIKELY(interval < 0)) {
1673 qWarning("QObject::startTimer: Timers cannot have negative intervals");
1674 return 0;
1675 }
1676 if (Q_UNLIKELY(!d->threadData->hasEventDispatcher())) {
1677 qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");
1678 return 0;
1679 }
1680 if (Q_UNLIKELY(thread() != QThread::currentThread())) {
1681 qWarning("QObject::startTimer: Timers cannot be started from another thread");
1682 return 0;
1683 }
1684 int timerId = d->threadData->eventDispatcher.load()->registerTimer(interval, timerType, this);
1685 if (!d->extraData)
1686 d->extraData = new QObjectPrivate::ExtraData;
1687 d->extraData->runningTimers.append(timerId);
1688 return timerId;
1689}
1690
1691/*!
1692 \since 5.9
1693 \overload
1694 \fn int QObject::startTimer(std::chrono::milliseconds time, Qt::TimerType timerType)
1695
1696 Starts a timer and returns a timer identifier, or returns zero if
1697 it could not start a timer.
1698
1699 A timer event will occur every \a time interval until killTimer()
1700 is called. If \a time is equal to \c{std::chrono::duration::zero()},
1701 then the timer event occurs once every time there are no more window
1702 system events to process.
1703
1704 The virtual timerEvent() function is called with the QTimerEvent
1705 event parameter class when a timer event occurs. Reimplement this
1706 function to get timer events.
1707
1708 If multiple timers are running, the QTimerEvent::timerId() can be
1709 used to find out which timer was activated.
1710
1711 Example:
1712
1713 \snippet code/src_corelib_kernel_qobject.cpp 8
1714
1715 Note that QTimer's accuracy depends on the underlying operating system and
1716 hardware. The \a timerType argument allows you to customize the accuracy of
1717 the timer. See Qt::TimerType for information on the different timer types.
1718 Most platforms support an accuracy of 20 milliseconds; some provide more.
1719 If Qt is unable to deliver the requested number of timer events, it will
1720 silently discard some.
1721
1722 The QTimer class provides a high-level programming interface with
1723 single-shot timers and timer signals instead of events. There is
1724 also a QBasicTimer class that is more lightweight than QTimer and
1725 less clumsy than using timer IDs directly.
1726
1727 \sa timerEvent(), killTimer(), QTimer::singleShot()
1728*/
1729
1730/*!
1731 Kills the timer with timer identifier, \a id.
1732
1733 The timer identifier is returned by startTimer() when a timer
1734 event is started.
1735
1736 \sa timerEvent(), startTimer()
1737*/
1738
1739void QObject::killTimer(int id)
1740{
1741 Q_D(QObject);
1742 if (Q_UNLIKELY(thread() != QThread::currentThread())) {
1743 qWarning("QObject::killTimer: Timers cannot be stopped from another thread");
1744 return;
1745 }
1746 if (id) {
1747 int at = d->extraData ? d->extraData->runningTimers.indexOf(id) : -1;
1748 if (at == -1) {
1749 // timer isn't owned by this object
1750 qWarning("QObject::killTimer(): Error: timer id %d is not valid for object %p (%s, %s), timer has not been killed",
1751 id,
1752 this,
1753 metaObject()->className(),
1754 qPrintable(objectName()));
1755 return;
1756 }
1757
1758 if (d->threadData->hasEventDispatcher())
1759 d->threadData->eventDispatcher.load()->unregisterTimer(id);
1760
1761 d->extraData->runningTimers.remove(at);
1762 QAbstractEventDispatcherPrivate::releaseTimerId(id);
1763 }
1764}
1765
1766
1767/*!
1768 \fn QObject *QObject::parent() const
1769
1770 Returns a pointer to the parent object.
1771
1772 \sa children()
1773*/
1774
1775/*!
1776 \fn const QObjectList &QObject::children() const
1777
1778 Returns a list of child objects.
1779 The QObjectList class is defined in the \c{<QObject>} header
1780 file as the following:
1781
1782 \quotefromfile kernel/qobject.h
1783 \skipto /typedef .*QObjectList/
1784 \printuntil QObjectList
1785
1786 The first child added is the \l{QList::first()}{first} object in
1787 the list and the last child added is the \l{QList::last()}{last}
1788 object in the list, i.e. new children are appended at the end.
1789
1790 Note that the list order changes when QWidget children are
1791 \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A
1792 widget that is raised becomes the last object in the list, and a
1793 widget that is lowered becomes the first object in the list.
1794
1795 \sa findChild(), findChildren(), parent(), setParent()
1796*/
1797
1798
1799/*!
1800 \fn template<typename T> T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
1801
1802 Returns the child of this object that can be cast into type T and
1803 that is called \a name, or \nullptr if there is no such object.
1804 Omitting the \a name argument causes all object names to be matched.
1805 The search is performed recursively, unless \a options specifies the
1806 option FindDirectChildrenOnly.
1807
1808 If there is more than one child matching the search, the most
1809 direct ancestor is returned. If there are several direct
1810 ancestors, it is undefined which one will be returned. In that
1811 case, findChildren() should be used.
1812
1813 This example returns a child \c{QPushButton} of \c{parentWidget}
1814 named \c{"button1"}, even if the button isn't a direct child of
1815 the parent:
1816
1817 \snippet code/src_corelib_kernel_qobject.cpp 10
1818
1819 This example returns a \c{QListWidget} child of \c{parentWidget}:
1820
1821 \snippet code/src_corelib_kernel_qobject.cpp 11
1822
1823 This example returns a child \c{QPushButton} of \c{parentWidget}
1824 (its direct parent) named \c{"button1"}:
1825
1826 \snippet code/src_corelib_kernel_qobject.cpp 41
1827
1828 This example returns a \c{QListWidget} child of \c{parentWidget},
1829 its direct parent:
1830
1831 \snippet code/src_corelib_kernel_qobject.cpp 42
1832
1833 \sa findChildren()
1834*/
1835
1836/*!
1837 \fn template<typename T> QList<T> QObject::findChildren(const QString &name, Qt::FindChildOptions options) const
1838
1839 Returns all children of this object with the given \a name that can be
1840 cast to type T, or an empty list if there are no such objects.
1841 Omitting the \a name argument causes all object names to be matched.
1842 The search is performed recursively, unless \a options specifies the
1843 option FindDirectChildrenOnly.
1844
1845 The following example shows how to find a list of child \c{QWidget}s of
1846 the specified \c{parentWidget} named \c{widgetname}:
1847
1848 \snippet code/src_corelib_kernel_qobject.cpp 12
1849
1850 This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
1851
1852 \snippet code/src_corelib_kernel_qobject.cpp 13
1853
1854 This example returns all \c{QPushButton}s that are immediate children of \c{parentWidget}:
1855
1856 \snippet code/src_corelib_kernel_qobject.cpp 43
1857
1858 \sa findChild()
1859*/
1860
1861/*!
1862 \fn template<typename T> QList<T> QObject::findChildren(const QRegExp &regExp, Qt::FindChildOptions options) const
1863 \overload findChildren()
1864 \obsolete
1865
1866 Returns the children of this object that can be cast to type T
1867 and that have names matching the regular expression \a regExp,
1868 or an empty list if there are no such objects.
1869 The search is performed recursively, unless \a options specifies the
1870 option FindDirectChildrenOnly.
1871
1872 Use the findChildren overload taking a QRegularExpression instead.
1873*/
1874
1875/*!
1876 \fn QList<T> QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options) const
1877 \overload findChildren()
1878
1879 \since 5.0
1880
1881 Returns the children of this object that can be cast to type T
1882 and that have names matching the regular expression \a re,
1883 or an empty list if there are no such objects.
1884 The search is performed recursively, unless \a options specifies the
1885 option FindDirectChildrenOnly.
1886*/
1887
1888/*!
1889 \fn template<typename T> T qFindChild(const QObject *obj, const QString &name)
1890 \relates QObject
1891 \overload qFindChildren()
1892 \obsolete
1893
1894 This function is equivalent to
1895 \a{obj}->\l{QObject::findChild()}{findChild}<T>(\a name).
1896
1897 \note This function was provided as a workaround for MSVC 6
1898 which did not support member template functions. It is advised
1899 to use the other form in new code.
1900
1901 \sa QObject::findChild()
1902*/
1903
1904/*!
1905 \fn template<typename T> QList<T> qFindChildren(const QObject *obj, const QString &name)
1906 \relates QObject
1907 \overload qFindChildren()
1908 \obsolete
1909
1910 This function is equivalent to
1911 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a name).
1912
1913 \note This function was provided as a workaround for MSVC 6
1914 which did not support member template functions. It is advised
1915 to use the other form in new code.
1916
1917 \sa QObject::findChildren()
1918*/
1919
1920/*!
1921 \fn template<typename T> QList<T> qFindChildren(const QObject *obj, const QRegExp &regExp)
1922 \relates QObject
1923 \overload qFindChildren()
1924
1925 This function is equivalent to
1926 \a{obj}->\l{QObject::findChildren()}{findChildren}<T>(\a regExp).
1927
1928 \note This function was provided as a workaround for MSVC 6
1929 which did not support member template functions. It is advised
1930 to use the other form in new code.
1931
1932 \sa QObject::findChildren()
1933*/
1934
1935/*!
1936 \internal
1937*/
1938void qt_qFindChildren_helper(const QObject *parent, const QString &name,
1939 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1940{
1941 if (!parent || !list)
1942 return;
1943 const QObjectList &children = parent->children();
1944 QObject *obj;
1945 for (int i = 0; i < children.size(); ++i) {
1946 obj = children.at(i);
1947 if (mo.cast(obj)) {
1948 if (name.isNull() || obj->objectName() == name)
1949 list->append(obj);
1950 }
1951 if (options & Qt::FindChildrenRecursively)
1952 qt_qFindChildren_helper(obj, name, mo, list, options);
1953 }
1954}
1955
1956#ifndef QT_NO_REGEXP
1957/*!
1958 \internal
1959*/
1960void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
1961 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1962{
1963 if (!parent || !list)
1964 return;
1965 const QObjectList &children = parent->children();
1966 QRegExp reCopy = re;
1967 QObject *obj;
1968 for (int i = 0; i < children.size(); ++i) {
1969 obj = children.at(i);
1970 if (mo.cast(obj) && reCopy.indexIn(obj->objectName()) != -1)
1971 list->append(obj);
1972
1973 if (options & Qt::FindChildrenRecursively)
1974 qt_qFindChildren_helper(obj, re, mo, list, options);
1975 }
1976}
1977#endif // QT_NO_REGEXP
1978
1979#if QT_CONFIG(regularexpression)
1980/*!
1981 \internal
1982*/
1983void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
1984 const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
1985{
1986 if (!parent || !list)
1987 return;
1988 const QObjectList &children = parent->children();
1989 QObject *obj;
1990 for (int i = 0; i < children.size(); ++i) {
1991 obj = children.at(i);
1992 if (mo.cast(obj)) {
1993 QRegularExpressionMatch m = re.match(obj->objectName());
1994 if (m.hasMatch())
1995 list->append(obj);
1996 }
1997 if (options & Qt::FindChildrenRecursively)
1998 qt_qFindChildren_helper(obj, re, mo, list, options);
1999 }
2000}
2001#endif // QT_CONFIG(regularexpression)
2002
2003/*!
2004 \internal
2005 */
2006QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
2007{
2008 if (!parent)
2009 return 0;
2010 const QObjectList &children = parent->children();
2011 QObject *obj;
2012 int i;
2013 for (i = 0; i < children.size(); ++i) {
2014 obj = children.at(i);
2015 if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
2016 return obj;
2017 }
2018 if (options & Qt::FindChildrenRecursively) {
2019 for (i = 0; i < children.size(); ++i) {
2020 obj = qt_qFindChild_helper(children.at(i), name, mo, options);
2021 if (obj)
2022 return obj;
2023 }
2024 }
2025 return 0;
2026}
2027
2028/*!
2029 Makes the object a child of \a parent.
2030
2031 \sa parent(), children()
2032*/
2033void QObject::setParent(QObject *parent)
2034{
2035 Q_D(QObject);
2036 Q_ASSERT(!d->isWidget);
2037 d->setParent_helper(parent);
2038}
2039
2040void QObjectPrivate::deleteChildren()
2041{
2042 Q_ASSERT_X(!isDeletingChildren, "QObjectPrivate::deleteChildren()", "isDeletingChildren already set, did this function recurse?");
2043 isDeletingChildren = true;
2044 // delete children objects
2045 // don't use qDeleteAll as the destructor of the child might
2046 // delete siblings
2047 for (int i = 0; i < children.count(); ++i) {
2048 currentChildBeingDeleted = children.at(i);
2049 children[i] = 0;
2050 delete currentChildBeingDeleted;
2051 }
2052 children.clear();
2053 currentChildBeingDeleted = 0;
2054 isDeletingChildren = false;
2055}
2056
2057void QObjectPrivate::setParent_helper(QObject *o)
2058{
2059 Q_Q(QObject);
2060 if (o == parent)
2061 return;
2062 if (parent) {
2063 QObjectPrivate *parentD = parent->d_func();
2064 if (parentD->isDeletingChildren && wasDeleted
2065 && parentD->currentChildBeingDeleted == q) {
2066 // don't do anything since QObjectPrivate::deleteChildren() already
2067 // cleared our entry in parentD->children.
2068 } else {
2069 const int index = parentD->children.indexOf(q);
2070 if (parentD->isDeletingChildren) {
2071 parentD->children[index] = 0;
2072 } else {
2073 parentD->children.removeAt(index);
2074 if (sendChildEvents && parentD->receiveChildEvents) {
2075 QChildEvent e(QEvent::ChildRemoved, q);
2076 QCoreApplication::sendEvent(parent, &e);
2077 }
2078 }
2079 }
2080 }
2081 parent = o;
2082 if (parent) {
2083 // object hierarchies are constrained to a single thread
2084 if (threadData != parent->d_func()->threadData) {
2085 qWarning("QObject::setParent: Cannot set parent, new parent is in a different thread");
2086 parent = 0;
2087 return;
2088 }
2089 parent->d_func()->children.append(q);
2090 if(sendChildEvents && parent->d_func()->receiveChildEvents) {
2091 if (!isWidget) {
2092 QChildEvent e(QEvent::ChildAdded, q);
2093 QCoreApplication::sendEvent(parent, &e);
2094 }
2095 }
2096 }
2097 if (!wasDeleted && !isDeletingChildren && declarativeData && QAbstractDeclarativeData::parentChanged)
2098 QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
2099}
2100
2101/*!
2102 \fn void QObject::installEventFilter(QObject *filterObj)
2103
2104 Installs an event filter \a filterObj on this object. For example:
2105 \snippet code/src_corelib_kernel_qobject.cpp 14
2106
2107 An event filter is an object that receives all events that are
2108 sent to this object. The filter can either stop the event or
2109 forward it to this object. The event filter \a filterObj receives
2110 events via its eventFilter() function. The eventFilter() function
2111 must return true if the event should be filtered, (i.e. stopped);
2112 otherwise it must return false.
2113
2114 If multiple event filters are installed on a single object, the
2115 filter that was installed last is activated first.
2116
2117 Here's a \c KeyPressEater class that eats the key presses of its
2118 monitored objects:
2119
2120 \snippet code/src_corelib_kernel_qobject.cpp 15
2121
2122 And here's how to install it on two widgets:
2123
2124 \snippet code/src_corelib_kernel_qobject.cpp 16
2125
2126 The QShortcut class, for example, uses this technique to intercept
2127 shortcut key presses.
2128
2129 \warning If you delete the receiver object in your eventFilter()
2130 function, be sure to return true. If you return false, Qt sends
2131 the event to the deleted object and the program will crash.
2132
2133 Note that the filtering object must be in the same thread as this
2134 object. If \a filterObj is in a different thread, this function does
2135 nothing. If either \a filterObj or this object are moved to a different
2136 thread after calling this function, the event filter will not be
2137 called until both objects have the same thread affinity again (it
2138 is \e not removed).
2139
2140 \sa removeEventFilter(), eventFilter(), event()
2141*/
2142
2143void QObject::installEventFilter(QObject *obj)
2144{
2145 Q_D(QObject);
2146 if (!obj)
2147 return;
2148 if (d->threadData != obj->d_func()->threadData) {
2149 qWarning("QObject::installEventFilter(): Cannot filter events for objects in a different thread.");
2150 return;
2151 }
2152
2153 if (!d->extraData)
2154 d->extraData = new QObjectPrivate::ExtraData;
2155
2156 // clean up unused items in the list
2157 d->extraData->eventFilters.removeAll((QObject*)0);
2158 d->extraData->eventFilters.removeAll(obj);
2159 d->extraData->eventFilters.prepend(obj);
2160}
2161
2162/*!
2163 Removes an event filter object \a obj from this object. The
2164 request is ignored if such an event filter has not been installed.
2165
2166 All event filters for this object are automatically removed when
2167 this object is destroyed.
2168
2169 It is always safe to remove an event filter, even during event
2170 filter activation (i.e. from the eventFilter() function).
2171
2172 \sa installEventFilter(), eventFilter(), event()
2173*/
2174
2175void QObject::removeEventFilter(QObject *obj)
2176{
2177 Q_D(QObject);
2178 if (d->extraData) {
2179 for (int i = 0; i < d->extraData->eventFilters.count(); ++i) {
2180 if (d->extraData->eventFilters.at(i) == obj)
2181 d->extraData->eventFilters[i] = 0;
2182 }
2183 }
2184}
2185
2186
2187/*!
2188 \fn void QObject::destroyed(QObject *obj)
2189
2190 This signal is emitted immediately before the object \a obj is
2191 destroyed, after any instances of QPointer have been notified,
2192 and cannot be blocked.
2193
2194 All the objects's children are destroyed immediately after this
2195 signal is emitted.
2196
2197 \sa deleteLater(), QPointer
2198*/
2199
2200/*!
2201 Schedules this object for deletion.
2202
2203 The object will be deleted when control returns to the event
2204 loop. If the event loop is not running when this function is
2205 called (e.g. deleteLater() is called on an object before
2206 QCoreApplication::exec()), the object will be deleted once the
2207 event loop is started. If deleteLater() is called after the main event loop
2208 has stopped, the object will not be deleted.
2209 Since Qt 4.8, if deleteLater() is called on an object that lives in a
2210 thread with no running event loop, the object will be destroyed when the
2211 thread finishes.
2212
2213 Note that entering and leaving a new event loop (e.g., by opening a modal
2214 dialog) will \e not perform the deferred deletion; for the object to be
2215 deleted, the control must return to the event loop from which deleteLater()
2216 was called. This does not apply to objects deleted while a previous, nested
2217 event loop was still running: the Qt event loop will delete those objects
2218 as soon as the new nested event loop starts.
2219
2220 \b{Note:} It is safe to call this function more than once; when the
2221 first deferred deletion event is delivered, any pending events for the
2222 object are removed from the event queue.
2223
2224 \sa destroyed(), QPointer
2225*/
2226void QObject::deleteLater()
2227{
2228 QCoreApplication::postEvent(this, new QDeferredDeleteEvent());
2229}
2230
2231/*!
2232 \fn QString QObject::tr(const char *sourceText, const char *disambiguation, int n)
2233 \reentrant
2234
2235 Returns a translated version of \a sourceText, optionally based on a
2236 \a disambiguation string and value of \a n for strings containing plurals;
2237 otherwise returns QString::fromUtf8(\a sourceText) if no appropriate
2238 translated string is available.
2239
2240 Example:
2241 \snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context
2242 \dots
2243
2244 If the same \a sourceText is used in different roles within the
2245 same context, an additional identifying string may be passed in
2246 \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
2247 the preferred way to pass comments to translators.
2248
2249 Example:
2250
2251 \snippet code/src_corelib_kernel_qobject.cpp 17
2252 \dots
2253
2254 See \l{Writing Source Code for Translation} for a detailed description of
2255 Qt's translation mechanisms in general, and the
2256 \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
2257 section for information on disambiguation.
2258
2259 \warning This method is reentrant only if all translators are
2260 installed \e before calling this method. Installing or removing
2261 translators while performing translations is not supported. Doing
2262 so will probably result in crashes or other undesirable behavior.
2263
2264 \sa QCoreApplication::translate(), {Internationalization with Qt}
2265*/
2266
2267/*!
2268 \fn QString QObject::trUtf8(const char *sourceText, const char *disambiguation, int n)
2269 \reentrant
2270 \obsolete
2271
2272 Returns a translated version of \a sourceText, or
2273 QString::fromUtf8(\a sourceText) if there is no appropriate
2274 version. It is otherwise identical to tr(\a sourceText, \a
2275 disambiguation, \a n).
2276
2277 \warning This method is reentrant only if all translators are
2278 installed \e before calling this method. Installing or removing
2279 translators while performing translations is not supported. Doing
2280 so will probably result in crashes or other undesirable behavior.
2281
2282 \warning For portability reasons, we recommend that you use
2283 escape sequences for specifying non-ASCII characters in string
2284 literals to trUtf8(). For example:
2285
2286 \snippet code/src_corelib_kernel_qobject.cpp 20
2287
2288 \sa tr(), QCoreApplication::translate(), {Internationalization with Qt}
2289*/
2290
2291
2292
2293
2294/*****************************************************************************
2295 Signals and slots
2296 *****************************************************************************/
2297
2298
2299const char *qFlagLocation(const char *method)
2300{
2301 QThreadData *currentThreadData = QThreadData::current(false);
2302 if (currentThreadData != 0)
2303 currentThreadData->flaggedSignatures.store(method);
2304 return method;
2305}
2306
2307static int extract_code(const char *member)
2308{
2309 // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE
2310 return (((int)(*member) - '0') & 0x3);
2311}
2312
2313static const char * extract_location(const char *member)
2314{
2315 if (QThreadData::current()->flaggedSignatures.contains(member)) {
2316 // signature includes location information after the first null-terminator
2317 const char *location = member + qstrlen(member) + 1;
2318 if (*location != '\0')
2319 return location;
2320 }
2321 return 0;
2322}
2323
2324static bool check_signal_macro(const QObject *sender, const char *signal,
2325 const char *func, const char *op)
2326{
2327 int sigcode = extract_code(signal);
2328 if (sigcode != QSIGNAL_CODE) {
2329 if (sigcode == QSLOT_CODE)
2330 qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
2331 func, op, sender->metaObject()->className(), signal+1);
2332 else
2333 qWarning("QObject::%s: Use the SIGNAL macro to %s %s::%s",
2334 func, op, sender->metaObject()->className(), signal);
2335 return false;
2336 }
2337 return true;
2338}
2339
2340static bool check_method_code(int code, const QObject *object,
2341 const char *method, const char *func)
2342{
2343 if (code != QSLOT_CODE && code != QSIGNAL_CODE) {
2344 qWarning("QObject::%s: Use the SLOT or SIGNAL macro to "
2345 "%s %s::%s", func, func, object->metaObject()->className(), method);
2346 return false;
2347 }
2348 return true;
2349}
2350
2351static void err_method_notfound(const QObject *object,
2352 const char *method, const char *func)
2353{
2354 const char *type = "method";
2355 switch (extract_code(method)) {
2356 case QSLOT_CODE: type = "slot"; break;
2357 case QSIGNAL_CODE: type = "signal"; break;
2358 }
2359 const char *loc = extract_location(method);
2360 if (strchr(method,')') == 0) // common typing mistake
2361 qWarning("QObject::%s: Parentheses expected, %s %s::%s%s%s",
2362 func, type, object->metaObject()->className(), method+1,
2363 loc ? " in ": "", loc ? loc : "");
2364 else
2365 qWarning("QObject::%s: No such %s %s::%s%s%s",
2366 func, type, object->metaObject()->className(), method+1,
2367 loc ? " in ": "", loc ? loc : "");
2368
2369}
2370
2371
2372static void err_info_about_objects(const char * func,
2373 const QObject * sender,
2374 const QObject * receiver)
2375{
2376 QString a = sender ? sender->objectName() : QString();
2377 QString b = receiver ? receiver->objectName() : QString();
2378 if (!a.isEmpty())
2379 qWarning("QObject::%s: (sender name: '%s')", func, a.toLocal8Bit().data());
2380 if (!b.isEmpty())
2381 qWarning("QObject::%s: (receiver name: '%s')", func, b.toLocal8Bit().data());
2382}
2383
2384/*!
2385 Returns a pointer to the object that sent the signal, if called in
2386 a slot activated by a signal; otherwise it returns 0. The pointer
2387 is valid only during the execution of the slot that calls this
2388 function from this object's thread context.
2389
2390 The pointer returned by this function becomes invalid if the
2391 sender is destroyed, or if the slot is disconnected from the
2392 sender's signal.
2393
2394 \warning This function violates the object-oriented principle of
2395 modularity. However, getting access to the sender might be useful
2396 when many signals are connected to a single slot.
2397
2398 \warning As mentioned above, the return value of this function is
2399 not valid when the slot is called via a Qt::DirectConnection from
2400 a thread different from this object's thread. Do not use this
2401 function in this type of scenario.
2402
2403 \sa senderSignalIndex()
2404*/
2405
2406QObject *QObject::sender() const
2407{
2408 Q_D(const QObject);
2409
2410 QBasicMutexLocker locker(signalSlotLock(this));
2411 QObjectPrivate::ConnectionData *cd = d->connections.load();
2412 if (!cd || !cd->currentSender)
2413 return nullptr;
2414
2415 for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
2416 if (c->sender == cd->currentSender->sender)
2417 return cd->currentSender->sender;
2418 }
2419
2420 return 0;
2421}
2422
2423/*!
2424 \since 4.8
2425
2426 Returns the meta-method index of the signal that called the currently
2427 executing slot, which is a member of the class returned by sender().
2428 If called outside of a slot activated by a signal, -1 is returned.
2429
2430 For signals with default parameters, this function will always return
2431 the index with all parameters, regardless of which was used with
2432 connect(). For example, the signal \c {destroyed(QObject *obj = 0)}
2433 will have two different indexes (with and without the parameter), but
2434 this function will always return the index with a parameter. This does
2435 not apply when overloading signals with different parameters.
2436
2437 \warning This function violates the object-oriented principle of
2438 modularity. However, getting access to the signal index might be useful
2439 when many signals are connected to a single slot.
2440
2441 \warning The return value of this function is not valid when the slot
2442 is called via a Qt::DirectConnection from a thread different from this
2443 object's thread. Do not use this function in this type of scenario.
2444
2445 \sa sender(), QMetaObject::indexOfSignal(), QMetaObject::method()
2446*/
2447
2448int QObject::senderSignalIndex() const
2449{
2450 Q_D(const QObject);
2451
2452 QBasicMutexLocker locker(signalSlotLock(this));
2453 QObjectPrivate::ConnectionData *cd = d->connections.load();
2454 if (!cd || !cd->currentSender)
2455 return -1;
2456
2457 for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
2458 if (c->sender == cd->currentSender->sender) {
2459 // Convert from signal range to method range
2460 return QMetaObjectPrivate::signal(c->sender->metaObject(), cd->currentSender->signal).methodIndex();
2461 }
2462 }
2463
2464 return -1;
2465}
2466
2467/*!
2468 Returns the number of receivers connected to the \a signal.
2469
2470 Since both slots and signals can be used as receivers for signals,
2471 and the same connections can be made many times, the number of
2472 receivers is the same as the number of connections made from this
2473 signal.
2474
2475 When calling this function, you can use the \c SIGNAL() macro to
2476 pass a specific signal:
2477
2478 \snippet code/src_corelib_kernel_qobject.cpp 21
2479
2480 \warning This function violates the object-oriented principle of
2481 modularity. However, it might be useful when you need to perform
2482 expensive initialization only if something is connected to a
2483 signal.
2484
2485 \sa isSignalConnected()
2486*/
2487
2488int QObject::receivers(const char *signal) const
2489{
2490 Q_D(const QObject);
2491 int receivers = 0;
2492 if (signal) {
2493 QByteArray signal_name = QMetaObject::normalizedSignature(signal);
2494 signal = signal_name;
2495#ifndef QT_NO_DEBUG
2496 if (!check_signal_macro(this, signal, "receivers", "bind"))
2497 return 0;
2498#endif
2499 signal++; // skip code
2500 int signal_index = d->signalIndex(signal);
2501 if (signal_index < 0) {
2502#ifndef QT_NO_DEBUG
2503 err_method_notfound(this, signal-1, "receivers");
2504#endif
2505 return 0;
2506 }
2507
2508 if (!d->isSignalConnected(signal_index))
2509 return receivers;
2510
2511 if (d->declarativeData && QAbstractDeclarativeData::receivers) {
2512 receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
2513 signal_index);
2514 }
2515
2516 QObjectPrivate::ConnectionData *cd = d->connections.load();
2517 QBasicMutexLocker locker(signalSlotLock(this));
2518 if (cd && signal_index < cd->signalVectorCount()) {
2519 const QObjectPrivate::Connection *c = cd->signalVector.load()->at(signal_index).first.load();
2520 while (c) {
2521 receivers += c->receiver.load() ? 1 : 0;
2522 c = c->nextConnectionList.load();
2523 }
2524 }
2525 }
2526 return receivers;
2527}
2528
2529/*!
2530 \since 5.0
2531 Returns \c true if the \a signal is connected to at least one receiver,
2532 otherwise returns \c false.
2533
2534 \a signal must be a signal member of this object, otherwise the behaviour
2535 is undefined.
2536
2537 \snippet code/src_corelib_kernel_qobject.cpp 49
2538
2539 As the code snippet above illustrates, you can use this function
2540 to avoid emitting a signal that nobody listens to.
2541
2542 \warning This function violates the object-oriented principle of
2543 modularity. However, it might be useful when you need to perform
2544 expensive initialization only if something is connected to a
2545 signal.
2546*/
2547bool QObject::isSignalConnected(const QMetaMethod &signal) const
2548{
2549 Q_D(const QObject);
2550 if (!signal.mobj)
2551 return false;
2552
2553 Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
2554 "QObject::isSignalConnected" , "the parameter must be a signal member of the object");
2555 uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/5;
2556
2557 if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
2558 signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
2559
2560 signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj);
2561
2562 QBasicMutexLocker locker(signalSlotLock(this));
2563 return d->isSignalConnected(signalIndex, true);
2564}
2565
2566/*!
2567 \internal
2568
2569 This helper function calculates signal and method index for the given
2570 member in the specified class.
2571
2572 \list
2573 \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
2574
2575 \li If specified member is not a member of obj instance class (or one of
2576 its parent classes) then both signalIndex and methodIndex are set to -1.
2577 \endlist
2578
2579 This function is used by QObject::connect and QObject::disconnect which
2580 are working with QMetaMethod.
2581
2582 \a signalIndex is set to the signal index of member. If the member
2583 specified is not signal this variable is set to -1.
2584
2585 \a methodIndex is set to the method index of the member. If the
2586 member is not a method of the object specified by the \a obj argument this
2587 variable is set to -1.
2588*/
2589void QMetaObjectPrivate::memberIndexes(const QObject *obj,
2590 const QMetaMethod &member,
2591 int *signalIndex, int *methodIndex)
2592{
2593 *signalIndex = -1;
2594 *methodIndex = -1;
2595 if (!obj || !member.mobj)
2596 return;
2597 const QMetaObject *m = obj->metaObject();
2598 // Check that member is member of obj class
2599 while (m != 0 && m != member.mobj)
2600 m = m->d.superdata;
2601 if (!m)
2602 return;
2603 *signalIndex = *methodIndex = (member.handle - get(member.mobj)->methodData)/5;
2604
2605 int signalOffset;
2606 int methodOffset;
2607 computeOffsets(m, &signalOffset, &methodOffset);
2608
2609 *methodIndex += methodOffset;
2610 if (member.methodType() == QMetaMethod::Signal) {
2611 *signalIndex = originalClone(m, *signalIndex);
2612 *signalIndex += signalOffset;
2613 } else {
2614 *signalIndex = -1;
2615 }
2616}
2617
2618#ifndef QT_NO_DEBUG
2619static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaMethod &signal,
2620 const QMetaObject *receiver, const QMetaMethod &method)
2621{
2622 if (signal.attributes() & QMetaMethod::Compatibility) {
2623 if (!(method.attributes() & QMetaMethod::Compatibility))
2624 qWarning("QObject::connect: Connecting from COMPAT signal (%s::%s)",
2625 sender->className(), signal.methodSignature().constData());
2626 } else if ((method.attributes() & QMetaMethod::Compatibility) &&
2627 method.methodType() == QMetaMethod::Signal) {
2628 qWarning("QObject::connect: Connecting from %s::%s to COMPAT slot (%s::%s)",
2629 sender->className(), signal.methodSignature().constData(),
2630 receiver->className(), method.methodSignature().constData());
2631 }
2632}
2633#endif
2634
2635/*!
2636 \threadsafe
2637
2638 Creates a connection of the given \a type from the \a signal in
2639 the \a sender object to the \a method in the \a receiver object.
2640 Returns a handle to the connection that can be used to disconnect
2641 it later.
2642
2643 You must use the \c SIGNAL() and \c SLOT() macros when specifying
2644 the \a signal and the \a method, for example:
2645
2646 \snippet code/src_corelib_kernel_qobject.cpp 22
2647
2648 This example ensures that the label always displays the current
2649 scroll bar value. Note that the signal and slots parameters must not
2650 contain any variable names, only the type. E.g. the following would
2651 not work and return false:
2652
2653 \snippet code/src_corelib_kernel_qobject.cpp 23
2654
2655 A signal can also be connected to another signal:
2656
2657 \snippet code/src_corelib_kernel_qobject.cpp 24
2658
2659 In this example, the \c MyWidget constructor relays a signal from
2660 a private member variable, and makes it available under a name
2661 that relates to \c MyWidget.
2662
2663 A signal can be connected to many slots and signals. Many signals
2664 can be connected to one slot.
2665
2666 If a signal is connected to several slots, the slots are activated
2667 in the same order in which the connections were made, when the
2668 signal is emitted.
2669
2670 The function returns a QMetaObject::Connection that represents
2671 a handle to a connection if it successfully
2672 connects the signal to the slot. The connection handle will be invalid
2673 if it cannot create the connection, for example, if QObject is unable
2674 to verify the existence of either \a signal or \a method, or if their
2675 signatures aren't compatible.
2676 You can check if the handle is valid by casting it to a bool.
2677
2678 By default, a signal is emitted for every connection you make;
2679 two signals are emitted for duplicate connections. You can break
2680 all of these connections with a single disconnect() call.
2681 If you pass the Qt::UniqueConnection \a type, the connection will only
2682 be made if it is not a duplicate. If there is already a duplicate
2683 (exact same signal to the exact same slot on the same objects),
2684 the connection will fail and connect will return an invalid QMetaObject::Connection.
2685
2686 \note Qt::UniqueConnections do not work for lambdas, non-member functions
2687 and functors; they only apply to connecting to member functions.
2688
2689 The optional \a type parameter describes the type of connection
2690 to establish. In particular, it determines whether a particular
2691 signal is delivered to a slot immediately or queued for delivery
2692 at a later time. If the signal is queued, the parameters must be
2693 of types that are known to Qt's meta-object system, because Qt
2694 needs to copy the arguments to store them in an event behind the
2695 scenes. If you try to use a queued connection and get the error
2696 message
2697
2698 \snippet code/src_corelib_kernel_qobject.cpp 25
2699
2700 call qRegisterMetaType() to register the data type before you
2701 establish the connection.
2702
2703 \sa disconnect(), sender(), qRegisterMetaType(), Q_DECLARE_METATYPE(),
2704 {Differences between String-Based and Functor-Based Connections}
2705*/
2706QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
2707 const QObject *receiver, const char *method,
2708 Qt::ConnectionType type)
2709{
2710 if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
2711 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2712 sender ? sender->metaObject()->className() : "(null)",
2713 (signal && *signal) ? signal+1 : "(null)",
2714 receiver ? receiver->metaObject()->className() : "(null)",
2715 (method && *method) ? method+1 : "(null)");
2716 return QMetaObject::Connection(0);
2717 }
2718 QByteArray tmp_signal_name;
2719
2720 if (!check_signal_macro(sender, signal, "connect", "bind"))
2721 return QMetaObject::Connection(0);
2722 const QMetaObject *smeta = sender->metaObject();
2723 const char *signal_arg = signal;
2724 ++signal; //skip code
2725 QArgumentTypeArray signalTypes;
2726 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
2727 QByteArray signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2728 int signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2729 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2730 if (signal_index < 0) {
2731 // check for normalized signatures
2732 tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
2733 signal = tmp_signal_name.constData() + 1;
2734
2735 signalTypes.clear();
2736 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
2737 smeta = sender->metaObject();
2738 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
2739 &smeta, signalName, signalTypes.size(), signalTypes.constData());
2740 }
2741 if (signal_index < 0) {
2742 err_method_notfound(sender, signal_arg, "connect");
2743 err_info_about_objects("connect", sender, receiver);
2744 return QMetaObject::Connection(0);
2745 }
2746 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
2747 signal_index += QMetaObjectPrivate::signalOffset(smeta);
2748
2749 QByteArray tmp_method_name;
2750 int membcode = extract_code(method);
2751
2752 if (!check_method_code(membcode, receiver, method, "connect"))
2753 return QMetaObject::Connection(0);
2754 const char *method_arg = method;
2755 ++method; // skip code
2756
2757 QArgumentTypeArray methodTypes;
2758 QByteArray methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2759 const QMetaObject *rmeta = receiver->metaObject();
2760 int method_index_relative = -1;
2761 Q_ASSERT(QMetaObjectPrivate::get(rmeta)->revision >= 7);
2762 switch (membcode) {
2763 case QSLOT_CODE:
2764 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2765 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2766 break;
2767 case QSIGNAL_CODE:
2768 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2769 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2770 break;
2771 }
2772 if (method_index_relative < 0) {
2773 // check for normalized methods
2774 tmp_method_name = QMetaObject::normalizedSignature(method);
2775 method = tmp_method_name.constData();
2776
2777 methodTypes.clear();
2778 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
2779 // rmeta may have been modified above
2780 rmeta = receiver->metaObject();
2781 switch (membcode) {
2782 case QSLOT_CODE:
2783 method_index_relative = QMetaObjectPrivate::indexOfSlotRelative(
2784 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2785 break;
2786 case QSIGNAL_CODE:
2787 method_index_relative = QMetaObjectPrivate::indexOfSignalRelative(
2788 &rmeta, methodName, methodTypes.size(), methodTypes.constData());
2789 break;
2790 }
2791 }
2792
2793 if (method_index_relative < 0) {
2794 err_method_notfound(receiver, method_arg, "connect");
2795 err_info_about_objects("connect", sender, receiver);
2796 return QMetaObject::Connection(0);
2797 }
2798
2799 if (!QMetaObjectPrivate::checkConnectArgs(signalTypes.size(), signalTypes.constData(),
2800 methodTypes.size(), methodTypes.constData())) {
2801 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2802 "\n %s::%s --> %s::%s",
2803 sender->metaObject()->className(), signal,
2804 receiver->metaObject()->className(), method);
2805 return QMetaObject::Connection(0);
2806 }
2807
2808 int *types = 0;
2809 if ((type == Qt::QueuedConnection)
2810 && !(types = queuedConnectionTypes(signalTypes.constData(), signalTypes.size()))) {
2811 return QMetaObject::Connection(0);
2812 }
2813
2814#ifndef QT_NO_DEBUG
2815 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
2816 QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
2817 check_and_warn_compat(smeta, smethod, rmeta, rmethod);
2818#endif
2819 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2820 sender, signal_index, smeta, receiver, method_index_relative, rmeta ,type, types));
2821 return handle;
2822}
2823
2824/*!
2825 \since 4.8
2826
2827 Creates a connection of the given \a type from the \a signal in
2828 the \a sender object to the \a method in the \a receiver object.
2829 Returns a handle to the connection that can be used to disconnect
2830 it later.
2831
2832 The Connection handle will be invalid if it cannot create the
2833 connection, for example, the parameters were invalid.
2834 You can check if the QMetaObject::Connection is valid by casting it to a bool.
2835
2836 This function works in the same way as
2837 \c {connect(const QObject *sender, const char *signal,
2838 const QObject *receiver, const char *method,
2839 Qt::ConnectionType type)}
2840 but it uses QMetaMethod to specify signal and method.
2841
2842 \sa connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
2843 */
2844QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
2845 const QObject *receiver, const QMetaMethod &method,
2846 Qt::ConnectionType type)
2847{
2848 if (sender == 0
2849 || receiver == 0
2850 || signal.methodType() != QMetaMethod::Signal
2851 || method.methodType() == QMetaMethod::Constructor) {
2852 qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
2853 sender ? sender->metaObject()->className() : "(null)",
2854 signal.methodSignature().constData(),
2855 receiver ? receiver->metaObject()->className() : "(null)",
2856 method.methodSignature().constData() );
2857 return QMetaObject::Connection(0);
2858 }
2859
2860 int signal_index;
2861 int method_index;
2862 {
2863 int dummy;
2864 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
2865 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
2866 }
2867
2868 const QMetaObject *smeta = sender->metaObject();
2869 const QMetaObject *rmeta = receiver->metaObject();
2870 if (signal_index == -1) {
2871 qWarning("QObject::connect: Can't find signal %s on instance of class %s",
2872 signal.methodSignature().constData(), smeta->className());
2873 return QMetaObject::Connection(0);
2874 }
2875 if (method_index == -1) {
2876 qWarning("QObject::connect: Can't find method %s on instance of class %s",
2877 method.methodSignature().constData(), rmeta->className());
2878 return QMetaObject::Connection(0);
2879 }
2880
2881 if (!QMetaObject::checkConnectArgs(signal.methodSignature().constData(), method.methodSignature().constData())) {
2882 qWarning("QObject::connect: Incompatible sender/receiver arguments"
2883 "\n %s::%s --> %s::%s",
2884 smeta->className(), signal.methodSignature().constData(),
2885 rmeta->className(), method.methodSignature().constData());
2886 return QMetaObject::Connection(0);
2887 }
2888
2889 int *types = 0;
2890 if ((type == Qt::QueuedConnection)
2891 && !(types = queuedConnectionTypes(signal.parameterTypes())))
2892 return QMetaObject::Connection(0);
2893
2894#ifndef QT_NO_DEBUG
2895 check_and_warn_compat(smeta, signal, rmeta, method);
2896#endif
2897 QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
2898 sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
2899 return handle;
2900}
2901
2902/*!
2903 \fn bool QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const
2904 \overload connect()
2905 \threadsafe
2906
2907 Connects \a signal from the \a sender object to this object's \a
2908 method.
2909
2910 Equivalent to connect(\a sender, \a signal, \c this, \a method, \a type).
2911
2912 Every connection you make emits a signal, so duplicate connections emit
2913 two signals. You can break a connection using disconnect().
2914
2915 \sa disconnect()
2916*/
2917
2918/*!
2919 \threadsafe
2920
2921 Disconnects \a signal in object \a sender from \a method in object
2922 \a receiver. Returns \c true if the connection is successfully broken;
2923 otherwise returns \c false.
2924
2925 A signal-slot connection is removed when either of the objects
2926 involved are destroyed.
2927
2928 disconnect() is typically used in three ways, as the following
2929 examples demonstrate.
2930 \list 1
2931 \li Disconnect everything connected to an object's signals:
2932
2933 \snippet code/src_corelib_kernel_qobject.cpp 26
2934
2935 equivalent to the non-static overloaded function
2936
2937 \snippet code/src_corelib_kernel_qobject.cpp 27
2938
2939 \li Disconnect everything connected to a specific signal:
2940
2941 \snippet code/src_corelib_kernel_qobject.cpp 28
2942
2943 equivalent to the non-static overloaded function
2944
2945 \snippet code/src_corelib_kernel_qobject.cpp 29
2946
2947 \li Disconnect a specific receiver:
2948
2949 \snippet code/src_corelib_kernel_qobject.cpp 30
2950
2951 equivalent to the non-static overloaded function
2952
2953 \snippet code/src_corelib_kernel_qobject.cpp 31
2954
2955 \endlist
2956
2957 0 may be used as a wildcard, meaning "any signal", "any receiving
2958 object", or "any slot in the receiving object", respectively.
2959
2960 The \a sender may never be \nullptr. (You cannot disconnect signals
2961 from more than one object in a single call.)
2962
2963 If \a signal is 0, it disconnects \a receiver and \a method from
2964 any signal. If not, only the specified signal is disconnected.
2965
2966 If \a receiver is 0, it disconnects anything connected to \a
2967 signal. If not, slots in objects other than \a receiver are not
2968 disconnected.
2969
2970 If \a method is 0, it disconnects anything that is connected to \a
2971 receiver. If not, only slots named \a method will be disconnected,
2972 and all other slots are left alone. The \a method must be \nullptr
2973 if \a receiver is left out, so you cannot disconnect a
2974 specifically-named slot on all objects.
2975
2976 \sa connect()
2977*/
2978bool QObject::disconnect(const QObject *sender, const char *signal,
2979 const QObject *receiver, const char *method)
2980{
2981 if (sender == 0 || (receiver == 0 && method != 0)) {
2982 qWarning("QObject::disconnect: Unexpected null parameter");
2983 return false;
2984 }
2985
2986 const char *signal_arg = signal;
2987 QByteArray signal_name;
2988 bool signal_found = false;
2989 if (signal) {
2990 QT_TRY {
2991 signal_name = QMetaObject::normalizedSignature(signal);
2992 signal = signal_name.constData();
2993 } QT_CATCH (const std::bad_alloc &) {
2994 // if the signal is already normalized, we can continue.
2995 if (sender->metaObject()->indexOfSignal(signal + 1) == -1)
2996 QT_RETHROW;
2997 }
2998
2999 if (!check_signal_macro(sender, signal, "disconnect", "unbind"))
3000 return false;
3001 signal++; // skip code
3002 }
3003
3004 QByteArray method_name;
3005 const char *method_arg = method;
3006 int membcode = -1;
3007 bool method_found = false;
3008 if (method) {
3009 QT_TRY {
3010 method_name = QMetaObject::normalizedSignature(method);
3011 method = method_name.constData();
3012 } QT_CATCH(const std::bad_alloc &) {
3013 // if the method is already normalized, we can continue.
3014 if (receiver->metaObject()->indexOfMethod(method + 1) == -1)
3015 QT_RETHROW;
3016 }
3017
3018 membcode = extract_code(method);
3019 if (!check_method_code(membcode, receiver, method, "disconnect"))
3020 return false;
3021 method++; // skip code
3022 }
3023
3024 /* We now iterate through all the sender's and receiver's meta
3025 * objects in order to also disconnect possibly shadowed signals
3026 * and slots with the same signature.
3027 */
3028 bool res = false;
3029 const QMetaObject *smeta = sender->metaObject();
3030 QByteArray signalName;
3031 QArgumentTypeArray signalTypes;
3032 Q_ASSERT(QMetaObjectPrivate::get(smeta)->revision >= 7);
3033 if (signal)
3034 signalName = QMetaObjectPrivate::decodeMethodSignature(signal, signalTypes);
3035 QByteArray methodName;
3036 QArgumentTypeArray methodTypes;
3037 Q_ASSERT(!receiver || QMetaObjectPrivate::get(receiver->metaObject())->revision >= 7);
3038 if (method)
3039 methodName = QMetaObjectPrivate::decodeMethodSignature(method, methodTypes);
3040 do {
3041 int signal_index = -1;
3042 if (signal) {
3043 signal_index = QMetaObjectPrivate::indexOfSignalRelative(
3044 &smeta, signalName, signalTypes.size(), signalTypes.constData());
3045 if (signal_index < 0)
3046 break;
3047 signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
3048 signal_index += QMetaObjectPrivate::signalOffset(smeta);
3049 signal_found = true;
3050 }
3051
3052 if (!method) {
3053 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
3054 } else {
3055 const QMetaObject *rmeta = receiver->metaObject();
3056 do {
3057 int method_index = QMetaObjectPrivate::indexOfMethod(
3058 rmeta, methodName, methodTypes.size(), methodTypes.constData());
3059 if (method_index >= 0)
3060 while (method_index < rmeta->methodOffset())
3061 rmeta = rmeta->superClass();
3062 if (method_index < 0)
3063 break;
3064 res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
3065 method_found = true;
3066 } while ((rmeta = rmeta->superClass()));
3067 }
3068 } while (signal && (smeta = smeta->superClass()));
3069
3070 if (signal && !signal_found) {
3071 err_method_notfound(sender, signal_arg, "disconnect");
3072 err_info_about_objects("disconnect", sender, receiver);
3073 } else if (method && !method_found) {
3074 err_method_notfound(receiver, method_arg, "disconnect");
3075 err_info_about_objects("disconnect", sender, receiver);
3076 }
3077 if (res) {
3078 if (!signal)
3079 const_cast<QObject*>(sender)->disconnectNotify(QMetaMethod());
3080 }
3081 return res;
3082}
3083
3084/*!
3085 \since 4.8
3086
3087 Disconnects \a signal in object \a sender from \a method in object
3088 \a receiver. Returns \c true if the connection is successfully broken;
3089 otherwise returns \c false.
3090
3091 This function provides the same possibilities like
3092 \c {disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method) }
3093 but uses QMetaMethod to represent the signal and the method to be disconnected.
3094
3095 Additionally this function returnsfalse and no signals and slots disconnected
3096 if:
3097 \list 1
3098
3099 \li \a signal is not a member of sender class or one of its parent classes.
3100
3101 \li \a method is not a member of receiver class or one of its parent classes.
3102
3103 \li \a signal instance represents not a signal.
3104
3105 \endlist
3106
3107 QMetaMethod() may be used as wildcard in the meaning "any signal" or "any slot in receiving object".
3108 In the same way 0 can be used for \a receiver in the meaning "any receiving object". In this case
3109 method should also be QMetaMethod(). \a sender parameter should be never 0.
3110
3111 \sa disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
3112 */
3113bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
3114 const QObject *receiver, const QMetaMethod &method)
3115{
3116 if (sender == 0 || (receiver == 0 && method.mobj != 0)) {
3117 qWarning("QObject::disconnect: Unexpected null parameter");
3118 return false;
3119 }
3120 if (signal.mobj) {
3121 if(signal.methodType() != QMetaMethod::Signal) {
3122 qWarning("QObject::%s: Attempt to %s non-signal %s::%s",
3123 "disconnect","unbind",
3124 sender->metaObject()->className(), signal.methodSignature().constData());
3125 return false;
3126 }
3127 }
3128 if (method.mobj) {
3129 if(method.methodType() == QMetaMethod::Constructor) {
3130 qWarning("QObject::disconect: cannot use constructor as argument %s::%s",
3131 receiver->metaObject()->className(), method.methodSignature().constData());
3132 return false;
3133 }
3134 }
3135
3136 // Reconstructing SIGNAL() macro result for signal.methodSignature() string
3137 QByteArray signalSignature;
3138 if (signal.mobj) {
3139 signalSignature.reserve(signal.methodSignature().size()+1);
3140 signalSignature.append((char)(QSIGNAL_CODE + '0'));
3141 signalSignature.append(signal.methodSignature());
3142 }
3143
3144 int signal_index;
3145 int method_index;
3146 {
3147 int dummy;
3148 QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
3149 QMetaObjectPrivate::memberIndexes(receiver, method, &dummy, &method_index);
3150 }
3151 // If we are here sender is not null. If signal is not null while signal_index
3152 // is -1 then this signal is not a member of sender.
3153 if (signal.mobj && signal_index == -1) {
3154 qWarning("QObject::disconect: signal %s not found on class %s",
3155 signal.methodSignature().constData(), sender->metaObject()->className());
3156 return false;
3157 }
3158 // If this condition is true then method is not a member of receeiver.
3159 if (receiver && method.mobj && method_index == -1) {
3160 qWarning("QObject::disconect: method %s not found on class %s",
3161 method.methodSignature().constData(), receiver->metaObject()->className());
3162 return false;
3163 }
3164
3165 if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
3166 return false;
3167
3168 if (!signal.isValid()) {
3169 // The signal is a wildcard, meaning all signals were disconnected.
3170 // QMetaObjectPrivate::disconnect() doesn't call disconnectNotify()
3171 // per connection in this case. Call it once now, with an invalid
3172 // QMetaMethod as argument, as documented.
3173 const_cast<QObject*>(sender)->disconnectNotify(signal);
3174 }
3175 return true;
3176}
3177
3178/*!
3179 \threadsafe
3180
3181 \fn bool QObject::disconnect(const char *signal, const QObject *receiver, const char *method) const
3182 \overload disconnect()
3183
3184 Disconnects \a signal from \a method of \a receiver.
3185
3186 A signal-slot connection is removed when either of the objects
3187 involved are destroyed.
3188*/
3189
3190/*!
3191 \fn bool QObject::disconnect(const QObject *receiver, const char *method) const
3192 \overload disconnect()
3193
3194 Disconnects all signals in this object from \a receiver's \a
3195 method.
3196
3197 A signal-slot connection is removed when either of the objects
3198 involved are destroyed.
3199*/
3200
3201
3202/*!
3203 \since 5.0
3204
3205 This virtual function is called when something has been connected
3206 to \a signal in this object.
3207
3208 If you want to compare \a signal with a specific signal, you can
3209 use QMetaMethod::fromSignal() as follows:
3210
3211 \snippet code/src_corelib_kernel_qobject.cpp 32
3212
3213 \warning This function violates the object-oriented principle of
3214 modularity. However, it might be useful when you need to perform
3215 expensive initialization only if something is connected to a
3216 signal.
3217
3218 \warning This function is called from the thread which performs the
3219 connection, which may be a different thread from the thread in
3220 which this object lives.
3221
3222 \sa connect(), disconnectNotify()
3223*/
3224
3225void QObject::connectNotify(const QMetaMethod &signal)
3226{
3227 Q_UNUSED(signal);
3228}
3229
3230/*!
3231 \since 5.0
3232
3233 This virtual function is called when something has been
3234 disconnected from \a signal in this object.
3235
3236 See connectNotify() for an example of how to compare
3237 \a signal with a specific signal.
3238
3239 If all signals were disconnected from this object (e.g., the
3240 signal argument to disconnect() was 0), disconnectNotify()
3241 is only called once, and the \a signal will be an invalid
3242 QMetaMethod (QMetaMethod::isValid() returns \c false).
3243
3244 \warning This function violates the object-oriented principle of
3245 modularity. However, it might be useful for optimizing access to
3246 expensive resources.
3247
3248 \warning This function is called from the thread which performs the
3249 disconnection, which may be a different thread from the thread in
3250 which this object lives. This function may also be called with a QObject
3251 internal mutex locked. It is therefore not allowed to re-enter any
3252 of any QObject functions from your reimplementation and if you lock
3253 a mutex in your reimplementation, make sure that you don't call QObject
3254 functions with that mutex held in other places or it will result in
3255 a deadlock.
3256
3257 \sa disconnect(), connectNotify()
3258*/
3259
3260void QObject::disconnectNotify(const QMetaMethod &signal)
3261{
3262 Q_UNUSED(signal);
3263}
3264
3265/*
3266 \internal
3267 convert a signal index from the method range to the signal range
3268 */
3269static int methodIndexToSignalIndex(const QMetaObject **base, int signal_index)
3270{
3271 if (signal_index < 0)
3272 return signal_index;
3273 const QMetaObject *metaObject = *base;
3274 while (metaObject && metaObject->methodOffset() > signal_index)
3275 metaObject = metaObject->superClass();
3276
3277 if (metaObject) {
3278 int signalOffset, methodOffset;
3279 computeOffsets(metaObject, &signalOffset, &methodOffset);
3280 if (signal_index < metaObject->methodCount())
3281 signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
3282 else
3283 signal_index = signal_index - methodOffset + signalOffset;
3284 *base = metaObject;
3285 }
3286 return signal_index;
3287}
3288
3289/*!
3290 \internal
3291 \a types is a 0-terminated vector of meta types for queued
3292 connections.
3293
3294 if \a signal_index is -1, then we effectively connect *all* signals
3295 from the sender to the receiver's slot
3296 */
3297QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_index,
3298 const QObject *receiver, int method_index, int type, int *types)
3299{
3300 const QMetaObject *smeta = sender->metaObject();
3301 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3302 return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
3303 receiver, method_index,
3304 0, //FIXME, we could speed this connection up by computing the relative index
3305 type, types));
3306}
3307
3308/*!
3309 \internal
3310 Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3311
3312 method_index is relative to the rmeta metaobject, if rmeta is \nullptr, then it is absolute index
3313
3314 the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
3315 */
3316QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
3317 int signal_index, const QMetaObject *smeta,
3318 const QObject *receiver, int method_index,
3319 const QMetaObject *rmeta, int type, int *types)
3320{
3321 QObject *s = const_cast<QObject *>(sender);
3322 QObject *r = const_cast<QObject *>(receiver);
3323
3324 int method_offset = rmeta ? rmeta->methodOffset() : 0;
3325 Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
3326 QObjectPrivate::StaticMetaCallFunction callFunction = rmeta ? rmeta->d.static_metacall : nullptr;
3327
3328 QOrderedMutexLocker locker(signalSlotLock(sender),
3329 signalSlotLock(receiver));
3330
3331 QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
3332 if (type & Qt::UniqueConnection && scd) {
3333 if (scd->signalVectorCount() > signal_index) {
3334 const QObjectPrivate::Connection *c2 = scd->signalVector.load()->at(signal_index).first.load();
3335
3336 int method_index_absolute = method_index + method_offset;
3337
3338 while (c2) {
3339 if (!c2->isSlotObject && c2->receiver.load() == receiver && c2->method() == method_index_absolute)
3340 return nullptr;
3341 c2 = c2->nextConnectionList.load();
3342 }
3343 }
3344 type &= Qt::UniqueConnection - 1;
3345 }
3346
3347 QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
3348 c->sender = s;
3349 c->signal_index = signal_index;
3350 c->receiver.store(r);
3351 QThreadData *td = r->d_func()->threadData;
3352 td->ref();
3353 c->receiverThreadData.store(td);
3354 c->method_relative = method_index;
3355 c->method_offset = method_offset;
3356 c->connectionType = type;
3357 c->isSlotObject = false;
3358 c->argumentTypes.store(types);
3359 c->callFunction = callFunction;
3360
3361 QObjectPrivate::get(s)->addConnection(signal_index, c.data());
3362
3363 locker.unlock();
3364 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3365 if (smethod.isValid())
3366 s->connectNotify(smethod);
3367
3368 return c.take();
3369}
3370
3371/*!
3372 \internal
3373 */
3374bool QMetaObject::disconnect(const QObject *sender, int signal_index,
3375 const QObject *receiver, int method_index)
3376{
3377 const QMetaObject *smeta = sender->metaObject();
3378 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3379 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3380 receiver, method_index, 0);
3381}
3382
3383/*!
3384 \internal
3385
3386Disconnect a single signal connection. If QMetaObject::connect() has been called
3387multiple times for the same sender, signal_index, receiver and method_index only
3388one of these connections will be removed.
3389 */
3390bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
3391 const QObject *receiver, int method_index)
3392{
3393 const QMetaObject *smeta = sender->metaObject();
3394 signal_index = methodIndexToSignalIndex(&smeta, signal_index);
3395 return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
3396 receiver, method_index, 0,
3397 QMetaObjectPrivate::DisconnectOne);
3398}
3399
3400/*!
3401 \internal
3402 Helper function to remove the connection from the senders list and setting the receivers to 0
3403 */
3404bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
3405 const QObject *receiver, int method_index, void **slot,
3406 QBasicMutex *senderMutex, DisconnectType disconnectType)
3407{
3408 bool success = false;
3409
3410 auto &connectionList = connections->connectionsForSignal(signalIndex);
3411 auto *c = connectionList.first.load();
3412 while (c) {
3413 QObject *r = c->receiver.load();
3414 if (r && (receiver == nullptr || (r == receiver
3415 && (method_index < 0 || (!c->isSlotObject && c->method() == method_index))
3416 && (slot == nullptr || (c->isSlotObject && c->slotObj->compare(slot)))))) {
3417 bool needToUnlock = false;
3418 QBasicMutex *receiverMutex = nullptr;
3419 if (r) {
3420 receiverMutex = signalSlotLock(r);
3421 // need to relock this receiver and sender in the correct order
3422 needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex);
3423 }
3424 if (c->receiver.load())
3425 connections->removeConnection(c);
3426
3427 if (needToUnlock)
3428 receiverMutex->unlock();
3429
3430 success = true;
3431
3432 if (disconnectType == DisconnectOne)
3433 return success;
3434 }
3435 c = c->nextConnectionList.load();
3436 }
3437 return success;
3438}
3439
3440/*!
3441 \internal
3442 Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
3443 */
3444bool QMetaObjectPrivate::disconnect(const QObject *sender,
3445 int signal_index, const QMetaObject *smeta,
3446 const QObject *receiver, int method_index, void **slot,
3447 DisconnectType disconnectType)
3448{
3449 if (!sender)
3450 return false;
3451
3452 QObject *s = const_cast<QObject *>(sender);
3453
3454 QBasicMutex *senderMutex = signalSlotLock(sender);
3455 QBasicMutexLocker locker(senderMutex);
3456
3457 QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
3458 if (!scd)
3459 return false;
3460
3461 bool success = false;
3462 {
3463 // prevent incoming connections changing the connections->receivers while unlocked
3464 QObjectPrivate::ConnectionDataPointer connections(scd);
3465
3466 if (signal_index < 0) {
3467 // remove from all connection lists
3468 for (int sig_index = -1; sig_index < scd->signalVectorCount(); ++sig_index) {
3469 if (disconnectHelper(connections.data(), sig_index, receiver, method_index, slot, senderMutex, disconnectType))
3470 success = true;
3471 }
3472 } else if (signal_index < scd->signalVectorCount()) {
3473 if (disconnectHelper(connections.data(), signal_index, receiver, method_index, slot, senderMutex, disconnectType))
3474 success = true;
3475 }
3476 }
3477
3478 locker.unlock();
3479 if (success) {
3480 scd->cleanOrphanedConnections(s);
3481
3482 QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
3483 if (smethod.isValid())
3484 s->disconnectNotify(smethod);
3485 }
3486
3487 return success;
3488}
3489
3490/*!
3491 \fn void QMetaObject::connectSlotsByName(QObject *object)
3492
3493 Searches recursively for all child objects of the given \a object, and connects
3494 matching signals from them to slots of \a object that follow the following form:
3495
3496 \snippet code/src_corelib_kernel_qobject.cpp 33
3497
3498 Let's assume our object has a child object of type \c{QPushButton} with
3499 the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
3500 button's \c{clicked()} signal would be:
3501
3502 \snippet code/src_corelib_kernel_qobject.cpp 34
3503
3504 If \a object itself has a properly set object name, its own signals are also
3505 connected to its respective slots.
3506
3507 \sa QObject::setObjectName()
3508 */
3509void QMetaObject::connectSlotsByName(QObject *o)
3510{
3511 if (!o)
3512 return;
3513 const QMetaObject *mo = o->metaObject();
3514 Q_ASSERT(mo);
3515 const QObjectList list = // list of all objects to look for matching signals including...
3516 o->findChildren<QObject *>(QString()) // all children of 'o'...
3517 << o; // and the object 'o' itself
3518
3519 // for each method/slot of o ...
3520 for (int i = 0; i < mo->methodCount(); ++i) {
3521 const QByteArray slotSignature = mo->method(i).methodSignature();
3522 const char *slot = slotSignature.constData();
3523 Q_ASSERT(slot);
3524
3525 // ...that starts with "on_", ...
3526 if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
3527 continue;
3528
3529 // ...we check each object in our list, ...
3530 bool foundIt = false;
3531 for(int j = 0; j < list.count(); ++j) {
3532 const QObject *co = list.at(j);
3533 const QByteArray coName = co->objectName().toLatin1();
3534
3535 // ...discarding those whose objectName is not fitting the pattern "on_<objectName>_...", ...
3536 if (coName.isEmpty() || qstrncmp(slot + 3, coName.constData(), coName.size()) || slot[coName.size()+3] != '_')
3537 continue;
3538
3539 const char *signal = slot + coName.size() + 4; // the 'signal' part of the slot name
3540
3541 // ...for the presence of a matching signal "on_<objectName>_<signal>".
3542 const QMetaObject *smeta;
3543 int sigIndex = co->d_func()->signalIndex(signal, &smeta);
3544 if (sigIndex < 0) {
3545 // if no exactly fitting signal (name + complete parameter type list) could be found
3546 // look for just any signal with the correct name and at least the slot's parameter list.
3547 // Note: if more than one of thoses signals exist, the one that gets connected is
3548 // chosen 'at random' (order of declaration in source file)
3549 QList<QByteArray> compatibleSignals;
3550 const QMetaObject *smo = co->metaObject();
3551 int sigLen = qstrlen(signal) - 1; // ignore the trailing ')'
3552 for (int k = QMetaObjectPrivate::absoluteSignalCount(smo)-1; k >= 0; --k) {
3553 const QMetaMethod method = QMetaObjectPrivate::signal(smo, k);
3554 if (!qstrncmp(method.methodSignature().constData(), signal, sigLen)) {
3555 smeta = method.enclosingMetaObject();
3556 sigIndex = k;
3557 compatibleSignals.prepend(method.methodSignature());
3558 }
3559 }
3560 if (compatibleSignals.size() > 1)
3561 qWarning() << "QMetaObject::connectSlotsByName: Connecting slot" << slot
3562 << "with the first of the following compatible signals:" << compatibleSignals;
3563 }
3564
3565 if (sigIndex < 0)
3566 continue;
3567
3568 // we connect it...
3569 if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
3570 foundIt = true;
3571 // ...and stop looking for further objects with the same name.
3572 // Note: the Designer will make sure each object name is unique in the above
3573 // 'list' but other code may create two child objects with the same name. In
3574 // this case one is chosen 'at random'.
3575 break;
3576 }
3577 }
3578 if (foundIt) {
3579 // we found our slot, now skip all overloads
3580 while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
3581 ++i;
3582 } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
3583 // check if the slot has the following signature: "on_..._...(..."
3584 int iParen = slotSignature.indexOf('(');
3585 int iLastUnderscore = slotSignature.lastIndexOf('_', iParen-1);
3586 if (iLastUnderscore > 3)
3587 qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
3588 }
3589 }
3590}
3591
3592/*!
3593 \internal
3594
3595 \a signal must be in the signal index range (see QObjectPrivate::signalIndex()).
3596*/
3597static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
3598{
3599 const int *argumentTypes = c->argumentTypes.load();
3600 if (!argumentTypes) {
3601 QMetaMethod m = QMetaObjectPrivate::signal(sender->metaObject(), signal);
3602 argumentTypes = queuedConnectionTypes(m.parameterTypes());
3603 if (!argumentTypes) // cannot queue arguments
3604 argumentTypes = &DIRECT_CONNECTION_ONLY;
3605 if (!c->argumentTypes.testAndSetOrdered(0, argumentTypes)) {
3606 if (argumentTypes != &DIRECT_CONNECTION_ONLY)
3607 delete [] argumentTypes;
3608 argumentTypes = c->argumentTypes.load();
3609 }
3610 }
3611 if (argumentTypes == &DIRECT_CONNECTION_ONLY) // cannot activate
3612 return;
3613 int nargs = 1; // include return type
3614 while (argumentTypes[nargs-1])
3615 ++nargs;
3616 int *types = (int *) malloc(nargs*sizeof(int));
3617 Q_CHECK_PTR(types);
3618 void **args = (void **) malloc(nargs*sizeof(void *));
3619 Q_CHECK_PTR(args);
3620 types[0] = 0; // return type
3621 args[0] = 0; // return value
3622
3623 if (nargs > 1) {
3624 for (int n = 1; n < nargs; ++n)
3625 types[n] = argumentTypes[n-1];
3626
3627 for (int n = 1; n < nargs; ++n)
3628 args[n] = QMetaType::create(types[n], argv[n]);
3629 }
3630
3631 QBasicMutexLocker locker(signalSlotLock(c->receiver.load()));
3632 if (!c->receiver.load()) {
3633 // the connection has been disconnected before we got the lock
3634 locker.unlock();
3635 for (int n = 1; n < nargs; ++n)
3636 QMetaType::destroy(types[n], args[n]);
3637 free(types);
3638 free(args);
3639 return;
3640 }
3641
3642 QMetaCallEvent *ev = c->isSlotObject ?
3643 new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
3644 new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
3645 QCoreApplication::postEvent(c->receiver.load(), ev);
3646}
3647
3648template <bool callbacks_enabled>
3649void doActivate(QObject *sender, int signal_index, void **argv)
3650{
3651 QObjectPrivate *sp = QObjectPrivate::get(sender);
3652
3653 if (sp->blockSig)
3654 return;
3655
3656 if (sp->isDeclarativeSignalConnected(signal_index)
3657 && QAbstractDeclarativeData::signalEmitted) {
3658 Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index);
3659 QAbstractDeclarativeData::signalEmitted(sp->declarativeData, sender,
3660 signal_index, argv);
3661 Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index);
3662 }
3663
3664 const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr;
3665
3666 void *empty_argv[] = { nullptr };
3667 if (!argv)
3668 argv = empty_argv;
3669
3670 if (!sp->maybeSignalConnected(signal_index)) {
3671 // The possible declarative connection is done, and nothing else is connected
3672 if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
3673 signal_spy_set->signal_begin_callback(sender, signal_index, argv);
3674 Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
3675 Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
3676 if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
3677 signal_spy_set->signal_end_callback(sender, signal_index);
3678 return;
3679 }
3680
3681 if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
3682 signal_spy_set->signal_begin_callback(sender, signal_index, argv);
3683 Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
3684
3685 bool senderDeleted = false;
3686 {
3687 Q_ASSERT(sp->connections);
3688 QObjectPrivate::ConnectionDataPointer connections(sp->connections.load());
3689 QObjectPrivate::SignalVector *signalVector = connections->signalVector.load();
3690
3691 const QObjectPrivate::ConnectionList *list;
3692 if (signal_index < signalVector->count())
3693 list = &signalVector->at(signal_index);
3694 else
3695 list = &signalVector->at(-1);
3696
3697 Qt::HANDLE currentThreadId = QThread::currentThreadId();
3698 bool inSenderThread = currentThreadId == QObjectPrivate::get(sender)->threadData->threadId.load();
3699
3700 // We need to check against the highest connection id to ensure that signals added
3701 // during the signal emission are not emitted in this emission.
3702 uint highestConnectionId = connections->currentConnectionId.load();
3703 do {
3704 QObjectPrivate::Connection *c = list->first.load();
3705 if (!c)
3706 continue;
3707
3708 do {
3709 QObject * const receiver = c->receiver.load();
3710 if (!receiver)
3711 continue;
3712
3713 QThreadData *td = c->receiverThreadData.load();
3714 if (!td)
3715 continue;
3716
3717 bool receiverInSameThread;
3718 if (