📄 qobject.cpp
字号:
for (i = 0; i < children.size(); ++i) { obj = children.at(i); if (mo.cast(obj) && (name.isNull() || obj->objectName() == name)) return obj; } for (i = 0; i < children.size(); ++i) { obj = qt_qFindChild_helper(children.at(i), name, mo); if (obj) return obj; } return 0;}/*! Makes the object a child of \a parent. \sa QWidget::setParent()*/void QObject::setParent(QObject *parent){ Q_D(QObject); Q_ASSERT(!d->isWidget); d->setParent_helper(parent);}void QObjectPrivate::setParent_helper(QObject *o){ Q_Q(QObject); if (o == parent) return; if (parent && !parent->d_func()->wasDeleted && parent->d_func()->children.removeAll(q)) { if(sendChildEvents && parent->d_func()->receiveChildEvents) { QChildEvent e(QEvent::ChildRemoved, q); QCoreApplication::sendEvent(parent, &e); } } parent = o; if (parent) { // object hierarchies are constrained to a single thread Q_ASSERT_X(thread == parent->d_func()->thread, "QObject::setParent", "New parent must be in the same thread as the previous parent"); parent->d_func()->children.append(q); if(sendChildEvents && parent->d_func()->receiveChildEvents) { if (!isWidget) { QChildEvent e(QEvent::ChildAdded, q); QCoreApplication::sendEvent(parent, &e);#ifdef QT3_SUPPORT QCoreApplication::postEvent(parent, new QChildEvent(QEvent::ChildInserted, q));#endif }#ifdef QT3_SUPPORT else { QCoreApplication::postEvent(parent, new QChildEvent(QEvent::ChildInserted, q)); }#endif } }}/*! \fn void QObject::installEventFilter(QObject *filterObj) Installs an event filter \a filterObj on this object. For example: \code monitoredObj->installEventFilter(filterObj); \endcode An event filter is an object that receives all events that are sent to this object. The filter can either stop the event or forward it to this object. The event filter \a filterObj receives events via its eventFilter() function. The eventFilter() function must return true if the event should be filtered, (i.e. stopped); otherwise it must return false. If multiple event filters are installed on a single object, the filter that was installed last is activated first. Here's a \c KeyPressEater class that eats the key presses of its monitored objects: \code class KeyPressEater : public QObject { Q_OBJECT ... protected: bool eventFilter(QObject *obj, QEvent *event); }; bool KeyPressEater::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); qDebug("Ate key press %d", keyEvent->key()); return true; } else { // standard event processing return QObject::eventFilter(obj, event); } } \endcode And here's how to install it on two widgets: \code KeyPressEater *keyPressEater = new KeyPressEater(this); QPushButton *pushButton = new QPushButton(this); QListView *listView = new QListView(this); pushButton->installEventFilter(keyPressEater); listView->installEventFilter(keyPressEater); \endcode The QShortcut class, for example, uses this technique to intercept shortcut key presses. \warning If you delete the receiver object in your eventFilter() function, be sure to return true. If you return false, Qt sends the event to the deleted object and the program will crash. \sa removeEventFilter(), eventFilter(), event()*/void QObject::installEventFilter(QObject *obj){ Q_D(QObject); if (!obj) return; // clean up unused items in the list d->eventFilters.removeAll((QObject*)0); d->eventFilters.removeAll(obj); d->eventFilters.prepend(obj);}/*! Removes an event filter object \a obj from this object. The request is ignored if such an event filter has not been installed. All event filters for this object are automatically removed when this object is destroyed. It is always safe to remove an event filter, even during event filter activation (i.e. from the eventFilter() function). \sa installEventFilter(), eventFilter(), event()*/void QObject::removeEventFilter(QObject *obj){ Q_D(QObject); d->eventFilters.removeAll(obj);}/*! \fn QObject::destroyed(QObject *obj) This signal is emitted immediately before the object \a obj is destroyed, and can not be blocked. All the objects's children are destroyed immediately after this signal is emitted. \sa deleteLater(), QPointer*//*! Schedules this object for deletion. The object will be deleted when control returns to the event loop. Note that entering and leaving a new event loop (e.g., by opening a modal dialog) will \e not perform the deferred deletion; for the object to be deleted, the control must return to the event loop from which deleteLater() was called. \sa destroyed(), QPointer*/void QObject::deleteLater(){ QCoreApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));}/*! \fn QString QObject::tr(const char *sourceText, const char * comment) \reentrant Returns a translated version of \a sourceText, or \a sourceText itself if there is no appropriate translated version. The translation context is Object with \a comment (0 by default). All Object subclasses using the Q_OBJECT macro automatically have a reimplementation of this function with the subclass name as context. \warning This method is reentrant only if all translators are installed \e before calling this method. Installing or removing translators while performing translations is not supported. Doing so will probably result in crashes or other undesirable behavior. \sa trUtf8(), QApplication::translate(), {Internationalization with Qt}*//*! \fn QString QObject::trUtf8(const char *sourceText, const char *comment) \reentrant Returns a translated version of \a sourceText, or QString::fromUtf8(\a sourceText) if there is no appropriate version. It is otherwise identical to tr(\a sourceText, \a comment). \warning This method is reentrant only if all translators are installed \e before calling this method. Installing or removing translators while performing translations is not supported. Doing so will probably result in crashes or other undesirable behavior. \warning For portability reasons, we recommend that you use escape sequences for specifying non-ASCII characters in string literals to trUtf8(). For example: \code label->setText(tr("F\252r \310lise")); \endcode \sa tr(), QApplication::translate(), {Internationalization with Qt}*//***************************************************************************** Signals and slots *****************************************************************************/static bool check_signal_macro(const QObject *sender, const char *signal, const char *func, const char *op){ int sigcode = (int)(*signal) - '0'; if (sigcode != QSIGNAL_CODE) { if (sigcode == QSLOT_CODE) qWarning("Object::%s: Attempt to %s non-signal %s::%s", func, op, sender->metaObject()->className(), signal+1); else qWarning("Object::%s: Use the SIGNAL macro to %s %s::%s", func, op, sender->metaObject()->className(), signal); return false; } return true;}static bool check_method_code(int code, const QObject *object, const char *method, const char *func){ if (code != QSLOT_CODE && code != QSIGNAL_CODE) { qWarning("Object::%s: Use the SLOT or SIGNAL macro to " "%s %s::%s", func, func, object->metaObject()->className(), method); return false; } return true;}static void err_method_notfound(int code, const QObject *object, const char *method, const char *func){ const char *type = 0; switch (code) { case QSLOT_CODE: type = "slot"; break; case QSIGNAL_CODE: type = "signal"; break; } if (strchr(method,')') == 0) // common typing mistake qWarning("Object::%s: Parentheses expected, %s %s::%s", func, type, object->metaObject()->className(), method); else qWarning("Object::%s: No such %s %s::%s", func, type, object->metaObject()->className(), method);}static void err_info_about_objects(const char * func, const QObject * sender, const QObject * receiver){ QString a = sender ? sender->objectName() : QString(); QString b = receiver ? receiver->objectName() : QString(); if (!a.isEmpty()) qWarning("Object::%s: (sender name: '%s')", func, a.toLocal8Bit().data()); if (!b.isEmpty()) qWarning("Object::%s: (receiver name: '%s')", func, b.toLocal8Bit().data());}/*! Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. The pointer is valid only during the execution of the slot that calls this function. The pointer returned by this function becomes invalid if the sender is destroyed, or if the slot is disconnected from the sender's signal. \warning This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot. The sender is undefined if the slot is called as a normal C++ function.*/QObject *QObject::sender() const{ Q_D(const QObject); QConnectionList * const list = ::connectionList(); if (!list) return 0; QReadLocker locker(&list->lock); QConnectionList::Hash::const_iterator it = list->sendersHash.find(d->currentSender); const QConnectionList::Hash::const_iterator end = list->sendersHash.constEnd(); // Return 0 if d->currentSender isn't in the senders hash (it has been destroyed?) if (it == end) return 0; // Only return d->currentSender if it's actually connected to "this" for (; it != end && it.key() == d->currentSender; ++it) { const int at = it.value(); const QConnection &c = list->connections.at(at); if (c.receiver == this) return d->currentSender; } return 0;}/*! Returns the number of receivers connect to the \a signal. When calling this function, you can use the \c SIGNAL() macro to pass a specific signal: \code if (receivers(SIGNAL(valueChanged(QByteArray))) > 0) { QByteArray data; get_the_value(&data); // expensive operation emit valueChanged(data); } \endcode As the code snippet above illustrates, you can use this function to avoid emitting a signal that nobody listens to. \warning This function violates the object-oriented principle of modularity. However, it might be useful when you need to perform expensive initialization only if something is connected to a signal.*/int QObject::receivers(const char *signal) const{ int receivers = 0; if (signal) { QByteArray signal_name = QMetaObject::normalizedSignature(signal); signal = signal_name;#ifndef QT_NO_DEBUG if (!check_signal_macro(this, signal, "receivers", "bind")) return 0;#endif signal++; // skip code const QMetaObject *smeta = this->metaObject(); int signal_index = smeta->indexOfSignal(signal); if (signal_index < 0) {#ifndef QT_NO_DEBUG err_method_notfound(QSIGNAL_CODE, this, signal, "receivers");#endif return false; } QConnectionList *list = ::connectionList(); QReadLocker locker(&list->lock); QHash<const QObject *, int>::const_iterator i = list->sendersHash.find(this); while (i != list->sendersHash.constEnd() && i.key() == this) { if (list->connections.at(i.value()).signal == signal_index) ++receivers; ++i; } } return receivers;}/*! \threadsafe Creates a connection of the given \a type from the \a signal in the \a sender object to the \a method in the \a receiver object. Returns true if the connection succeeds; otherwise returns false. You must use the \c SIGNAL() and \c SLOT() macros when specifying the \a signal and the \a method, for example: \code QLabel *label = new QLabel; QScrollBar *scrollBar = new QScrollBar; QObject::connect(scrollBar, SIGNAL(valueChanged(int)), label, SLOT(setNum(int))); \endcode This exam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -