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