?? qobject.cpp
字號:
to retrieve a pointer to the current application, and then use QApplication::thread() to retrieve the thread in which the application lives. For example: \code myObject->moveToThread(QApplication::instance()->thread()); \endcode If \a targetThread is zero, all event processing for this object and its children stops. Note that all active timers for the object will be reset. The timers are first stopped in the current thread and restarted (with the same interval) in the \a targetThread. As a result, constantly moving an object between threads can postpone timer events indefinitely. \warning This function is \e not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only "push" an object from the current thread to another thread, it cannot "pull" an object from any arbitrary thread to the current thread. \sa thread() */void QObject::moveToThread(QThread *targetThread){ Q_D(QObject); if (d->threadData->thread == targetThread) { // object is already in this thread return; } if (d->parent != 0) { qWarning("QObject::moveToThread: Cannot move objects with a parent"); return; } if (d->isWidget) { qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread"); return; } QThreadData *currentData = QThreadData::current(); QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0); if (d->threadData->thread == 0 && currentData == targetData) { // one exception to the rule: we allow moving objects with no thread affinity to the current thread currentData = d->threadData; } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", d->threadData->thread, currentData->thread, targetData->thread); return; } // prepare to move d->moveToThread_helper(); QWriteLocker locker(QObjectPrivate::readWriteLock()); if (currentData != targetData) { targetData->postEventList.mutex.lock(); while (currentData && !currentData->postEventList.mutex.tryLock()) { targetData->postEventList.mutex.unlock(); targetData->postEventList.mutex.lock(); } } // keep currentData alive (since we've got it locked) currentData->ref(); // move the object d_func()->setThreadData_helper(currentData, targetData); if (currentData != targetData) { targetData->postEventList.mutex.unlock(); if (currentData) currentData->postEventList.mutex.unlock(); } // now currentData can commit suicide if it wants to currentData->deref();}void QObjectPrivate::moveToThread_helper(){ Q_Q(QObject); QEvent e(QEvent::ThreadChange); QCoreApplication::sendEvent(q, &e); for (int i = 0; i < children.size(); ++i) { QObject *child = children.at(i); child->d_func()->moveToThread_helper(); }}void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData){ Q_Q(QObject); // move posted events int eventsMoved = 0; for (int i = 0; i < currentData->postEventList.size(); ++i) { const QPostEvent &pe = currentData->postEventList.at(i); if (!pe.event) continue; if (pe.receiver == q) { // move this post event to the targetList targetData->postEventList.append(pe); const_cast<QPostEvent &>(pe).event = 0; ++eventsMoved; } } if (eventsMoved > 0 && targetData->eventDispatcher) targetData->eventDispatcher->wakeUp(); // set new thread data targetData->ref(); threadData->deref(); threadData = targetData; for (int i = 0; i < children.size(); ++i) { QObject *child = children.at(i); child->d_func()->setThreadData_helper(currentData, targetData); }}void QObjectPrivate::_q_reregisterTimers(void *pointer){ Q_Q(QObject); QList<QPair<int, int> > *timerList = reinterpret_cast<QList<QPair<int, int> > *>(pointer); QAbstractEventDispatcher *eventDispatcher = threadData->eventDispatcher; for (int i = 0; i < timerList->size(); ++i) { const QPair<int, int> &pair = timerList->at(i); eventDispatcher->registerTimer(pair.first, pair.second, q); } delete timerList;}//// The timer flag hasTimer is set when startTimer is called.// It is not reset when killing the timer because more than// one timer might be active.///*! Starts a timer and returns a timer identifier, or returns zero if it could not start a timer. A timer event will occur every \a interval milliseconds until killTimer() is called. If \a interval is 0, then the timer event occurs once every time there are no more window system events to process. The virtual timerEvent() function is called with the QTimerEvent event parameter class when a timer event occurs. Reimplement this function to get timer events. If multiple timers are running, the QTimerEvent::timerId() can be used to find out which timer was activated. Example: \code class MyObject : public QObject { Q_OBJECT public: MyObject(QObject *parent = 0); protected: void timerEvent(QTimerEvent *event); }; MyObject::MyObject(QObject *parent) : QObject(parent) { startTimer(50); // 50-millisecond timer startTimer(1000); // 1-second timer startTimer(60000); // 1-minute timer } void MyObject::timerEvent(QTimerEvent *event) { qDebug() << "Timer ID:" << event->timerId(); } \endcode Note that QTimer's accuracy depends on the underlying operating system and hardware. Most platforms support an accuracy of 20 milliseconds; some provide more. If Qt is unable to deliver the requested number of timer events, it will silently discard some. The QTimer class provides a high-level programming interface with single-shot timers and timer signals instead of events. There is also a QBasicTimer class that is more lightweight than QTimer and less clumsy than using timer IDs directly. \sa timerEvent(), killTimer(), QTimer::singleShot()*/int QObject::startTimer(int interval){ Q_D(QObject); if (interval < 0) { qWarning("QObject::startTimer: QTimer cannot have a negative interval"); return 0; } d->pendTimer = true; // set timer flag if (!d->threadData->eventDispatcher) { qWarning("QObject::startTimer: QTimer can only be used with threads started with QThread"); return 0; } return d->threadData->eventDispatcher->registerTimer(interval, this);}/*! Kills the timer with timer identifier, \a id. The timer identifier is returned by startTimer() when a timer event is started. \sa timerEvent(), startTimer()*/void QObject::killTimer(int id){ Q_D(QObject); if (d->threadData->eventDispatcher) d->threadData->eventDispatcher->unregisterTimer(id);}/*! \fn QObject *QObject::parent() const Returns a pointer to the parent object. \sa children()*//*! \fn const QObjectList &QObject::children() const Returns a list of child objects. The QObjectList class is defined in the \c{<QObject>} header file as the following: \quotefromfile src/corelib/kernel/qobject.h \skipto /typedef .*QObjectList/ \printuntil QObjectList The first child added is the \l{QList::first()}{first} object in the list and the last child added is the \l{QList::last()}{last} object in the list, i.e. new children are appended at the end. Note that the list order changes when QWidget children are \l{QWidget::raise()}{raised} or \l{QWidget::lower()}{lowered}. A widget that is raised becomes the last object in the list, and a widget that is lowered becomes the first object in the list. \sa findChild(), findChildren(), parent(), setParent()*/#ifdef QT3_SUPPORTstatic void objSearch(QObjectList &result, const QObjectList &list, const char *inheritsClass, bool onlyWidgets, const char *objName, QRegExp *rx, bool recurse){ for (int i = 0; i < list.size(); ++i) { QObject *obj = list.at(i); bool ok = true; if (onlyWidgets) ok = obj->isWidgetType(); else if (inheritsClass && !obj->inherits(inheritsClass)) ok = false; if (ok) { if (objName) ok = (obj->objectName() == QLatin1String(objName));#ifndef QT_NO_REGEXP else if (rx) ok = (rx->indexIn(obj->objectName()) != -1);#endif } if (ok) // match! result.append(obj); if (recurse) { QObjectList clist = obj->children(); if (!clist.isEmpty()) objSearch(result, clist, inheritsClass, onlyWidgets, objName, rx, recurse); } }}/*! \internal Searches the children and optionally grandchildren of this object, and returns a list of those objects that are named or that match \a objName and inherit \a inheritsClass. If \a inheritsClass is 0 (the default), all classes match. If \a objName is 0 (the default), all object names match. If \a regexpMatch is true (the default), \a objName is a regular expression that the objects's names must match. The syntax is that of a QRegExp. If \a regexpMatch is false, \a objName is a string and object names must match it exactly. Note that \a inheritsClass uses single inheritance from QObject, the way inherits() does. According to inherits(), QWidget inherits QObject but not QPaintDevice. This does not quite match reality, but is the best that can be done on the wide variety of compilers Qt supports. Finally, if \a recursiveSearch is true (the default), queryList() searches \e{n}th-generation as well as first-generation children. If all this seems a bit complex for your needs, the simpler child() function may be what you want. This somewhat contrived example disables all the buttons in this window: \code QList<QObject *> list = window()->queryList("QAbstractButton")); foreach (QObject *obj, list) static_cast<QAbstractButton *>(obj)->setEnabled(false); \endcode \warning Delete the list as soon you have finished using it. The list contains pointers that may become invalid at almost any time without notice (as soon as the user closes a window you may have dangling pointers, for example). \sa child() children(), parent(), inherits(), objectName(), QRegExp*/QObjectList QObject::queryList(const char *inheritsClass, const char *objName, bool regexpMatch, bool recursiveSearch) const{ Q_D(const QObject); QObjectList list; bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);#ifndef QT_NO_REGEXP if (regexpMatch && objName) { // regexp matching QRegExp rx(QString::fromLatin1(objName)); objSearch(list, d->children, inheritsClass, onlyWidgets, 0, &rx, recursiveSearch); } else#endif { objSearch(list, d->children, inheritsClass, onlyWidgets, objName, 0, recursiveSearch); } return list;}#endif/*! \fn T *QObject::findChild(const QString &name) const Returns the child of this object that can be casted into type T and that is called \a name, or 0 if there is no such object. An empty string matches all object names. The search is performed recursively. If there is more than one child matching the search, the most direct ancestor is returned. If there are several direct ancestors, it is undefined which one will be returned. In that case, findChildren() should be used. This example returns a child \l{QPushButton} of \c{parentWidget} named \c{"button1"}: \code QPushButton *button = parentWidget->findChild<QPushButton *>("button1"); \endcode This example returns a \l{QListWidget} child of \c{parentWidget}: \code QListWidget *list = parentWidget->findChild<QListWidget *>(); \endcode \warning This function is not available with MSVC 6. Use qFindChild() instead if you need to support that version of the compiler. \sa findChildren(), qFindChild()*//*! \fn QList<T> QObject::findChildren(const QString &name) const Returns all children of this object with the given \a name that can be cast to type T, or an empty list if there are no such objects. An empty string matches all object names. The search is performed recursively. The following example shows how to find a list of child \l{QWidget}s of the specified \c{parentWidget} named \c{widgetname}: \code QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>("widgetname"); \endcode This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -