📄 qobject.cpp
字号:
return; } QWriteLocker locker(guardHashLock()); if (*ptr) { GuardHash::iterator it = hash->find(*ptr); const GuardHash::iterator end = hash->end(); for (; it.key() == *ptr && it != end; ++it) { if (it.value() == ptr) { (void) hash->erase(it); break; } } } *ptr = o; if (*ptr) hash->insert(*ptr, ptr);}/*! \internal */void QObjectPrivate::clearGuards(QObject *object){ GuardHash *hash = ::guardHash(); if (hash) { QWriteLocker locker(guardHashLock()); GuardHash::iterator it = hash->find(object); const GuardHash::iterator end = hash->end(); while (it.key() == object && it != end) { *it.value() = 0; it = hash->erase(it); } }}/*! \internal */QMetaCallEvent::QMetaCallEvent(int id, const QObject *sender, int nargs, int *types, void **args) :QEvent(MetaCall), id_(id), sender_(sender), idFrom_(-1), idTo_(-1), nargs_(nargs), types_(types), args_(args){ }/*! \internal */QMetaCallEvent::QMetaCallEvent(int id, const QObject *sender, int idFrom, int idTo, int nargs, int *types, void **args) : QEvent(MetaCall), id_(id), sender_(sender), idFrom_(idFrom), idTo_(idTo), nargs_(nargs), types_(types), args_(args){ }/*! \internal */QMetaCallEvent::~QMetaCallEvent(){ for (int i = 0; i < nargs_; ++i) { if (types_[i] && args_[i]) QMetaType::destroy(types_[i], args_[i]); } if (types_) qFree(types_); if (args_) qFree(args_);}/*! \class QObject \brief The QObject class is the base class of all Qt objects. \ingroup objectmodel \mainclass \reentrant QObject is the heart of the \l{Qt object model}. The central feature in this model is a very powerful mechanism for seamless object communication called \l{signals and slots}. You can connect a signal to a slot with connect() and destroy the connection with disconnect(). To avoid never ending notification loops you can temporarily block signals with blockSignals(). The protected functions connectNotify() and disconnectNotify() make it possible to track connections. QObjects organize themselves in object trees. When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. The parent takes ownership of the object i.e. it will automatically delete its children in its destructor. You can look for an object by name and optionally type using findChild() or findChildren(). Every object has an objectName() and its class name can be found via the corresponding metaObject() (see QMetaObject::className()). You can determine whether the object's class inherits another class in the QObject inheritance hierarchy by using the inherits() function. When an object is deleted, it emits a destroyed() signal. You can catch this signal to avoid dangling references to QObjects. The QPointer class provides an elegant way to use this feature. QObjects can receive events through event() and filter the events of other objects. See installEventFilter() and eventFilter() for details. A convenience handler, childEvent(), can be reimplemented to catch child events. Events are delivered in the thread in which the object was created; see \l{Thread Support in Qt} and thread() for details. Note that event processing is not done at all for QObjects with no thread affinity (thread() returns zero). Use the moveToThread() function to change the thread affinity for an object and its children (the object cannot be moved if it has a parent). Last but not least, QObject provides the basic timer support in Qt; see QTimer for high-level support for timers. Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the \l{moc}{Meta Object Compiler} on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior. All Qt widgets inherit QObject. The convenience function isWidgetType() returns whether an object is actually a widget. It is much faster than \l{qobject_cast()}{qobject_cast}<QWidget *>(\e{obj}) or \e{obj}->\l{inherits()}{inherits}("QWidget"). Some QObject functions, e.g. children(), return a QObjectList. QObjectList is a typedef for QList<QObject *>. \section1 Auto-Connection Qt's meta-object system provides a mechanism to automatically connect signals and slots between QObject subclasses and their children. As long as objects are defined with suitable object names, and slots follow a simple naming convention, this connection can be performed at run-time by the QMetaObject::connectSlotsByName() function. \l uic generates code that invokes this function to enable auto-connection to be performed between widgets on forms created with \QD. More information about using auto-connection with \QD is given in the \l{Using a Component in Your Application#A Dialog With Auto-Connect}{Using a Component in Your Application} section of the \QD manual. \sa QMetaObject, QPointer, QObjectCleanupHandler, {Object Trees and Object Ownership}*//*! \relates QObject Returns a pointer to the object named \a name that inherits \a type and with a given \a parent. Returns 0 if there is no such child. \code QLineEdit *lineEdit = static_cast<QLineEdit *>( qt_find_obj_child(myWidget, "QLineEdit", "my line edit")); if (lineEdit) lineEdit->setText("Default"); \endcode*/void *qt_find_obj_child(QObject *parent, const char *type, const QString &name){ QObjectList list = parent->children(); if (list.size() == 0) return 0; for (int i = 0; i < list.size(); ++i) { QObject *obj = list.at(i); if (name == obj->objectName() && obj->inherits(type)) return obj; } return 0;}/***************************************************************************** QObject member functions *****************************************************************************//*! Constructs an object with parent object \a parent. The parent of an object may be viewed as the object's owner. For instance, a \l{QDialog}{dialog box} is the parent of the \gui OK and \gui Cancel buttons it contains. The destructor of a parent object destroys all child objects. Setting \a parent to 0 constructs an object with no parent. If the object is a widget, it will become a top-level window. \sa parent(), findChild(), findChildren()*/QObject::QObject(QObject *parent) : d_ptr(new QObjectPrivate){ Q_D(QObject); ::qt_addObject(d_ptr->q_ptr = this); d->threadData = QThreadData::current(); d->threadData->ref(); if (parent && parent->d_func()->threadData != d->threadData) { qWarning("QObject: Cannot create children for a parent that is in a different thread."); parent = 0; } setParent(parent);}#ifdef QT3_SUPPORT/*! \overload \obsolete Creates a new QObject with the given \a parent and object \a name. */QObject::QObject(QObject *parent, const char *name) : d_ptr(new QObjectPrivate){ Q_D(QObject); ::qt_addObject(d_ptr->q_ptr = this); d->threadData = QThreadData::current(); d->threadData->ref(); if (parent && parent->d_func()->threadData != d->threadData) { qWarning("QObject: Cannot create children for a parent that is in a different thread."); parent = 0; } setParent(parent); setObjectName(QString::fromAscii(name));}#endif/*! \internal */QObject::QObject(QObjectPrivate &dd, QObject *parent) : d_ptr(&dd){ Q_D(QObject); ::qt_addObject(d_ptr->q_ptr = this); d->threadData = QThreadData::current(); d->threadData->ref(); if (parent && parent->d_func()->threadData != d->threadData) { qWarning("QObject: Cannot create children for a parent that is in a different thread."); parent = 0; } if (d->isWidget) { if (parent) { d->parent = parent; d->parent->d_func()->children.append(this); } // no events sent here, this is done at the end of the QWidget constructor } else { setParent(parent); }}/*! Destroys the object, deleting all its child objects. All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue. However, it is often safer to use deleteLater() rather than deleting a QObject subclass directly. \warning All child objects are deleted. If any of these objects are on the stack or global, sooner or later your program will crash. We do not recommend holding pointers to child objects from outside the parent. If you still do, the destroyed() signal gives you an opportunity to detect when an object is destroyed. \warning Deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly if it exists in a different thread than the one currently executing. Use deleteLater() instead, which will cause the event loop to delete the object after all pending events have been delivered to it. \sa deleteLater()*/QObject::~QObject(){ Q_D(QObject); if (d->wasDeleted) {#if defined(QT_DEBUG) qWarning("QObject: Double deletion detected");#endif return; } d->wasDeleted = true; d->blockSig = 0; // unblock signals so we always emit destroyed() if (!d->isWidget) { // set all QPointers for this object to zero - note that // ~QWidget() does this for us, so we don't have to do it twice QObjectPrivate::clearGuards(this); } emit destroyed(this); QConnectionList *list = ::connectionList(); if (list) { QWriteLocker locker(&list->lock); list->remove(this); } if (d->pendTimer) { // unregister pending timers if (d->threadData->eventDispatcher) d->threadData->eventDispatcher->unregisterTimers(this); } d->eventFilters.clear(); if (!d->children.isEmpty()) d->deleteChildren(); { QWriteLocker locker(QObjectPrivate::readWriteLock()); ::qt_removeObject(this); /* theoretically, we cannot check d->postedEvents without holding the postEventList.mutex for the object's thread, but since we hold the QObjectPrivate::readWriteLock(), nothing can go into QCoreApplication::postEvent(), which effectively means no one can post new events, which is what we are trying to prevent. this means we can safely check d->postedEvents, since we are fairly sure it will not change (it could, but only by decreasing, i.e. removing posted events from a differebnt thread) */ if (d->postedEvents > 0) QCoreApplication::removePostedEvents(this); } if (d->parent) // remove it from parent object d->setParent_helper(0); d->threadData->deref(); delete d; d_ptr = 0;}/*! \fn QMetaObject *QObject::metaObject() const Returns a pointer to the meta-object of this object. A meta-object contains information about a class that inherits QObject, e.g. class name, superclass name, properties, signals and slots. Every class that contains the Q_OBJECT macro will also have a meta-object. The meta-object information is required by the signal/slot connection mechanism and the property system. The inherits() function also makes use of the meta-object. If you have no pointer to an actual object instance but still want to access the meta-object of a class, you can use \l staticMetaObject. Example: \code QObject *obj = new QPushButton; obj->metaObject()->className(); // returns "QPushButton" QPushButton::staticMetaObject.className(); // returns "QPushButton" \endcode \sa staticMetaObject*//*! \variable QObject::staticMetaObject This variable stores the meta-object for the class. A meta-object contains information about a class that inherits QObject, e.g. class name, superclass name, properties, signals and slots. Every class that contains the Q_OBJECT macro will also have a meta-object. The meta-object information is required by the signal/slot connection mechanism and the property system. The inherits() function also makes use of the meta-object. If you have a pointer to an object, you can use metaObject() to retrieve the meta-object associated with that object. Example: \code QPushButton::staticMetaObject.className(); // returns "QPushButton" QObject *obj = new QPushButton; obj->metaObject()->className(); // returns "QPushButton" \endcode \sa metaObject()*//*! \fn T *qobject_cast<T *>(QObject *object) \relates QObject Returns the given \a object cast to type T if the object is of type T (or of a subclass); otherwise returns 0. The class T must inherit (directly or indirectly) QObject and be declared with the \l Q_OBJECT macro. A class is considered to inherit itself.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -