📄 qcoreapplication.cpp
字号:
applications are used at the console or as server processes. The \a argc and \a argv arguments are processed by the application, and made available in a more convenient form by the arguments() function.*/QCoreApplication::QCoreApplication(int &argc, char **argv) : QObject(*new QCoreApplicationPrivate(argc, argv)){ init(); QCoreApplicationPrivate::eventDispatcher->startingUp();}extern void set_winapp_name();// ### move to QCoreApplicationPrivate constructor?void QCoreApplication::init(){ Q_D(QCoreApplication);#ifdef Q_WS_WIN // 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_LIBRARY if (!coreappdata()->app_libpaths) { // make sure that library paths is initialized libraryPaths(); } else { d->appendApplicationPathToLibraryPaths(); }#endif#ifndef QT_NO_THREAD QThread::initialize();#endif if (!QCoreApplicationPrivate::eventDispatcher) d->createEventDispatcher(); Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0); QCoreApplicationPrivate::moveToMainThread(QCoreApplicationPrivate::eventDispatcher); QThreadData *data = QThreadData::get(mainThread()); data->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;#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(){ Q_D(QCoreApplication); qt_call_post_routines(); self = 0; QCoreApplicationPrivate::is_app_closing = true; QCoreApplicationPrivate::is_app_running = false;#ifndef QT_NO_THREAD QThread::cleanup();#endif QThreadData::get(mainThread())->eventDispatcher = 0; if (d->eventDispatcher) d->eventDispatcher->closingDown(); d->eventDispatcher = 0;}/*! 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; } d->checkReceiverThread(receiver);#ifdef QT3_SUPPORT if (event->type() == QEvent::ChildRemoved && receiver->d_func()->postedChildInsertedEvents) d->removePostedChildInsertedEvents(receiver, 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); // send to all application event filters for (int i = 0; i < eventFilters.size(); ++i) { register QObject *obj = eventFilters.at(i); if (obj && obj->eventFilter(receiver, event)) return true; } // 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 (obj && obj->eventFilter(receiver, event)) return true; } } 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 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). \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()*/void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags){ QThread *currentThread = QThread::currentThread(); if (!currentThread) return; QThreadData::get(currentThread)->eventDispatcher->processEvents(flags);}/*! \overload Processes pending events 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). \sa exec(), QTimer, QEventLoop::processEvents()*/void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime){ QThread *currentThread = QThread::currentThread(); if (!currentThread) return; QThreadData *data = QThreadData::get(currentThread); 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; QThread *currentThread = QThread::currentThread(); if (currentThread != self->thread()) { qWarning("QApplication::exec() failed: must be called from the main thread."); return -1; } QThreadData *data = QThreadData::get(currentThread); if (!data->eventLoops.isEmpty()) { qWarning("QApplication::exec() failed: the event loop is already running."); return -1; } data->quitNow = false; QEventLoop eventLoop; self->d_func()->in_exec = true; int returnCode = eventLoop.exec(); data->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. 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 = QThreadData::get(self->thread()); 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); 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. The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted. It is \e {not safe} to modify or delete the event after it has been posted. When control returns to the main event loop, all events that are stored in the queue will be sent using the notify() function. \threadsafe \sa sendEvent(), notify(), sendPostedEvent()*/void QCoreApplication::postEvent(QObject *receiver, QEvent *event){ if (receiver == 0) { qWarning("QCoreApplication::postEvent: Unexpected null receiver"); delete event; return; }#ifndef QT_NO_THREAD // uberhack for enabling some threading features for (mumble) if (receiver == (QObject *) 0xfeedface && event == (QEvent *) 0xc0ffee) { QThreadPrivate::adoptCurrentThreadEnabled = true; if (!the_mainThread) the_mainThread = new QAdoptedThread(); return; }#endif /* avoid a deadlock when trying to create the mainThread() when posting the very first event in an application with a QCoreApplication */ (void) mainThread(); QReadLocker locker(QObjectPrivate::readWriteLock()); if (!QObjectPrivate::isValidObject(receiver)) { qWarning("QCoreApplication::postEvent: Receiver is not a valid QObject"); delete event; return; } QThread *thread = receiver->thread(); if (!thread) thread = mainThread(); if (!thread) { // posting during destruction? just delete the event to prevent a leak delete event; return; } QThreadData *data = QThreadData::get(thread); { QMutexLocker locker(&data->postEventList.mutex); // if this is one of the compressible events, do compression if (receiver->d_func()->postedEvents && self && self->compressEvent(event, receiver, &data->postEventList)) { delete event; return; } event->posted = true; ++receiver->d_func()->postedEvents;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -