?? qcoreapplication.cpp
字號:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qcoreapplication.h"#include "qcoreapplication_p.h"#include "qabstracteventdispatcher.h"#include "qcoreevent.h"#include "qeventloop.h"#include <qdatastream.h>#include <qdatetime.h>#include <qdebug.h>#include <qdir.h>#include <qfile.h>#include <qfileinfo.h>#include <qhash.h>#include <private/qprocess_p.h>#include <qtextcodec.h>#include <qthread.h>#include <qthreadstorage.h>#include <private/qthread_p.h>#include <qlibraryinfo.h>#ifdef Q_OS_UNIX# if !defined(QT_NO_GLIB)# include "qeventdispatcher_glib_p.h"# endif# include "qeventdispatcher_unix_p.h"#endif#ifdef Q_OS_WIN# include "qeventdispatcher_win_p.h"#endif#include <stdlib.h>#ifdef Q_OS_UNIX#include <locale.h>#endif#if defined(Q_WS_WIN) || defined(Q_WS_MAC)extern QString qAppFileName();#endif#if !defined(Q_OS_WIN)QString QCoreApplicationPrivate::appName() const{ static QString applName; if (applName.isEmpty() && argv[0]) { char *p = strrchr(argv[0], '/'); applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]); } return applName;}#endifbool QCoreApplicationPrivate::checkInstance(const char *function){ bool b = (QCoreApplication::self != 0); if (!b) qWarning("QApplication::%s: Please instantiate the QApplication object first", function); return b;}// Support for introspectionQSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set){ qt_signal_spy_callback_set = callback_set;}extern "C" void Q_CORE_EXPORT qt_startup_hook(){}typedef QList<QtCleanUpFunction> QVFuncList;Q_GLOBAL_STATIC(QVFuncList, postRList)void qAddPostRoutine(QtCleanUpFunction p){ QVFuncList *list = postRList(); if (!list) return; list->prepend(p);}void qRemovePostRoutine(QtCleanUpFunction p){ QVFuncList *list = postRList(); if (!list) return; list->removeAll(p);}void Q_CORE_EXPORT qt_call_post_routines(){ QVFuncList *list = postRList(); if (!list) return; while (!list->isEmpty()) (list->takeFirst())();}// app starting up if falsebool QCoreApplicationPrivate::is_app_running = false; // app closing down if truebool QCoreApplicationPrivate::is_app_closing = false;Q_CORE_EXPORT uint qGlobalPostedEventsCount(){ return QThreadData::current()->postEventList.size();}void qt_set_current_thread_to_main_thread(){ QCoreApplicationPrivate::theMainThread = QThread::currentThread();}QCoreApplication *QCoreApplication::self = 0;QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;uint QCoreApplicationPrivate::attribs;#ifdef Q_OS_UNIXQt::HANDLE qt_application_thread_id = 0;#endifstruct QCoreApplicationData { QCoreApplicationData() {#ifndef QT_NO_LIBRARY app_libpaths = 0;#endif } ~QCoreApplicationData() {#ifndef QT_NO_LIBRARY delete app_libpaths;#endif } QString orgName, orgDomain, application;#ifndef QT_NO_LIBRARY QStringList *app_libpaths;#endif};Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv) : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0), in_exec(false){ static const char *const empty = ""; if (argc == 0 || argv == 0) { argc = 0; argv = (char **)∅ // ouch! careful with QCoreApplication::argv()! } QCoreApplicationPrivate::is_app_closing = false;#ifdef Q_OS_UNIX qt_application_thread_id = QThread::currentThreadId();#endif // note: this call to QThread::currentThread() may end up setting theMainThread! if (QThread::currentThread() != theMainThread) qWarning("WARNING: QApplication was not created in the main() thread.");}QCoreApplicationPrivate::~QCoreApplicationPrivate(){#ifndef QT_NO_THREAD QThreadStorageData::finish(threadData->tls); threadData->tls = 0;#endif // need to clear the state of the mainData, just in case a new QCoreApplication comes along. QMutexLocker locker(&threadData->postEventList.mutex); for (int i = 0; i < threadData->postEventList.size(); ++i) { const QPostEvent &pe = threadData->postEventList.at(i); if (pe.event) { --pe.receiver->d_func()->postedEvents;#ifdef QT3_SUPPORT if (pe.event->type() == QEvent::ChildInserted) --pe.receiver->d_func()->postedChildInsertedEvents;#endif pe.event->posted = false; delete pe.event; } } threadData->postEventList.clear(); threadData->postEventList.recursion = 0; threadData->quitNow = false;}void QCoreApplicationPrivate::createEventDispatcher(){ Q_Q(QCoreApplication);#if defined(Q_OS_UNIX)# if !defined(QT_NO_GLIB) if (qgetenv("QT_NO_GLIB").isEmpty()) eventDispatcher = new QEventDispatcherGlib(q); else# endif eventDispatcher = new QEventDispatcherUNIX(q);#elif defined(Q_OS_WIN) eventDispatcher = new QEventDispatcherWin32(q);#else# error "QEventDispatcher not yet ported to this platform"#endif}QThread *QCoreApplicationPrivate::theMainThread = 0;QThread *QCoreApplicationPrivate::mainThread(){ Q_ASSERT(theMainThread != 0); return theMainThread;}#ifdef QT3_SUPPORTvoid QCoreApplicationPrivate::removePostedChildInsertedEvents(QObject *receiver, QObject *child){ QThreadData *data = receiver->d_func()->threadData; QMutexLocker locker(&data->postEventList.mutex); // the QObject destructor calls QObject::removeChild, which calls // QCoreApplication::sendEvent() directly. this can happen while the event // loop is in the middle of posting events, and when we get here, we may // not have any more posted events for this object. // if this is a child remove event and the child insert // hasn't been dispatched yet, kill that insert for (int i = 0; i < data->postEventList.size(); ++i) { const QPostEvent &pe = data->postEventList.at(i); if (pe.event && pe.receiver == receiver) { if (pe.event->type() == QEvent::ChildInserted && ((QChildEvent*)pe.event)->child() == child) { --receiver->d_func()->postedEvents; --receiver->d_func()->postedChildInsertedEvents; Q_ASSERT(receiver->d_func()->postedEvents >= 0); Q_ASSERT(receiver->d_func()->postedChildInsertedEvents >= 0); pe.event->posted = false; delete pe.event; const_cast<QPostEvent &>(pe).event = 0; const_cast<QPostEvent &>(pe).receiver = 0; } } }}#endifvoid QCoreApplicationPrivate::checkReceiverThread(QObject *receiver){ QThread *currentThread = QThread::currentThread(); QThread *thr = receiver->thread(); Q_ASSERT_X(currentThread == thr || !thr, "QCoreApplication::sendEvent", QString::fromLatin1("Cannot send events to objects owned by a different thread. " "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4") .arg(QString::number((ulong) currentThread, 16)) .arg(receiver->objectName()) .arg(QLatin1String(receiver->metaObject()->className())) .arg(QString::number((ulong) thr, 16)) .toLocal8Bit().data()); Q_UNUSED(currentThread); Q_UNUSED(thr);}void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths(){#ifndef QT_NO_LIBRARY QStringList *app_libpaths = coreappdata()->app_libpaths; Q_ASSERT(app_libpaths); QString app_location( QCoreApplication::applicationFilePath() ); app_location.truncate(app_location.lastIndexOf(QLatin1Char('/'))); app_location = QDir(app_location).canonicalPath(); if (app_location != QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location)) app_libpaths->append(app_location);#endif}QString qAppName(){ if (!QCoreApplicationPrivate::checkInstance("qAppName")) return QString(); return QCoreApplication::instance()->d_func()->appName();}/*! \class QCoreApplication \brief The QCoreApplication class provides an event loop for console Qt applications. \ingroup application \mainclass This class is used by non-GUI applications to provide their event loop. For non-GUI application that uses Qt, there should be exactly one QCoreApplication object. For GUI applications, see QApplication. QCoreApplication contains the main event loop, where all events from the operating system (e.g., timer and network events) and other sources are processed and dispatched. It also handles the application's initialization and finalization, as well as system-wide and application-wide settings. The command line arguments which QCoreApplication's constructor should be called with are accessible using arguments(). The event loop is started with a call to exec(). Long running operations can call processEvents() to keep the application responsive. Some Qt classes, such as QString, can be used without a QCoreApplication object. However, in general, we recommend that you create a QCoreApplication or a QApplication object in your \c main() function as early as possible. An application has an applicationDirPath() and an applicationFilePath(). Translation files can be added or removed using installTranslator() and removeTranslator(). Application strings can be translated using translate(). The QObject::tr() and QObject::trUtf8() functions are implemented in terms of translate(). The class provides a quit() slot and an aboutToQuit() signal. Several static convenience functions are also provided. The QCoreApplication object is available from instance(). Events can be sent or posted using sendEvent(), postEvent(), and sendPostedEvents(). Pending events can be removed with removePostedEvents() or flushed with flush(). Library paths (see QLibrary) can be retrieved with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(), and removeLibraryPath(). \sa QApplication, QAbstractEventDispatcher, QEventLoop*//*! \fn static QCoreApplication *QCoreApplication::instance() Returns a pointer to the application's QCoreApplication (or QApplication) instance.*//*!\internal */QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p) : QObject(p, 0){ init(); // note: it is the subclasses' job to call // QCoreApplicationPrivate::eventDispatcher->startingUp();}/*! Flushes the platform specific event queues. If you are doing graphical changes inside a loop that does not return to the event loop on asynchronous window systems like X11 or double buffered window systems like Mac OS X, and you want to visualize these changes immediately (e.g. Splash Screens), call this function. \sa sendPostedEvents()*/void QCoreApplication::flush(){ if (self && self->d_func()->eventDispatcher) self->d_func()->eventDispatcher->flush();}/*! Constructs a Qt kernel application. Kernel applications are applications without a graphical user interface. These type of 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_OS_UNIX setlocale(LC_ALL, ""); // use correct char set mapping setlocale(LC_NUMERIC, "C"); // make sprintf()/scanf() work#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -