1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qcoreapplication.h"
43 #include "qcoreapplication_p.h"
45 #include "qabstracteventdispatcher.h"
46 #include "qcoreevent.h"
47 #include "qeventloop.h"
48 #include "qcorecmdlineargs_p.h"
49 #include <qdatastream.h>
53 #include <qfileinfo.h>
55 #include <private/qprocess_p.h>
56 #include <qtextcodec.h>
58 #include <qthreadpool.h>
59 #include <qthreadstorage.h>
60 #include <private/qthread_p.h>
61 #include <qelapsedtimer.h>
62 #include <qlibraryinfo.h>
63 #include <qvarlengtharray.h>
64 #include <private/qfactoryloader_p.h>
65 #include <private/qfunctions_p.h>
66 #include <private/qlocale_p.h>
72 # include "qeventdispatcher_symbian_p.h"
73 # include "private/qcore_symbian_p.h"
74 # include "private/qfilesystemengine_p.h"
75 # include <apacmdln.h>
76 #elif defined(Q_OS_UNIX)
77 # if !defined(QT_NO_GLIB)
78 # include "qeventdispatcher_glib_p.h"
80 # include "qeventdispatcher_unix_p.h"
84 # include "qeventdispatcher_win_p.h"
88 # include "qcore_mac_p.h"
106 inline explicit QMutexUnlocker(QMutex *m)
109 inline ~QMutexUnlocker() { unlock(); }
110 inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; }
113 Q_DISABLE_COPY(QMutexUnlocker)
119 typedef TDriveNumber (*SystemDriveFunc)(RFs&);
120 static SystemDriveFunc PtrGetSystemDrive = 0;
121 static CApaCommandLine* apaCommandLine = 0;
122 static char *apaTail = 0;
123 static QVector<char *> *apaArgv = 0;
125 static void qt_cleanup_apa_cmd_line()
127 delete apaCommandLine;
135 static inline void qt_init_symbian_apa_arguments(int &argc, char **&argv)
137 // If app is launched via CApaCommandLine::StartApp(), normal arguments only contain
140 CApaCommandLine* commandLine = QCoreApplicationPrivate::symbianCommandLine();
142 TPtrC8 apaCmdLine = commandLine->TailEnd();
143 int tailLen = apaCmdLine.Length();
145 apaTail = reinterpret_cast<char *>(qMalloc(tailLen + 1));
146 qMemCopy(apaTail, reinterpret_cast<const char *>(apaCmdLine.Ptr()), tailLen);
147 apaTail[tailLen] = '\0';
148 apaArgv = new QVector<char *>(8);
149 // Reuse windows command line parsing
150 *apaArgv = qWinCmdLine<char>(apaTail, tailLen, argc);
151 apaArgv->insert(0, argv[0]);
153 argv = apaArgv->data();
159 CApaCommandLine* QCoreApplicationPrivate::symbianCommandLine()
161 // Getting of Apa command line needs to be static as it can only be called successfully
163 if (!apaCommandLine) {
164 TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(apaCommandLine);
165 if (err == KErrNone) {
166 qAddPostRoutine(qt_cleanup_apa_cmd_line);
169 return apaCommandLine;
174 #if defined(Q_OS_WIN) || defined(Q_WS_MAC)
175 extern QString qAppFileName();
178 int QCoreApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
180 #if !defined(Q_OS_WIN)
182 QString QCoreApplicationPrivate::macMenuBarName()
185 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
187 bundleName = QCFString::toQString(static_cast<CFStringRef>(string));
191 QString QCoreApplicationPrivate::appName() const
193 static QString applName;
195 applName = macMenuBarName();
197 if (applName.isEmpty() && argv[0]) {
198 char *p = strrchr(argv[0], '/');
199 applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
205 bool QCoreApplicationPrivate::checkInstance(const char *function)
207 bool b = (QCoreApplication::self != 0);
209 qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
213 void QCoreApplicationPrivate::processCommandLineArguments()
215 int j = argc ? 1 : 0;
216 for (int i = 1; i < argc; ++i) {
217 if (argv[i] && *argv[i] != '-') {
221 QByteArray arg = argv[i];
222 if (arg.startsWith("-qmljsdebugger=")) {
223 qmljs_debug_arguments = QString::fromLocal8Bit(arg.right(arg.length() - 15));
235 // Support for introspection
237 QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
239 void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
241 qt_signal_spy_callback_set = callback_set;
244 extern "C" void Q_CORE_EXPORT qt_startup_hook()
248 typedef QList<QtCleanUpFunction> QVFuncList;
249 Q_GLOBAL_STATIC(QVFuncList, postRList)
251 void qAddPostRoutine(QtCleanUpFunction p)
253 QVFuncList *list = postRList();
259 void qRemovePostRoutine(QtCleanUpFunction p)
261 QVFuncList *list = postRList();
267 void Q_CORE_EXPORT qt_call_post_routines()
269 QVFuncList *list = 0;
272 } QT_CATCH(const std::bad_alloc &) {
273 // ignore - if we can't allocate a post routine list,
274 // there's a high probability that there's no post
275 // routine to be executed :)
279 while (!list->isEmpty())
280 (list->takeFirst())();
284 // app starting up if false
285 bool QCoreApplicationPrivate::is_app_running = false;
286 // app closing down if true
287 bool QCoreApplicationPrivate::is_app_closing = false;
288 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
289 Q_CORE_EXPORT bool qt_locale_initialized = false;
291 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
293 QThreadData *currentThreadData = QThreadData::current();
294 return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
298 void qt_set_current_thread_to_main_thread()
300 QCoreApplicationPrivate::theMainThread = QThread::currentThread();
305 QCoreApplication *QCoreApplication::self = 0;
306 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
307 uint QCoreApplicationPrivate::attribs;
310 Qt::HANDLE qt_application_thread_id = 0;
313 struct QCoreApplicationData {
314 QCoreApplicationData() {
315 #ifndef QT_NO_LIBRARY
319 ~QCoreApplicationData() {
320 #ifndef QT_NO_LIBRARY
324 // cleanup the QAdoptedThread created for the main() thread
325 if (QCoreApplicationPrivate::theMainThread) {
326 QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
327 QCoreApplicationPrivate::theMainThread = 0;
328 data->deref(); // deletes the data and the adopted thread
331 QString orgName, orgDomain, application;
332 QString applicationVersion;
334 #ifndef QT_NO_LIBRARY
335 QStringList *app_libpaths;
340 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
342 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
343 : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
344 in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
346 app_compile_version = flags & 0xffffff;
347 static const char *const empty = "";
348 if (argc == 0 || argv == 0) {
350 argv = (char **)∅ // ouch! careful with QCoreApplication::argv()!
352 QCoreApplicationPrivate::is_app_closing = false;
355 qt_init_symbian_apa_arguments(argc, argv);
359 qt_application_thread_id = QThread::currentThreadId();
362 // note: this call to QThread::currentThread() may end up setting theMainThread!
363 if (QThread::currentThread() != theMainThread)
364 qWarning("WARNING: QApplication was not created in the main() thread.");
367 QCoreApplicationPrivate::~QCoreApplicationPrivate()
372 void QCoreApplicationPrivate::cleanupThreadData()
374 if (threadData && !threadData_clean) {
376 void *data = &threadData->tls;
377 QThreadStorageData::finish((void **)data);
380 // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
381 QMutexLocker locker(&threadData->postEventList.mutex);
382 for (int i = 0; i < threadData->postEventList.size(); ++i) {
383 const QPostEvent &pe = threadData->postEventList.at(i);
385 --pe.receiver->d_func()->postedEvents;
386 pe.event->posted = false;
390 threadData->postEventList.clear();
391 threadData->postEventList.recursion = 0;
392 threadData->quitNow = false;
393 threadData_clean = true;
397 void QCoreApplicationPrivate::createEventDispatcher()
399 Q_Q(QCoreApplication);
400 #if defined(Q_OS_SYMBIAN)
401 eventDispatcher = new QEventDispatcherSymbian(q);
402 #elif defined(Q_OS_UNIX)
403 # if !defined(QT_NO_GLIB)
404 if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
405 eventDispatcher = new QEventDispatcherGlib(q);
408 eventDispatcher = new QEventDispatcherUNIX(q);
409 #elif defined(Q_OS_WIN)
410 eventDispatcher = new QEventDispatcherWin32(q);
412 # error "QEventDispatcher not yet ported to this platform"
416 void QCoreApplicationPrivate::_q_initializeProcessManager()
418 #ifndef QT_NO_PROCESS
420 QProcessPrivate::initializeProcessManager();
426 QThread *QCoreApplicationPrivate::theMainThread = 0;
427 QThread *QCoreApplicationPrivate::mainThread()
429 Q_ASSERT(theMainThread != 0);
430 return theMainThread;
433 #if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
434 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
436 QThread *currentThread = QThread::currentThread();
437 QThread *thr = receiver->thread();
438 Q_ASSERT_X(currentThread == thr || !thr,
439 "QCoreApplication::sendEvent",
440 QString::fromLatin1("Cannot send events to objects owned by a different thread. "
441 "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
442 .arg(QString::number((quintptr) currentThread, 16))
443 .arg(receiver->objectName())
444 .arg(QLatin1String(receiver->metaObject()->className()))
445 .arg(QString::number((quintptr) thr, 16))
446 .toLocal8Bit().data());
447 Q_UNUSED(currentThread);
450 #elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG)
451 // no implementation in release builds, but keep the symbol present
452 void QCoreApplicationPrivate::checkReceiverThread(QObject * /* receiver */)
457 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
459 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
460 QStringList *app_libpaths = coreappdata()->app_libpaths;
461 Q_ASSERT(app_libpaths);
462 # if defined(Q_OS_SYMBIAN)
463 QString app_location( QCoreApplication::applicationDirPath() );
464 // File existence check for application's private dir requires additional '\' or
465 // platform security will not allow it.
466 if (app_location != QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location + QLatin1Char('\\')) && !app_libpaths->contains(app_location))
468 QString app_location( QCoreApplication::applicationFilePath() );
469 app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
470 app_location = QDir(app_location).canonicalPath();
471 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
473 app_libpaths->append(app_location);
479 if (!QCoreApplicationPrivate::checkInstance("qAppName"))
481 return QCoreApplication::instance()->d_func()->appName();
485 \class QCoreApplication
486 \brief The QCoreApplication class provides an event loop for console Qt
489 This class is used by non-GUI applications to provide their event
490 loop. For non-GUI application that uses Qt, there should be exactly
491 one QCoreApplication object. For GUI applications, see
494 QCoreApplication contains the main event loop, where all events
495 from the operating system (e.g., timer and network events) and
496 other sources are processed and dispatched. It also handles the
497 application's initialization and finalization, as well as
498 system-wide and application-wide settings.
500 \section1 The Event Loop and Event Handling
502 The event loop is started with a call to exec(). Long running
503 operations can call processEvents() to keep the application
506 In general, we recommend that you create a QCoreApplication or a
507 QApplication object in your \c main() function as early as
508 possible. exec() will not return until the event loop exits; e.g.,
509 when quit() is called.
511 Several static convenience functions are also provided. The
512 QCoreApplication object is available from instance(). Events can
513 be sent or posted using sendEvent(), postEvent(), and
514 sendPostedEvents(). Pending events can be removed with
515 removePostedEvents() or flushed with flush().
517 The class provides a quit() slot and an aboutToQuit() signal.
519 \section1 Application and Library Paths
521 An application has an applicationDirPath() and an
522 applicationFilePath(). Library paths (see QLibrary) can be retrieved
523 with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
524 and removeLibraryPath().
526 \section1 Internationalization and Translations
528 Translation files can be added or removed
529 using installTranslator() and removeTranslator(). Application
530 strings can be translated using translate(). The QObject::tr()
531 and QObject::trUtf8() functions are implemented in terms of
534 \section1 Accessing Command Line Arguments
536 The command line arguments which are passed to QCoreApplication's
537 constructor should be accessed using the arguments() function.
538 Note that some arguments supplied by the user may have been
539 processed and removed by QCoreApplication.
541 In cases where command line arguments need to be obtained using the
542 argv() function, you must convert them from the local string encoding
543 using QString::fromLocal8Bit().
545 \section1 Locale Settings
547 On Unix/Linux Qt is configured to use the system locale settings by
548 default. This can cause a conflict when using POSIX functions, for
549 instance, when converting between data types such as floats and
550 strings, since the notation may differ between locales. To get
551 around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
552 right after initializing QApplication or QCoreApplication to reset
553 the locale that is used for number formatting to "C"-locale.
555 \sa QApplication, QAbstractEventDispatcher, QEventLoop,
556 {Semaphores Example}, {Wait Conditions Example}
560 \fn static QCoreApplication *QCoreApplication::instance()
562 Returns a pointer to the application's QCoreApplication (or
563 QApplication) instance.
565 If no instance has been allocated, \c null is returned.
570 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
574 // note: it is the subclasses' job to call
575 // QCoreApplicationPrivate::eventDispatcher->startingUp();
579 Flushes the platform specific event queues.
581 If you are doing graphical changes inside a loop that does not
582 return to the event loop on asynchronous window systems like X11
583 or double buffered window systems like Mac OS X, and you want to
584 visualize these changes immediately (e.g. Splash Screens), call
587 \sa sendPostedEvents()
589 void QCoreApplication::flush()
591 if (self && self->d_func()->eventDispatcher)
592 self->d_func()->eventDispatcher->flush();
596 Constructs a Qt kernel application. Kernel applications are
597 applications without a graphical user interface. These type of
598 applications are used at the console or as server processes.
600 The \a argc and \a argv arguments are processed by the application,
601 and made available in a more convenient form by the arguments()
604 \warning The data referred to by \a argc and \a argv must stay valid
605 for the entire lifetime of the QCoreApplication object. In addition,
606 \a argc must be greater than zero and \a argv must contain at least
607 one valid character string.
609 QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
610 : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
613 QCoreApplicationPrivate::eventDispatcher->startingUp();
614 #if defined(Q_OS_SYMBIAN)
615 #ifndef QT_NO_LIBRARY
616 // Refresh factoryloader, as text codecs are requested during lib path
617 // resolving process and won't be therefore properly loaded.
618 // Unknown if this is symbian specific issue.
619 QFactoryLoader::refreshAll();
621 #ifndef QT_NO_SYSTEMLOCALE
622 d_func()->symbianInit();
624 #endif //Q_OS_SYMBIAN
628 // ### move to QCoreApplicationPrivate constructor?
629 void QCoreApplication::init()
631 Q_D(QCoreApplication);
634 setlocale(LC_ALL, ""); // use correct char set mapping
635 qt_locale_initialized = true;
638 Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
639 QCoreApplication::self = this;
642 //ensure temp and working directories exist
643 QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::tempPath()), true);
644 QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::currentPath()), true);
648 QThread::initialize();
651 // use the event dispatcher created by the app programmer (if any)
652 if (!QCoreApplicationPrivate::eventDispatcher)
653 QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
654 // otherwise we create one
655 if (!QCoreApplicationPrivate::eventDispatcher)
656 d->createEventDispatcher();
657 Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
659 if (!QCoreApplicationPrivate::eventDispatcher->parent())
660 QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
662 d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
664 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
665 if (!coreappdata()->app_libpaths) {
666 // make sure that library paths is initialized
669 d->appendApplicationPathToLibraryPaths();
674 extern void qt_core_eval_init(uint);
675 qt_core_eval_init(d->application_type);
678 #if defined(Q_OS_SYMBIAN) \
679 && defined(Q_CC_NOKIAX86) \
682 * Prevent the executable from being locked in the Symbian emulator. The
683 * code dramatically simplifies debugging on Symbian, but beyond that has
686 * Force the ZLazyUnloadTimer to fire and therefore unload code segments
687 * immediately. The code affects Symbian's file server and on the other
688 * hand needs only to be run once in each emulator run.
692 CleanupClosePushL(loader);
693 User::LeaveIfError(loader.Connect());
694 User::LeaveIfError(loader.CancelLazyDllUnload());
695 CleanupStack::PopAndDestroy(&loader);
699 d->processCommandLineArguments();
704 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
705 void QCoreApplicationPrivate::symbianInit()
707 if (!environmentChangeNotifier)
708 environmentChangeNotifier.reset(new QEnvironmentChangeNotifier);
714 Destroys the QCoreApplication object.
716 QCoreApplication::~QCoreApplication()
718 qt_call_post_routines();
721 QCoreApplicationPrivate::is_app_closing = true;
722 QCoreApplicationPrivate::is_app_running = false;
724 #if !defined(QT_NO_THREAD)
725 #if !defined(QT_NO_CONCURRENT)
726 // Synchronize and stop the global thread pool threads.
727 QThreadPool *globalThreadPool = 0;
729 globalThreadPool = QThreadPool::globalInstance();
731 // swallow the exception, since destructors shouldn't throw
733 if (globalThreadPool)
734 globalThreadPool->waitForDone();
739 d_func()->threadData->eventDispatcher = 0;
740 if (QCoreApplicationPrivate::eventDispatcher)
741 QCoreApplicationPrivate::eventDispatcher->closingDown();
742 QCoreApplicationPrivate::eventDispatcher = 0;
744 #ifndef QT_NO_LIBRARY
745 delete coreappdata()->app_libpaths;
746 coreappdata()->app_libpaths = 0;
752 Sets the attribute \a attribute if \a on is true;
753 otherwise clears the attribute.
755 One of the attributes that can be set with this method is
756 Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
757 windows immediately. Normally, resources for widgets are allocated
758 on demand to improve efficiency and minimize resource usage.
759 Therefore, if it is important to minimize resource consumption, do
760 not set this attribute.
764 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
767 QCoreApplicationPrivate::attribs |= 1 << attribute;
769 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
773 Returns true if attribute \a attribute is set;
774 otherwise returns false.
778 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
780 return QCoreApplicationPrivate::testAttribute(attribute);
787 This function is here to make it possible for Qt extensions to
788 hook into event notification without subclassing QApplication
790 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
792 // Make it possible for Qt Jambi and QSA to hook into events even
793 // though QApplication is subclassed...
795 void *cbdata[] = { receiver, event, &result };
796 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
800 // Qt enforces the rule that events can only be sent to objects in
801 // the current thread, so receiver->d_func()->threadData is
802 // equivalent to QThreadData::current(), just without the function
804 QObjectPrivate *d = receiver->d_func();
805 QThreadData *threadData = d->threadData;
807 // Exception-safety without try/catch
810 inline Incrementer(int &variable) : variable(variable)
812 inline ~Incrementer()
815 Incrementer inc(threadData->loopLevel);
817 #ifdef QT_JAMBI_BUILD
819 int *oldDeleteWatch = QObjectPrivate::setDeleteWatch(d, &deleteWatch);
821 bool inEvent = d->inEventHandler;
822 d->inEventHandler = true;
826 returnValue = notify(receiver, event);
828 #ifdef QT_JAMBI_BUILD
829 // Restore the previous state if the object was not deleted..
831 d->inEventHandler = inEvent;
833 QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
840 Sends \a event to \a receiver: \a {receiver}->event(\a event).
841 Returns the value that is returned from the receiver's event
842 handler. Note that this function is called for all events sent to
843 any object in any thread.
845 For certain types of events (e.g. mouse and key events),
846 the event will be propagated to the receiver's parent and so on up to
847 the top-level object if the receiver is not interested in the event
848 (i.e., it returns false).
850 There are five different ways that events can be processed;
851 reimplementing this virtual function is just one of them. All five
852 approaches are listed below:
854 \i Reimplementing paintEvent(), mousePressEvent() and so
855 on. This is the commonest, easiest and least powerful way.
857 \i Reimplementing this function. This is very powerful, providing
858 complete control; but only one subclass can be active at a time.
860 \i Installing an event filter on QCoreApplication::instance(). Such
861 an event filter is able to process all events for all widgets, so
862 it's just as powerful as reimplementing notify(); furthermore, it's
863 possible to have more than one application-global event filter.
864 Global event filters even see mouse events for
865 \l{QWidget::isEnabled()}{disabled widgets}. Note that application
866 event filters are only called for objects that live in the main
869 \i Reimplementing QObject::event() (as QWidget does). If you do
870 this you get Tab key presses, and you get to see the events before
871 any widget-specific event filters.
873 \i Installing an event filter on the object. Such an event filter gets all
874 the events, including Tab and Shift+Tab key press events, as long as they
875 do not change the focus widget.
878 \sa QObject::event(), installEventFilter()
881 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
883 Q_D(QCoreApplication);
884 // no events are delivered after ~QCoreApplication() has started
885 if (QCoreApplicationPrivate::is_app_closing)
888 if (receiver == 0) { // serious error
889 qWarning("QCoreApplication::notify: Unexpected null receiver");
894 d->checkReceiverThread(receiver);
897 return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
900 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
902 if (receiver->d_func()->threadData == this->threadData) {
903 // application event filters are only called for objects in the GUI thread
904 for (int i = 0; i < eventFilters.size(); ++i) {
905 register QObject *obj = eventFilters.at(i);
908 if (obj->d_func()->threadData != threadData) {
909 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
912 if (obj->eventFilter(receiver, event))
919 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
921 Q_Q(QCoreApplication);
923 for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
924 register QObject *obj = receiver->d_func()->eventFilters.at(i);
927 if (obj->d_func()->threadData != receiver->d_func()->threadData) {
928 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
931 if (obj->eventFilter(receiver, event))
940 Helper function called by notify()
942 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
944 // send to all application event filters
945 if (sendThroughApplicationEventFilters(receiver, event))
947 // send to all receiver event filters
948 if (sendThroughObjectEventFilters(receiver, event))
951 return receiver->event(event);
955 Returns true if an application object has not been created yet;
956 otherwise returns false.
961 bool QCoreApplication::startingUp()
963 return !QCoreApplicationPrivate::is_app_running;
967 Returns true if the application objects are being destroyed;
968 otherwise returns false.
973 bool QCoreApplication::closingDown()
975 return QCoreApplicationPrivate::is_app_closing;
980 Processes all pending events for the calling thread according to
981 the specified \a flags until there are no more events to process.
983 You can call this function occasionally when your program is busy
984 performing a long operation (e.g. copying a file).
986 In event you are running a local loop which calls this function
987 continuously, without an event loop, the
988 \l{QEvent::DeferredDelete}{DeferredDelete} events will
989 not be processed. This can affect the behaviour of widgets,
990 e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
991 events to function properly. An alternative would be to call
992 \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
993 within that local loop.
995 Calling this function processes events only for the calling thread.
999 \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1001 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1003 QThreadData *data = QThreadData::current();
1004 if (!data->eventDispatcher)
1006 if (flags & QEventLoop::DeferredDeletion)
1007 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1008 data->eventDispatcher->processEvents(flags);
1012 \overload processEvents()
1014 Processes pending events for the calling thread for \a maxtime
1015 milliseconds or until there are no more events to process,
1016 whichever is shorter.
1018 You can call this function occasionally when you program is busy
1019 doing a long operation (e.g. copying a file).
1021 Calling this function processes events only for the calling thread.
1025 \sa exec(), QTimer, QEventLoop::processEvents()
1027 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
1029 QThreadData *data = QThreadData::current();
1030 if (!data->eventDispatcher)
1032 QElapsedTimer start;
1034 if (flags & QEventLoop::DeferredDeletion)
1035 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1036 while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1037 if (start.elapsed() > maxtime)
1039 if (flags & QEventLoop::DeferredDeletion)
1040 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1044 /*****************************************************************************
1045 Main event loop wrappers
1046 *****************************************************************************/
1049 Enters the main event loop and waits until exit() is called.
1050 Returns the value that was set to exit() (which is 0 if exit() is
1053 It is necessary to call this function to start event handling. The
1054 main event loop receives events from the window system and
1055 dispatches these to the application widgets.
1057 To make your application perform idle processing (i.e. executing a
1058 special function whenever there are no pending events), use a
1059 QTimer with 0 timeout. More advanced idle processing schemes can
1060 be achieved using processEvents().
1062 We recommend that you connect clean-up code to the
1063 \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1064 your application's \c{main()} function because on some platforms the
1065 QCoreApplication::exec() call may not return. For example, on Windows
1066 when the user logs off, the system terminates the process after Qt
1067 closes all top-level windows. Hence, there is no guarantee that the
1068 application will have time to exit its event loop and execute code at
1069 the end of the \c{main()} function after the QCoreApplication::exec()
1072 \sa quit(), exit(), processEvents(), QApplication::exec()
1074 int QCoreApplication::exec()
1076 if (!QCoreApplicationPrivate::checkInstance("exec"))
1079 QThreadData *threadData = self->d_func()->threadData;
1080 if (threadData != QThreadData::current()) {
1081 qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1084 if (!threadData->eventLoops.isEmpty()) {
1085 qWarning("QCoreApplication::exec: The event loop is already running");
1089 threadData->quitNow = false;
1090 QEventLoop eventLoop;
1091 self->d_func()->in_exec = true;
1092 self->d_func()->aboutToQuitEmitted = false;
1093 int returnCode = eventLoop.exec();
1094 threadData->quitNow = false;
1096 self->d_func()->in_exec = false;
1097 if (!self->d_func()->aboutToQuitEmitted)
1098 emit self->aboutToQuit();
1099 self->d_func()->aboutToQuitEmitted = true;
1100 sendPostedEvents(0, QEvent::DeferredDelete);
1108 Tells the application to exit with a return code.
1110 After this function has been called, the application leaves the
1111 main event loop and returns from the call to exec(). The exec()
1112 function returns \a returnCode. If the event loop is not running,
1113 this function does nothing.
1115 By convention, a \a returnCode of 0 means success, and any non-zero
1116 value indicates an error.
1118 Note that unlike the C library function of the same name, this
1119 function \e does return to the caller -- it is event processing that
1124 void QCoreApplication::exit(int returnCode)
1128 QThreadData *data = self->d_func()->threadData;
1129 data->quitNow = true;
1130 for (int i = 0; i < data->eventLoops.size(); ++i) {
1131 QEventLoop *eventLoop = data->eventLoops.at(i);
1132 eventLoop->exit(returnCode);
1136 /*****************************************************************************
1137 QCoreApplication management of posted events
1138 *****************************************************************************/
1141 \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1143 Sends event \a event directly to receiver \a receiver, using the
1144 notify() function. Returns the value that was returned from the
1147 The event is \e not deleted when the event has been sent. The normal
1148 approach is to create the event on the stack, for example:
1150 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
1152 \sa postEvent(), notify()
1156 Adds the event \a event, with the object \a receiver as the
1157 receiver of the event, to an event queue and returns immediately.
1159 The event must be allocated on the heap since the post event queue
1160 will take ownership of the event and delete it once it has been
1161 posted. It is \e {not safe} to access the event after
1164 When control returns to the main event loop, all events that are
1165 stored in the queue will be sent using the notify() function.
1167 Events are processed in the order posted. For more control over
1168 the processing order, use the postEvent() overload below, which
1169 takes a priority argument. This function posts all event with a
1170 Qt::NormalEventPriority.
1174 \sa sendEvent(), notify(), sendPostedEvents()
1177 void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
1179 postEvent(receiver, event, Qt::NormalEventPriority);
1184 \overload postEvent()
1187 Adds the event \a event, with the object \a receiver as the
1188 receiver of the event, to an event queue and returns immediately.
1190 The event must be allocated on the heap since the post event queue
1191 will take ownership of the event and delete it once it has been
1192 posted. It is \e {not safe} to access the event after
1195 When control returns to the main event loop, all events that are
1196 stored in the queue will be sent using the notify() function.
1198 Events are sorted in descending \a priority order, i.e. events
1199 with a high \a priority are queued before events with a lower \a
1200 priority. The \a priority can be any integer value, i.e. between
1201 INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1202 details. Events with equal \a priority will be processed in the
1207 \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1209 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1211 if (receiver == 0) {
1212 qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1217 QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1218 QThreadData *data = *pdata;
1220 // posting during destruction? just delete the event to prevent a leak
1225 // lock the post event mutex
1226 data->postEventList.mutex.lock();
1228 // if object has moved to another thread, follow it
1229 while (data != *pdata) {
1230 data->postEventList.mutex.unlock();
1234 // posting during destruction? just delete the event to prevent a leak
1239 data->postEventList.mutex.lock();
1242 QMutexUnlocker locker(&data->postEventList.mutex);
1244 // if this is one of the compressible events, do compression
1245 if (receiver->d_func()->postedEvents
1246 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1250 if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1251 // remember the current running eventloop for DeferredDelete
1252 // events posted in the receiver's thread
1253 event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel));
1256 // delete the event on exceptions to protect against memory leaks till the event is
1257 // properly owned in the postEventList
1258 QScopedPointer<QEvent> eventDeleter(event);
1259 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1260 eventDeleter.take();
1261 event->posted = true;
1262 ++receiver->d_func()->postedEvents;
1263 data->canWait = false;
1266 if (data->eventDispatcher)
1267 data->eventDispatcher->wakeUp();
1272 Returns true if \a event was compressed away (possibly deleted) and should not be added to the list.
1274 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1279 Q_ASSERT(postedEvents);
1281 // compress posted timers to this object.
1282 if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1283 int timerId = ((QTimerEvent *) event)->timerId();
1284 for (int i=0; i<postedEvents->size(); ++i) {
1285 const QPostEvent &e = postedEvents->at(i);
1286 if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1287 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1294 if ((event->type() == QEvent::DeferredDelete
1295 || event->type() == QEvent::Quit)
1296 && receiver->d_func()->postedEvents > 0) {
1297 for (int i = 0; i < postedEvents->size(); ++i) {
1298 const QPostEvent &cur = postedEvents->at(i);
1299 if (cur.receiver != receiver
1301 || cur.event->type() != event->type())
1303 // found an event for this receiver
1312 \fn void QCoreApplication::sendPostedEvents()
1313 \overload sendPostedEvents()
1315 Dispatches all posted events, i.e. empties the event queue.
1319 Immediately dispatches all events which have been previously queued
1320 with QCoreApplication::postEvent() and which are for the object \a receiver
1321 and have the event type \a event_type.
1323 Events from the window system are \e not dispatched by this
1324 function, but by processEvents().
1326 If \a receiver is null, the events of \a event_type are sent for all
1327 objects. If \a event_type is 0, all the events are sent for \a receiver.
1329 \note This method must be called from the same thread as its QObject parameter, \a receiver.
1331 \sa flush(), postEvent()
1334 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1336 QThreadData *data = QThreadData::current();
1338 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1341 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1344 if (event_type == -1) {
1345 // we were called by an obsolete event dispatcher.
1349 if (receiver && receiver->d_func()->threadData != data) {
1350 qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1351 "posted events for objects in another thread");
1355 ++data->postEventList.recursion;
1357 QMutexLocker locker(&data->postEventList.mutex);
1359 // by default, we assume that the event dispatcher can go to sleep after
1360 // processing all events. if any new events are posted while we send
1361 // events, canWait will be set to false.
1362 data->canWait = (data->postEventList.size() == 0);
1364 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1365 --data->postEventList.recursion;
1369 data->canWait = true;
1371 // okay. here is the tricky loop. be careful about optimizing
1372 // this, it looks the way it does for good reasons.
1373 int startOffset = data->postEventList.startOffset;
1374 int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1375 data->postEventList.insertionOffset = data->postEventList.size();
1377 // Exception-safe cleaning up without the need for a try/catch block
1382 bool exceptionCaught;
1384 inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1385 receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1389 if (exceptionCaught) {
1390 // since we were interrupted, we need another pass to make sure we clean everything up
1391 data->canWait = false;
1394 --data->postEventList.recursion;
1395 if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1396 data->eventDispatcher->wakeUp();
1398 // clear the global list, i.e. remove everything that was
1400 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1401 const QPostEventList::iterator it = data->postEventList.begin();
1402 data->postEventList.erase(it, it + data->postEventList.startOffset);
1403 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1404 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1405 data->postEventList.startOffset = 0;
1409 CleanUp cleanup(receiver, event_type, data);
1411 while (i < data->postEventList.size()) {
1413 if (i >= data->postEventList.insertionOffset)
1416 const QPostEvent &pe = data->postEventList.at(i);
1421 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1422 data->canWait = false;
1426 if (pe.event->type() == QEvent::DeferredDelete) {
1427 // DeferredDelete events are only sent when we are explicitly asked to
1428 // (s.a. QEvent::DeferredDelete), and then only if the event loop that
1429 // posted the event has returned.
1430 const bool allowDeferredDelete =
1431 (quintptr(pe.event->d) > unsigned(data->loopLevel)
1432 || (!quintptr(pe.event->d) && data->loopLevel > 0)
1433 || (event_type == QEvent::DeferredDelete
1434 && quintptr(pe.event->d) == unsigned(data->loopLevel)));
1435 if (!allowDeferredDelete) {
1436 // cannot send deferred delete
1437 if (!event_type && !receiver) {
1438 // don't lose the event
1439 data->postEventList.addEvent(pe);
1440 const_cast<QPostEvent &>(pe).event = 0;
1446 // first, we diddle the event so that we can deliver
1447 // it, and that no one will try to touch it later.
1448 pe.event->posted = false;
1449 QScopedPointer<QEvent> e(pe.event);
1450 QObject * r = pe.receiver;
1452 --r->d_func()->postedEvents;
1453 Q_ASSERT(r->d_func()->postedEvents >= 0);
1455 // next, update the data structure so that we're ready
1456 // for the next event.
1457 const_cast<QPostEvent &>(pe).event = 0;
1459 struct MutexUnlocker
1462 MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); }
1463 ~MutexUnlocker() { m.relock(); }
1465 MutexUnlocker unlocker(locker);
1467 // after all that work, it's time to deliver the event.
1468 QCoreApplication::sendEvent(r, e.data());
1470 // careful when adding anything below this point - the
1471 // sendEvent() call might invalidate any invariants this
1472 // function depends on.
1475 cleanup.exceptionCaught = false;
1479 Removes all events posted using postEvent() for \a receiver.
1481 The events are \e not dispatched, instead they are removed from the
1482 queue. You should never need to call this function. If you do call it,
1483 be aware that killing events may cause \a receiver to break one or
1489 void QCoreApplication::removePostedEvents(QObject *receiver)
1491 removePostedEvents(receiver, 0);
1495 \overload removePostedEvents()
1498 Removes all events of the given \a eventType that were posted
1499 using postEvent() for \a receiver.
1501 The events are \e not dispatched, instead they are removed from
1502 the queue. You should never need to call this function. If you do
1503 call it, be aware that killing events may cause \a receiver to
1504 break one or more invariants.
1506 If \a receiver is null, the events of \a eventType are removed for
1507 all objects. If \a eventType is 0, all the events are removed for
1513 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1515 QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1516 QMutexLocker locker(&data->postEventList.mutex);
1518 // the QObject destructor calls this function directly. this can
1519 // happen while the event loop is in the middle of posting events,
1520 // and when we get here, we may not have any more posted events
1522 if (receiver && !receiver->d_func()->postedEvents)
1525 //we will collect all the posted events for the QObject
1526 //and we'll delete after the mutex was unlocked
1527 QVarLengthArray<QEvent*> events;
1528 int n = data->postEventList.size();
1531 for (int i = 0; i < n; ++i) {
1532 const QPostEvent &pe = data->postEventList.at(i);
1534 if ((!receiver || pe.receiver == receiver)
1535 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1536 --pe.receiver->d_func()->postedEvents;
1537 pe.event->posted = false;
1538 events.append(pe.event);
1539 const_cast<QPostEvent &>(pe).event = 0;
1540 } else if (!data->postEventList.recursion) {
1542 data->postEventList.swap(i, j);
1548 if (receiver && eventType == 0) {
1549 Q_ASSERT(!receiver->d_func()->postedEvents);
1553 if (!data->postEventList.recursion) {
1555 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1559 for (int i = 0; i < events.count(); ++i) {
1565 Removes \a event from the queue of posted events, and emits a
1566 warning message if appropriate.
1568 \warning This function can be \e really slow. Avoid using it, if
1574 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1576 if (!event || !event->posted)
1579 QThreadData *data = QThreadData::current();
1581 QMutexLocker locker(&data->postEventList.mutex);
1583 if (data->postEventList.size() == 0) {
1584 #if defined(QT_DEBUG)
1585 qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1586 (void*)event, event->type());
1591 for (int i = 0; i < data->postEventList.size(); ++i) {
1592 const QPostEvent & pe = data->postEventList.at(i);
1593 if (pe.event == event) {
1595 qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1597 pe.receiver->metaObject()->className(),
1598 pe.receiver->objectName().toLocal8Bit().data());
1600 --pe.receiver->d_func()->postedEvents;
1601 pe.event->posted = false;
1603 const_cast<QPostEvent &>(pe).event = 0;
1612 bool QCoreApplication::event(QEvent *e)
1614 if (e->type() == QEvent::Quit) {
1618 return QObject::event(e);
1621 /*! \enum QCoreApplication::Encoding
1623 This enum type defines the 8-bit encoding of character string
1624 arguments to translate():
1626 \value CodecForTr The encoding specified by
1627 QTextCodec::codecForTr() (Latin-1 if none has
1629 \value UnicodeUTF8 UTF-8.
1630 \value DefaultCodec (Obsolete) Use CodecForTr instead.
1632 \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
1636 Tells the application to exit with return code 0 (success).
1637 Equivalent to calling QCoreApplication::exit(0).
1639 It's common to connect the QApplication::lastWindowClosed() signal
1640 to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1641 signals in QAction, QMenu, or QMenuBar to it.
1645 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
1647 \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
1650 void QCoreApplication::quit()
1656 \fn void QCoreApplication::aboutToQuit()
1658 This signal is emitted when the application is about to quit the
1659 main event loop, e.g. when the event loop level drops to zero.
1660 This may happen either after a call to quit() from inside the
1661 application or when the users shuts down the entire desktop session.
1663 The signal is particularly useful if your application has to do some
1664 last-second cleanup. Note that no user interaction is possible in
1670 #ifndef QT_NO_TRANSLATION
1672 Adds the translation file \a translationFile to the list of
1673 translation files to be used for translations.
1675 Multiple translation files can be installed. Translations are
1676 searched for in the reverse order in which they were installed,
1677 so the most recently installed translation file is searched first
1678 and the first translation file installed is searched last.
1679 The search stops as soon as a translation containing a matching
1682 Installing or removing a QTranslator, or changing an installed QTranslator
1683 generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1684 QCoreApplication instance. A QApplication instance will propagate the event
1685 to all toplevel windows, where a reimplementation of changeEvent can
1686 re-translate the user interface by passing user-visible strings via the
1687 tr() function to the respective property setters. User-interface classes
1688 generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
1691 \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
1694 void QCoreApplication::installTranslator(QTranslator *translationFile)
1696 if (!translationFile)
1699 if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1701 QCoreApplicationPrivate *d = self->d_func();
1702 d->translators.prepend(translationFile);
1704 #ifndef QT_NO_TRANSLATION_BUILDER
1705 if (translationFile->isEmpty())
1709 QEvent ev(QEvent::LanguageChange);
1710 QCoreApplication::sendEvent(self, &ev);
1714 Removes the translation file \a translationFile from the list of
1715 translation files used by this application. (It does not delete the
1716 translation file from the file system.)
1718 \sa installTranslator() translate(), QObject::tr()
1721 void QCoreApplication::removeTranslator(QTranslator *translationFile)
1723 if (!translationFile)
1725 if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1727 QCoreApplicationPrivate *d = self->d_func();
1728 if (d->translators.removeAll(translationFile) && !self->closingDown()) {
1729 QEvent ev(QEvent::LanguageChange);
1730 QCoreApplication::sendEvent(self, &ev);
1735 \overload translate()
1737 QString QCoreApplication::translate(const char *context, const char *sourceText,
1738 const char *disambiguation, Encoding encoding)
1740 return translate(context, sourceText, disambiguation, encoding, -1);
1743 static void replacePercentN(QString *result, int n)
1748 while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1751 if (result->at(percentPos + len) == QLatin1Char('L')) {
1753 fmt = QLatin1String("%L1");
1755 fmt = QLatin1String("%1");
1757 if (result->at(percentPos + len) == QLatin1Char('n')) {
1760 result->replace(percentPos, len, fmt);
1771 Returns the translation text for \a sourceText, by querying the
1772 installed translation files. The translation files are searched
1773 from the most recently installed file back to the first
1776 QObject::tr() and QObject::trUtf8() provide this functionality
1779 \a context is typically a class name (e.g., "MyDialog") and \a
1780 sourceText is either English text or a short identifying text.
1782 \a disambiguation is an identifying string, for when the same \a
1783 sourceText is used in different roles within the same context. By
1784 default, it is null.
1786 See the \l QTranslator and \l QObject::tr() documentation for
1787 more information about contexts, disambiguations and comments.
1789 \a encoding indicates the 8-bit encoding of character strings.
1791 \a n is used in conjunction with \c %n to support plural forms.
1792 See QObject::tr() for details.
1794 If none of the translation files contain a translation for \a
1795 sourceText in \a context, this function returns a QString
1796 equivalent of \a sourceText. The encoding of \a sourceText is
1797 specified by \e encoding; it defaults to CodecForTr.
1799 This function is not virtual. You can use alternative translation
1800 techniques by subclassing \l QTranslator.
1802 \warning This method is reentrant only if all translators are
1803 installed \e before calling this method. Installing or removing
1804 translators while performing translations is not supported. Doing
1805 so will most likely result in crashes or other undesirable
1808 \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
1812 QString QCoreApplication::translate(const char *context, const char *sourceText,
1813 const char *disambiguation, Encoding encoding, int n)
1820 if (self && !self->d_func()->translators.isEmpty()) {
1821 QList<QTranslator*>::ConstIterator it;
1822 QTranslator *translationFile;
1823 for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
1824 translationFile = *it;
1825 result = translationFile->translate(context, sourceText, disambiguation, n);
1826 if (!result.isEmpty())
1831 if (result.isEmpty()) {
1832 #ifdef QT_NO_TEXTCODEC
1835 if (encoding == UnicodeUTF8)
1836 result = QString::fromUtf8(sourceText);
1837 else if (QTextCodec::codecForTr() != 0)
1838 result = QTextCodec::codecForTr()->toUnicode(sourceText);
1841 result = QString::fromLatin1(sourceText);
1844 replacePercentN(&result, n);
1848 // Declared in qglobal.h
1849 QString qtTrId(const char *id, int n)
1851 return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n);
1854 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
1856 return QCoreApplication::self
1857 && QCoreApplication::self->d_func()->translators.contains(translator);
1860 #endif //QT_NO_TRANSLATE
1863 Returns the directory that contains the application executable.
1865 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1866 directory, and you run the \c{regexp} example, this function will
1867 return "C:/Trolltech/Qt/examples/tools/regexp".
1869 On Mac OS X this will point to the directory actually containing the
1870 executable, which may be inside of an application bundle (if the
1871 application is bundled).
1873 \warning On Linux, this function will try to get the path from the
1874 \c {/proc} file system. If that fails, it assumes that \c
1875 {argv[0]} contains the absolute file name of the executable. The
1876 function also assumes that the current directory has not been
1877 changed by the application.
1879 In Symbian this function will return the application private directory,
1880 not the path to executable itself, as those are always in \c {/sys/bin}.
1881 If the application is in a read only drive, i.e. ROM, then the private path
1882 on the system drive will be returned.
1884 \sa applicationFilePath()
1886 QString QCoreApplication::applicationDirPath()
1889 qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
1893 QCoreApplicationPrivate *d = self->d_func();
1894 if (d->cachedApplicationDirPath.isNull())
1895 #if defined(Q_OS_SYMBIAN)
1898 RFs& fs = qt_s60GetRFs();
1901 driveChar = (RProcess().FileName())[0];
1903 //Check if the process is installed in a read only drive (typically ROM),
1904 //and use the system drive (typically C:) if so.
1906 TDriveInfo driveInfo;
1907 TInt err = fs.CharToDrive(driveChar, drive);
1908 if (err == KErrNone) {
1909 err = fs.Drive(driveInfo, drive);
1911 if (err != KErrNone || (driveInfo.iDriveAtt & KDriveAttRom) || (driveInfo.iMediaAtt
1912 & KMediaAttWriteProtected)) {
1913 if(!PtrGetSystemDrive)
1914 PtrGetSystemDrive = reinterpret_cast<SystemDriveFunc>(qt_resolveS60PluginFunc(S60Plugin_GetSystemDrive));
1915 Q_ASSERT(PtrGetSystemDrive);
1916 drive = PtrGetSystemDrive(fs);
1917 fs.DriveToChar(drive, driveChar);
1920 qDriveChar = QChar(QLatin1Char(driveChar)).toUpper();
1922 TFileName privatePath;
1923 fs.PrivatePath(privatePath);
1924 appPath = qt_TDesC2QString(privatePath);
1925 appPath.prepend(QLatin1Char(':')).prepend(qDriveChar);
1927 // Create the appPath if it doesn't exist. Non-existing appPath will cause
1928 // Platform Security violations later on if the app doesn't have AllFiles capability.
1929 err = fs.CreatePrivatePath(drive);
1930 if (err != KErrNone)
1931 qWarning("QCoreApplication::applicationDirPath: Failed to create private path.");
1933 d->cachedApplicationDirPath = QFileInfo(appPath).path();
1936 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
1938 return d->cachedApplicationDirPath;
1942 Returns the file path of the application executable.
1944 For example, if you have installed Qt in the \c{/usr/local/qt}
1945 directory, and you run the \c{regexp} example, this function will
1946 return "/usr/local/qt/examples/tools/regexp/regexp".
1948 \warning On Linux, this function will try to get the path from the
1949 \c {/proc} file system. If that fails, it assumes that \c
1950 {argv[0]} contains the absolute file name of the executable. The
1951 function also assumes that the current directory has not been
1952 changed by the application.
1954 \sa applicationDirPath()
1956 QString QCoreApplication::applicationFilePath()
1959 qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
1963 QCoreApplicationPrivate *d = self->d_func();
1964 if (!d->cachedApplicationFilePath.isNull())
1965 return d->cachedApplicationFilePath;
1967 #if defined(Q_OS_WIN)
1968 d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
1969 return d->cachedApplicationFilePath;
1970 #elif defined(Q_WS_MAC)
1971 QString qAppFileName_str = qAppFileName();
1972 if(!qAppFileName_str.isEmpty()) {
1973 QFileInfo fi(qAppFileName_str);
1974 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
1975 return d->cachedApplicationFilePath;
1978 #if defined(Q_OS_SYMBIAN)
1981 TInt err = proc.Open(proc.Id());
1982 if (err == KErrNone) {
1983 TFileName procName = proc.FileName();
1984 appPath.append(QString(reinterpret_cast<const QChar*>(procName.Ptr()), procName.Length()));
1988 d->cachedApplicationFilePath = appPath;
1989 return d->cachedApplicationFilePath;
1991 #elif defined( Q_OS_UNIX )
1993 // Try looking for a /proc/<pid>/exe symlink first which points to
1994 // the absolute path of the executable
1995 QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
1996 if (pfi.exists() && pfi.isSymLink()) {
1997 d->cachedApplicationFilePath = pfi.canonicalFilePath();
1998 return d->cachedApplicationFilePath;
2002 QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
2005 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2007 If argv0 starts with a slash, it is already an absolute
2011 } else if (argv0.contains(QLatin1Char('/'))) {
2013 If argv0 contains one or more slashes, it is a file path
2014 relative to the current directory.
2016 absPath = QDir::current().absoluteFilePath(argv0);
2019 Otherwise, the file path has to be determined using the
2020 PATH environment variable.
2022 QByteArray pEnv = qgetenv("PATH");
2023 QDir currentDir = QDir::current();
2024 QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
2025 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
2028 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
2029 QFileInfo candidate_fi(candidate);
2030 if (candidate_fi.exists() && !candidate_fi.isDir()) {
2031 absPath = candidate;
2037 absPath = QDir::cleanPath(absPath);
2039 QFileInfo fi(absPath);
2040 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
2041 return d->cachedApplicationFilePath;
2048 Returns the current process ID for the application.
2050 qint64 QCoreApplication::applicationPid()
2052 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
2053 return GetCurrentProcessId();
2054 #elif defined(Q_OS_VXWORKS)
2055 return (pid_t) taskIdCurrent;
2064 Use arguments().size() instead.
2066 int QCoreApplication::argc()
2069 qWarning("QCoreApplication::argc: Please instantiate the QApplication object first");
2072 return self->d_func()->argc;
2079 Use arguments() instead.
2081 char **QCoreApplication::argv()
2084 qWarning("QCoreApplication::argv: Please instantiate the QApplication object first");
2087 return self->d_func()->argv;
2093 Returns the list of command-line arguments.
2095 Usually arguments().at(0) is the program name, arguments().at(1)
2096 is the first argument, and arguments().last() is the last
2097 argument. See the note below about Windows.
2099 Calling this function is slow - you should store the result in a variable
2100 when parsing the command line.
2102 \warning On Unix, this list is built from the argc and argv parameters passed
2103 to the constructor in the main() function. The string-data in argv is
2104 interpreted using QString::fromLocal8Bit(); hence it is not possible to
2105 pass, for example, Japanese command line arguments on a system that runs in a
2106 Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2109 On NT-based Windows, this limitation does not apply either.
2110 On Windows, the arguments() are not built from the contents of argv/argc, as
2111 the content does not support Unicode. Instead, the arguments() are constructed
2112 from the return value of
2113 \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2114 As a result of this, the string given by arguments().at(0) might not be
2115 the program name on Windows, depending on how the application was started.
2117 For Symbian applications started with \c RApaLsSession::StartApp one can specify
2118 arguments using \c CApaCommandLine::SetTailEndL function. Such arguments are only
2119 available via this method; they will not be passed to \c main function. Also note
2120 that only 8-bit string data set with \c CApaCommandLine::SetTailEndL is supported
2123 \sa applicationFilePath()
2126 QStringList QCoreApplication::arguments()
2131 qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2135 QString cmdline = QString::fromWCharArray(GetCommandLine());
2137 #if defined(Q_OS_WINCE)
2138 wchar_t tempFilename[MAX_PATH+1];
2139 if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
2140 tempFilename[MAX_PATH] = 0;
2141 cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
2143 #endif // Q_OS_WINCE
2145 list = qWinCmdArgs(cmdline);
2146 if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
2147 QStringList stripped;
2148 for (int a = 0; a < list.count(); ++a) {
2149 QString arg = list.at(a);
2150 QByteArray l1arg = arg.toLatin1();
2151 if (l1arg == "-qdevel" ||
2152 l1arg == "-qdebug" ||
2153 l1arg == "-reverse" ||
2154 l1arg == "-stylesheet" ||
2155 l1arg == "-widgetcount")
2157 else if (l1arg.startsWith("-style=") ||
2158 l1arg.startsWith("-qmljsdebugger="))
2160 else if (l1arg == "-style" ||
2161 l1arg == "-session" ||
2162 l1arg == "-testability")
2170 const int ac = self->d_func()->argc;
2171 char ** const av = self->d_func()->argv;
2172 for (int a = 0; a < ac; ++a) {
2173 list << QString::fromLocal8Bit(av[a]);
2181 \property QCoreApplication::organizationName
2182 \brief the name of the organization that wrote this application
2184 The value is used by the QSettings class when it is constructed
2185 using the empty constructor. This saves having to repeat this
2186 information each time a QSettings object is created.
2188 On Mac, QSettings uses organizationDomain() as the organization
2189 if it's not an empty string; otherwise it uses
2190 organizationName(). On all other platforms, QSettings uses
2191 organizationName() as the organization.
2193 \sa organizationDomain applicationName
2196 void QCoreApplication::setOrganizationName(const QString &orgName)
2198 coreappdata()->orgName = orgName;
2201 QString QCoreApplication::organizationName()
2203 return coreappdata()->orgName;
2207 \property QCoreApplication::organizationDomain
2208 \brief the Internet domain of the organization that wrote this application
2210 The value is used by the QSettings class when it is constructed
2211 using the empty constructor. This saves having to repeat this
2212 information each time a QSettings object is created.
2214 On Mac, QSettings uses organizationDomain() as the organization
2215 if it's not an empty string; otherwise it uses organizationName().
2216 On all other platforms, QSettings uses organizationName() as the
2219 \sa organizationName applicationName applicationVersion
2221 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2223 coreappdata()->orgDomain = orgDomain;
2226 QString QCoreApplication::organizationDomain()
2228 return coreappdata()->orgDomain;
2232 \property QCoreApplication::applicationName
2233 \brief the name of this application
2235 The value is used by the QSettings class when it is constructed
2236 using the empty constructor. This saves having to repeat this
2237 information each time a QSettings object is created.
2239 \sa organizationName organizationDomain applicationVersion
2241 void QCoreApplication::setApplicationName(const QString &application)
2243 coreappdata()->application = application;
2246 QString QCoreApplication::applicationName()
2248 return coreappdata()->application;
2252 \property QCoreApplication::applicationVersion
2254 \brief the version of this application
2256 \sa applicationName organizationName organizationDomain
2258 void QCoreApplication::setApplicationVersion(const QString &version)
2260 coreappdata()->applicationVersion = version;
2263 QString QCoreApplication::applicationVersion()
2265 return coreappdata()->applicationVersion;
2268 #ifndef QT_NO_LIBRARY
2270 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2273 Returns a list of paths that the application will search when
2274 dynamically loading libraries.
2276 Qt provides default library paths, but they can also be set using
2277 a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2278 will override default values.
2280 This list will include the installation directory for plugins if
2281 it exists (the default installation directory for plugins is \c
2282 INSTALL/plugins, where \c INSTALL is the directory where Qt was
2283 installed). The directory of the application executable (NOT the
2284 working directory) is always added, as well as the colon separated
2285 entries of the QT_PLUGIN_PATH environment variable.
2287 If you want to iterate over the list, you can use the \l foreach
2290 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
2292 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2293 {How to Create Qt Plugins}
2295 QStringList QCoreApplication::libraryPaths()
2297 QMutexLocker locker(libraryPathMutex());
2298 if (!coreappdata()->app_libpaths) {
2299 QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
2300 QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
2301 #if defined(Q_OS_SYMBIAN)
2302 // Add existing path on all drives for relative PluginsPath in Symbian
2303 if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) {
2304 QString tempPath = installPathPlugins;
2305 if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
2306 tempPath += QDir::separator();
2308 RFs& fs = qt_s60GetRFs();
2309 TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
2310 TFindFile finder(fs);
2311 TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
2312 while (err == KErrNone) {
2313 QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
2314 finder.File().Length());
2315 foundDir = QDir(foundDir).canonicalPath();
2316 if (!app_libpaths->contains(foundDir))
2317 app_libpaths->append(foundDir);
2318 err = finder.Find();
2322 if (QFile::exists(installPathPlugins)) {
2323 // Make sure we convert from backslashes to slashes.
2324 installPathPlugins = QDir(installPathPlugins).canonicalPath();
2325 if (!app_libpaths->contains(installPathPlugins))
2326 app_libpaths->append(installPathPlugins);
2330 // If QCoreApplication is not yet instantiated,
2331 // make sure we add the application path when we construct the QCoreApplication
2332 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2334 const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2335 if (!libPathEnv.isEmpty()) {
2336 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
2337 QLatin1Char pathSep(';');
2339 QLatin1Char pathSep(':');
2341 QStringList paths = QString::fromLatin1(libPathEnv).split(pathSep, QString::SkipEmptyParts);
2342 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2343 QString canonicalPath = QDir(*it).canonicalPath();
2344 if (!canonicalPath.isEmpty()
2345 && !app_libpaths->contains(canonicalPath)) {
2346 app_libpaths->append(canonicalPath);
2351 return *(coreappdata()->app_libpaths);
2358 Sets the list of directories to search when loading libraries to
2359 \a paths. All existing paths will be deleted and the path list
2360 will consist of the paths given in \a paths.
2362 In Symbian this function is only useful for setting paths for
2363 finding Qt extension plugin stubs, since the OS can only
2364 load libraries from the \c{/sys/bin} directory.
2366 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2368 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2370 QMutexLocker locker(libraryPathMutex());
2371 if (!coreappdata()->app_libpaths)
2372 coreappdata()->app_libpaths = new QStringList;
2373 *(coreappdata()->app_libpaths) = paths;
2375 QFactoryLoader::refreshAll();
2379 Prepends \a path to the beginning of the library path list, ensuring that
2380 it is searched for libraries first. If \a path is empty or already in the
2381 path list, the path list is not changed.
2383 The default path list consists of a single entry, the installation
2384 directory for plugins. The default installation directory for plugins
2385 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2388 In Symbian this function is only useful for adding paths for
2389 finding Qt extension plugin stubs, since the OS can only
2390 load libraries from the \c{/sys/bin} directory.
2392 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2394 void QCoreApplication::addLibraryPath(const QString &path)
2399 QMutexLocker locker(libraryPathMutex());
2401 // make sure that library paths is initialized
2404 QString canonicalPath = QDir(path).canonicalPath();
2405 if (!canonicalPath.isEmpty()
2406 && !coreappdata()->app_libpaths->contains(canonicalPath)) {
2407 coreappdata()->app_libpaths->prepend(canonicalPath);
2409 QFactoryLoader::refreshAll();
2414 Removes \a path from the library path list. If \a path is empty or not
2415 in the path list, the list is not changed.
2417 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2419 void QCoreApplication::removeLibraryPath(const QString &path)
2424 QMutexLocker locker(libraryPathMutex());
2426 // make sure that library paths is initialized
2429 QString canonicalPath = QDir(path).canonicalPath();
2430 coreappdata()->app_libpaths->removeAll(canonicalPath);
2431 QFactoryLoader::refreshAll();
2434 #endif //QT_NO_LIBRARY
2437 \typedef QCoreApplication::EventFilter
2439 A function with the following signature that can be used as an
2442 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
2444 \sa setEventFilter()
2448 \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
2450 Replaces the event filter function for the QCoreApplication with
2451 \a filter and returns the pointer to the replaced event filter
2452 function. Only the current event filter function is called. If you
2453 want to use both filter functions, save the replaced EventFilter
2454 in a place where yours can call it.
2456 The event filter function set here is called for all messages
2457 received by all threads meant for all Qt objects. It is \e not
2458 called for messages that are not meant for Qt objects.
2460 The event filter function should return true if the message should
2461 be filtered, (i.e. stopped). It should return false to allow
2462 processing the message to continue.
2464 By default, no event filter function is set (i.e., this function
2465 returns a null EventFilter the first time it is called).
2467 \note The filter function set here receives native messages,
2468 i.e. MSG or XEvent structs, that are going to Qt objects. It is
2469 called by QCoreApplication::filterEvent(). If the filter function
2470 returns false to indicate the message should be processed further,
2471 the native message can then be translated into a QEvent and
2472 handled by the standard Qt \l{QEvent} {event} filering, e.g.
2473 QObject::installEventFilter().
2475 \note The filter function set here is different form the filter
2476 function set via QAbstractEventDispatcher::setEventFilter(), which
2477 gets all messages received by its thread, even messages meant for
2478 objects that are not handled by Qt.
2480 \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
2482 QCoreApplication::EventFilter
2483 QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
2485 Q_D(QCoreApplication);
2486 EventFilter old = d->eventFilter;
2487 d->eventFilter = filter;
2492 Sends \a message through the event filter that was set by
2493 setEventFilter(). If no event filter has been set, this function
2494 returns false; otherwise, this function returns the result of the
2495 event filter function in the \a result parameter.
2497 \sa setEventFilter()
2499 bool QCoreApplication::filterEvent(void *message, long *result)
2501 Q_D(QCoreApplication);
2505 return d->eventFilter(message, result);
2507 return winEventFilter(reinterpret_cast<MSG *>(message), result);
2514 This function returns true if there are pending events; otherwise
2515 returns false. Pending events can be either from the window
2516 system or posted events using postEvent().
2518 \sa QAbstractEventDispatcher::hasPendingEvents()
2520 bool QCoreApplication::hasPendingEvents()
2522 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2523 if (eventDispatcher)
2524 return eventDispatcher->hasPendingEvents();
2529 \fn void QCoreApplication::watchUnixSignal(int signal, bool watch)
2534 \fn void QCoreApplication::unixSignal(int number)
2537 This signal is emitted whenever a Unix signal is received by the
2538 application. The Unix signal received is specified by its \a number.
2542 \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2543 \relates QCoreApplication
2545 Adds a global routine that will be called from the QApplication
2546 destructor. This function is normally used to add cleanup routines
2547 for program-wide functionality.
2549 The function specified by \a ptr should take no arguments and should
2550 return nothing. For example:
2552 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
2554 Note that for an application- or module-wide cleanup,
2555 qAddPostRoutine() is often not suitable. For example, if the
2556 program is split into dynamically loaded modules, the relevant
2557 module may be unloaded long before the QApplication destructor is
2560 For modules and libraries, using a reference-counted
2561 initialization manager or Qt's parent-child deletion mechanism may
2562 be better. Here is an example of a private class that uses the
2563 parent-child mechanism to call a cleanup function at the right
2566 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
2568 By selecting the right parent object, this can often be made to
2569 clean up the module's data at the right moment.
2573 \macro Q_DECLARE_TR_FUNCTIONS(context)
2574 \relates QCoreApplication
2576 The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2577 translation functions, \c tr() and \c trUtf8(), with these
2580 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
2582 This macro is useful if you want to use QObject::tr() or
2583 QObject::trUtf8() in classes that don't inherit from QObject.
2585 Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2586 class definition (before the first \c{public:} or \c{protected:}).
2589 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
2591 The \a context parameter is normally the class name, but it can
2594 \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2599 #include "moc_qcoreapplication.cpp"