📄 qcoreapplication.cpp
字号:
// Get the application name/instance if qWinMain() was not invoked set_winapp_name();#endif Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object"); QCoreApplication::self = this;#ifndef QT_NO_THREAD QThread::initialize();#endif // use the event dispatcher created by the app programmer (if any) if (!QCoreApplicationPrivate::eventDispatcher) QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher; // otherwise we create one if (!QCoreApplicationPrivate::eventDispatcher) d->createEventDispatcher(); Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0); if (!QCoreApplicationPrivate::eventDispatcher->parent()) QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread); d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;#ifndef QT_NO_LIBRARY if (!coreappdata()->app_libpaths) { // make sure that library paths is initialized libraryPaths(); } else { d->appendApplicationPathToLibraryPaths(); }#endif#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS)) // Make sure the process manager thread object is created in the main // thread. QProcessPrivate::initializeProcessManager();#endif#ifdef QT_EVAL extern void qt_core_eval_init(uint); qt_core_eval_init(d->application_type);#endif qt_startup_hook();}/*! Destroys the QCoreApplication object.*/QCoreApplication::~QCoreApplication(){ qt_call_post_routines(); self = 0; QCoreApplicationPrivate::is_app_closing = true; QCoreApplicationPrivate::is_app_running = false;#ifndef QT_NO_THREAD QThread::cleanup();#endif d_func()->threadData->eventDispatcher = 0; if (QCoreApplicationPrivate::eventDispatcher) QCoreApplicationPrivate::eventDispatcher->closingDown(); QCoreApplicationPrivate::eventDispatcher = 0;}/*! Sets the attribute \a attribute if \a on is true; otherwise clears the attribute. One of the attributes that can be set with this method is Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel windows immediately. Normally, resources for widgets are allocated on demand to improve efficiency and minimize resource usage. Therefore, if it is important to minimize resource consumption, do not set this attribute. \sa testAttribute()*/void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on){ if (on) QCoreApplicationPrivate::attribs |= 1 << attribute; else QCoreApplicationPrivate::attribs &= ~(1 << attribute);}/*! Returns true if attribute \a attribute is set; otherwise returns false. \sa setAttribute() */bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute){ return QCoreApplicationPrivate::testAttribute(attribute);}/*! \internal This function is here to make it possible for Qt extensions to hook into event notification without subclassing QApplication*/bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event){ // Make it possible for Qt JAmbi and QSA to hook into events even // though QApplication is subclassed... bool result = false; void *cbdata[] = { receiver, event, &result }; if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) { return result; } return notify(receiver, event);}/*! Sends \a event to \a receiver: \a {receiver}->event(\a event). Returns the value that is returned from the receiver's event handler. For certain types of events (e.g. mouse and key events), the event will be propagated to the receiver's parent and so on up to the top-level object if the receiver is not interested in the event (i.e., it returns false). There are five different ways that events can be processed; reimplementing this virtual function is just one of them. All five approaches are listed below: \list 1 \i Reimplementing paintEvent(), mousePressEvent() and so on. This is the commonest, easiest and least powerful way. \i Reimplementing this function. This is very powerful, providing complete control; but only one subclass can be active at a time. \i Installing an event filter on QCoreApplication::instance(). Such an event filter is able to process all events for all widgets, so it's just as powerful as reimplementing notify(); furthermore, it's possible to have more than one application-global event filter. Global event filters even see mouse events for \l{QWidget::isEnabled()}{disabled widgets}. \i Reimplementing QObject::event() (as QWidget does). If you do this you get Tab key presses, and you get to see the events before any widget-specific event filters. \i Installing an event filter on the object. Such an event filter gets all the events except Tab and Shift-Tab key presses. \endlist \sa QObject::event(), installEventFilter()*/bool QCoreApplication::notify(QObject *receiver, QEvent *event){ Q_D(QCoreApplication); // no events are delivered after ~QCoreApplication() has started if (QCoreApplicationPrivate::is_app_closing) return true; if (receiver == 0) { // serious error qWarning("QCoreApplication::notify: Unexpected null receiver"); return true; }#ifndef QT_NO_DEBUG d->checkReceiverThread(receiver);#endif#ifdef QT3_SUPPORT if (event->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty()) receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(event)->child());#endif // QT3_SUPPORT return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);}/*!\internal Helper function called by notify() */bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event){ Q_Q(QCoreApplication); QReadWriteLock *lock = QObjectPrivate::readWriteLock(); if (lock) lock->lockForRead(); // send to all application event filters for (int i = 0; i < eventFilters.size(); ++i) { register QObject *obj = eventFilters.at(i); if (lock) lock->unlock(); if (obj && obj->eventFilter(receiver, event)) return true; if (lock) lock->lockForRead(); } // send to all receiver event filters if (receiver != q) { for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) { register QObject *obj = receiver->d_func()->eventFilters.at(i); if (lock) lock->unlock(); if (obj && obj->eventFilter(receiver, event)) return true; if (lock) lock->lockForRead(); } } if (lock) lock->unlock(); return receiver->event(event);}/*! Returns true if an application object has not been created yet; otherwise returns false. \sa closingDown()*/bool QCoreApplication::startingUp(){ return !QCoreApplicationPrivate::is_app_running;}/*! Returns true if the application objects are being destroyed; otherwise returns false. \sa startingUp()*/bool QCoreApplication::closingDown(){ return QCoreApplicationPrivate::is_app_closing;}/*! Processes all pending events for the calling thread according to the specified \a flags until there are no more events to process. You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file). In event you are running a local loop which calls this function continuously, without an event loop, the \l{QEvent::DeferredDelete}{DeferredDelete} events will not be processed. This can affect the behaviour of widgets, e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete} events to function properly. An alternative would be to call \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from within that local loop. Calling this function processes events only for the calling thread. \threadsafe \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()*/void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags){ QThreadData *data = QThreadData::current(); if (!data->eventDispatcher) return; data->eventDispatcher->processEvents(flags);}/*! \overload Processes pending events for the calling thread for \a maxtime milliseconds or until there are no more events to process, whichever is shorter. You can call this function occasionally when you program is busy doing a long operation (e.g. copying a file). Calling this function processes events only for the calling thread. \threadsafe \sa exec(), QTimer, QEventLoop::processEvents()*/void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime){ QThreadData *data = QThreadData::current(); if (!data->eventDispatcher) return; QTime start; start.start(); while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { if (start.elapsed() > maxtime) break; }}/***************************************************************************** Main event loop wrappers *****************************************************************************//*! Enters the main event loop and waits until exit() is called. Returns the value that was set to exit() (which is 0 if exit() is called via quit()). It is necessary to call this function to start event handling. The main event loop receives events from the window system and dispatches these to the application widgets. To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More advanced idle processing schemes can be achieved using processEvents(). \sa quit(), exit(), processEvents(), QApplication::exec()*/int QCoreApplication::exec(){ if (!QCoreApplicationPrivate::checkInstance("exec")) return -1; QThreadData *threadData = self->d_func()->threadData; if (threadData != QThreadData::current()) { qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className()); return -1; } if (!threadData->eventLoops.isEmpty()) { qWarning("QCoreApplication::exec: The event loop is already running"); return -1; } threadData->quitNow = false; QEventLoop eventLoop; self->d_func()->in_exec = true; int returnCode = eventLoop.exec(); threadData->quitNow = false; if (self) { self->d_func()->in_exec = false; emit self->aboutToQuit(); sendPostedEvents(0, QEvent::DeferredDelete); } return returnCode;}/*! Tells the application to exit with a return code. After this function has been called, the application leaves the main event loop and returns from the call to exec(). The exec() function returns \a returnCode. If the event loop is not running, this function does nothing. By convention, a \a returnCode of 0 means success, and any non-zero value indicates an error. Note that unlike the C library function of the same name, this function \e does return to the caller -- it is event processing that stops. \sa quit(), exec()*/void QCoreApplication::exit(int returnCode){ if (!self) return; QThreadData *data = self->d_func()->threadData; data->quitNow = true; for (int i = 0; i < data->eventLoops.size(); ++i) { QEventLoop *eventLoop = data->eventLoops.at(i); eventLoop->exit(returnCode); }}/***************************************************************************** QCoreApplication management of posted events *****************************************************************************//*! \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) Sends event \a event directly to receiver \a receiver, using the notify() function. Returns the value that was returned from the event handler. The event is \e not deleted when the event has been sent. The normal approach is to create the event on the stack, for example: \code QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0); QApplication::sendEvent(mainWindow, &event); \endcode \sa postEvent(), notify()*//*! Adds the event \a event, with the object \a receiver as the receiver of the event, to an event queue and returns immediately.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -