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 // Support for introspection
215 QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
217 void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
219 qt_signal_spy_callback_set = callback_set;
222 extern "C" void Q_CORE_EXPORT qt_startup_hook()
226 typedef QList<QtCleanUpFunction> QVFuncList;
227 Q_GLOBAL_STATIC(QVFuncList, postRList)
229 void qAddPostRoutine(QtCleanUpFunction p)
231 QVFuncList *list = postRList();
237 void qRemovePostRoutine(QtCleanUpFunction p)
239 QVFuncList *list = postRList();
245 void Q_CORE_EXPORT qt_call_post_routines()
247 QVFuncList *list = 0;
250 } QT_CATCH(const std::bad_alloc &) {
251 // ignore - if we can't allocate a post routine list,
252 // there's a high probability that there's no post
253 // routine to be executed :)
257 while (!list->isEmpty())
258 (list->takeFirst())();
262 // app starting up if false
263 bool QCoreApplicationPrivate::is_app_running = false;
264 // app closing down if true
265 bool QCoreApplicationPrivate::is_app_closing = false;
266 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
267 Q_CORE_EXPORT bool qt_locale_initialized = false;
269 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
271 QThreadData *currentThreadData = QThreadData::current();
272 return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
276 void qt_set_current_thread_to_main_thread()
278 QCoreApplicationPrivate::theMainThread = QThread::currentThread();
283 QCoreApplication *QCoreApplication::self = 0;
284 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
285 uint QCoreApplicationPrivate::attribs;
288 Qt::HANDLE qt_application_thread_id = 0;
291 struct QCoreApplicationData {
292 QCoreApplicationData() {
293 #ifndef QT_NO_LIBRARY
297 ~QCoreApplicationData() {
298 #ifndef QT_NO_LIBRARY
302 // cleanup the QAdoptedThread created for the main() thread
303 if (QCoreApplicationPrivate::theMainThread) {
304 QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
305 QCoreApplicationPrivate::theMainThread = 0;
306 data->deref(); // deletes the data and the adopted thread
309 QString orgName, orgDomain, application;
310 QString applicationVersion;
312 #ifndef QT_NO_LIBRARY
313 QStringList *app_libpaths;
318 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
320 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
321 : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
322 in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
324 app_compile_version = flags & 0xffffff;
325 static const char *const empty = "";
326 if (argc == 0 || argv == 0) {
328 argv = (char **)∅ // ouch! careful with QCoreApplication::argv()!
330 QCoreApplicationPrivate::is_app_closing = false;
333 qt_init_symbian_apa_arguments(argc, argv);
337 qt_application_thread_id = QThread::currentThreadId();
340 // note: this call to QThread::currentThread() may end up setting theMainThread!
341 if (QThread::currentThread() != theMainThread)
342 qWarning("WARNING: QApplication was not created in the main() thread.");
345 QCoreApplicationPrivate::~QCoreApplicationPrivate()
350 void QCoreApplicationPrivate::cleanupThreadData()
352 if (threadData && !threadData_clean) {
354 void *data = &threadData->tls;
355 QThreadStorageData::finish((void **)data);
358 // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
359 QMutexLocker locker(&threadData->postEventList.mutex);
360 for (int i = 0; i < threadData->postEventList.size(); ++i) {
361 const QPostEvent &pe = threadData->postEventList.at(i);
363 --pe.receiver->d_func()->postedEvents;
364 pe.event->posted = false;
368 threadData->postEventList.clear();
369 threadData->postEventList.recursion = 0;
370 threadData->quitNow = false;
371 threadData_clean = true;
375 void QCoreApplicationPrivate::createEventDispatcher()
377 Q_Q(QCoreApplication);
378 #if defined(Q_OS_SYMBIAN)
379 eventDispatcher = new QEventDispatcherSymbian(q);
380 #elif defined(Q_OS_UNIX)
381 # if !defined(QT_NO_GLIB)
382 if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
383 eventDispatcher = new QEventDispatcherGlib(q);
386 eventDispatcher = new QEventDispatcherUNIX(q);
387 #elif defined(Q_OS_WIN)
388 eventDispatcher = new QEventDispatcherWin32(q);
390 # error "QEventDispatcher not yet ported to this platform"
394 void QCoreApplicationPrivate::_q_initializeProcessManager()
396 #ifndef QT_NO_PROCESS
398 QProcessPrivate::initializeProcessManager();
404 QThread *QCoreApplicationPrivate::theMainThread = 0;
405 QThread *QCoreApplicationPrivate::mainThread()
407 Q_ASSERT(theMainThread != 0);
408 return theMainThread;
411 #if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
412 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
414 QThread *currentThread = QThread::currentThread();
415 QThread *thr = receiver->thread();
416 Q_ASSERT_X(currentThread == thr || !thr,
417 "QCoreApplication::sendEvent",
418 QString::fromLatin1("Cannot send events to objects owned by a different thread. "
419 "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
420 .arg(QString::number((quintptr) currentThread, 16))
421 .arg(receiver->objectName())
422 .arg(QLatin1String(receiver->metaObject()->className()))
423 .arg(QString::number((quintptr) thr, 16))
424 .toLocal8Bit().data());
425 Q_UNUSED(currentThread);
428 #elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG)
429 // no implementation in release builds, but keep the symbol present
430 void QCoreApplicationPrivate::checkReceiverThread(QObject * /* receiver */)
435 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
437 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
438 QStringList *app_libpaths = coreappdata()->app_libpaths;
439 Q_ASSERT(app_libpaths);
440 # if defined(Q_OS_SYMBIAN)
441 QString app_location( QCoreApplication::applicationDirPath() );
442 // File existence check for application's private dir requires additional '\' or
443 // platform security will not allow it.
444 if (app_location != QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location + QLatin1Char('\\')) && !app_libpaths->contains(app_location))
446 QString app_location( QCoreApplication::applicationFilePath() );
447 app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
448 app_location = QDir(app_location).canonicalPath();
449 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
451 app_libpaths->append(app_location);
457 if (!QCoreApplicationPrivate::checkInstance("qAppName"))
459 return QCoreApplication::instance()->d_func()->appName();
463 \class QCoreApplication
464 \brief The QCoreApplication class provides an event loop for console Qt
467 This class is used by non-GUI applications to provide their event
468 loop. For non-GUI application that uses Qt, there should be exactly
469 one QCoreApplication object. For GUI applications, see
472 QCoreApplication contains the main event loop, where all events
473 from the operating system (e.g., timer and network events) and
474 other sources are processed and dispatched. It also handles the
475 application's initialization and finalization, as well as
476 system-wide and application-wide settings.
478 \section1 The Event Loop and Event Handling
480 The event loop is started with a call to exec(). Long running
481 operations can call processEvents() to keep the application
484 In general, we recommend that you create a QCoreApplication or a
485 QApplication object in your \c main() function as early as
486 possible. exec() will not return until the event loop exits; e.g.,
487 when quit() is called.
489 Several static convenience functions are also provided. The
490 QCoreApplication object is available from instance(). Events can
491 be sent or posted using sendEvent(), postEvent(), and
492 sendPostedEvents(). Pending events can be removed with
493 removePostedEvents() or flushed with flush().
495 The class provides a quit() slot and an aboutToQuit() signal.
497 \section1 Application and Library Paths
499 An application has an applicationDirPath() and an
500 applicationFilePath(). Library paths (see QLibrary) can be retrieved
501 with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
502 and removeLibraryPath().
504 \section1 Internationalization and Translations
506 Translation files can be added or removed
507 using installTranslator() and removeTranslator(). Application
508 strings can be translated using translate(). The QObject::tr()
509 and QObject::trUtf8() functions are implemented in terms of
512 \section1 Accessing Command Line Arguments
514 The command line arguments which are passed to QCoreApplication's
515 constructor should be accessed using the arguments() function.
516 Note that some arguments supplied by the user may have been
517 processed and removed by QCoreApplication.
519 In cases where command line arguments need to be obtained using the
520 argv() function, you must convert them from the local string encoding
521 using QString::fromLocal8Bit().
523 \section1 Locale Settings
525 On Unix/Linux Qt is configured to use the system locale settings by
526 default. This can cause a conflict when using POSIX functions, for
527 instance, when converting between data types such as floats and
528 strings, since the notation may differ between locales. To get
529 around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
530 right after initializing QApplication or QCoreApplication to reset
531 the locale that is used for number formatting to "C"-locale.
533 \sa QApplication, QAbstractEventDispatcher, QEventLoop,
534 {Semaphores Example}, {Wait Conditions Example}
538 \fn static QCoreApplication *QCoreApplication::instance()
540 Returns a pointer to the application's QCoreApplication (or
541 QApplication) instance.
543 If no instance has been allocated, \c null is returned.
548 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
552 // note: it is the subclasses' job to call
553 // QCoreApplicationPrivate::eventDispatcher->startingUp();
557 Flushes the platform specific event queues.
559 If you are doing graphical changes inside a loop that does not
560 return to the event loop on asynchronous window systems like X11
561 or double buffered window systems like Mac OS X, and you want to
562 visualize these changes immediately (e.g. Splash Screens), call
565 \sa sendPostedEvents()
567 void QCoreApplication::flush()
569 if (self && self->d_func()->eventDispatcher)
570 self->d_func()->eventDispatcher->flush();
574 Constructs a Qt kernel application. Kernel applications are
575 applications without a graphical user interface. These type of
576 applications are used at the console or as server processes.
578 The \a argc and \a argv arguments are processed by the application,
579 and made available in a more convenient form by the arguments()
582 \warning The data referred to by \a argc and \a argv must stay valid
583 for the entire lifetime of the QCoreApplication object. In addition,
584 \a argc must be greater than zero and \a argv must contain at least
585 one valid character string.
587 QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
588 : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
591 QCoreApplicationPrivate::eventDispatcher->startingUp();
592 #if defined(Q_OS_SYMBIAN)
593 #ifndef QT_NO_LIBRARY
594 // Refresh factoryloader, as text codecs are requested during lib path
595 // resolving process and won't be therefore properly loaded.
596 // Unknown if this is symbian specific issue.
597 QFactoryLoader::refreshAll();
599 #ifndef QT_NO_SYSTEMLOCALE
600 d_func()->symbianInit();
602 #endif //Q_OS_SYMBIAN
606 // ### move to QCoreApplicationPrivate constructor?
607 void QCoreApplication::init()
609 Q_D(QCoreApplication);
612 setlocale(LC_ALL, ""); // use correct char set mapping
613 qt_locale_initialized = true;
616 Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
617 QCoreApplication::self = this;
620 //ensure temp and working directories exist
621 QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::tempPath()), true);
622 QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::currentPath()), true);
626 QThread::initialize();
629 // use the event dispatcher created by the app programmer (if any)
630 if (!QCoreApplicationPrivate::eventDispatcher)
631 QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
632 // otherwise we create one
633 if (!QCoreApplicationPrivate::eventDispatcher)
634 d->createEventDispatcher();
635 Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
637 if (!QCoreApplicationPrivate::eventDispatcher->parent())
638 QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
640 d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
642 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
643 if (!coreappdata()->app_libpaths) {
644 // make sure that library paths is initialized
647 d->appendApplicationPathToLibraryPaths();
652 extern void qt_core_eval_init(uint);
653 qt_core_eval_init(d->application_type);
656 #if defined(Q_OS_SYMBIAN) \
657 && defined(Q_CC_NOKIAX86) \
660 * Prevent the executable from being locked in the Symbian emulator. The
661 * code dramatically simplifies debugging on Symbian, but beyond that has
664 * Force the ZLazyUnloadTimer to fire and therefore unload code segments
665 * immediately. The code affects Symbian's file server and on the other
666 * hand needs only to be run once in each emulator run.
670 CleanupClosePushL(loader);
671 User::LeaveIfError(loader.Connect());
672 User::LeaveIfError(loader.CancelLazyDllUnload());
673 CleanupStack::PopAndDestroy(&loader);
680 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
681 void QCoreApplicationPrivate::symbianInit()
683 if (!environmentChangeNotifier)
684 environmentChangeNotifier.reset(new QEnvironmentChangeNotifier);
690 Destroys the QCoreApplication object.
692 QCoreApplication::~QCoreApplication()
694 qt_call_post_routines();
697 QCoreApplicationPrivate::is_app_closing = true;
698 QCoreApplicationPrivate::is_app_running = false;
700 #if !defined(QT_NO_THREAD)
701 #if !defined(QT_NO_CONCURRENT)
702 // Synchronize and stop the global thread pool threads.
703 QThreadPool *globalThreadPool = 0;
705 globalThreadPool = QThreadPool::globalInstance();
707 // swallow the exception, since destructors shouldn't throw
709 if (globalThreadPool)
710 globalThreadPool->waitForDone();
715 d_func()->threadData->eventDispatcher = 0;
716 if (QCoreApplicationPrivate::eventDispatcher)
717 QCoreApplicationPrivate::eventDispatcher->closingDown();
718 QCoreApplicationPrivate::eventDispatcher = 0;
720 #ifndef QT_NO_LIBRARY
721 delete coreappdata()->app_libpaths;
722 coreappdata()->app_libpaths = 0;
728 Sets the attribute \a attribute if \a on is true;
729 otherwise clears the attribute.
731 One of the attributes that can be set with this method is
732 Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
733 windows immediately. Normally, resources for widgets are allocated
734 on demand to improve efficiency and minimize resource usage.
735 Therefore, if it is important to minimize resource consumption, do
736 not set this attribute.
740 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
743 QCoreApplicationPrivate::attribs |= 1 << attribute;
745 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
749 Returns true if attribute \a attribute is set;
750 otherwise returns false.
754 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
756 return QCoreApplicationPrivate::testAttribute(attribute);
763 This function is here to make it possible for Qt extensions to
764 hook into event notification without subclassing QApplication
766 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
768 // Make it possible for Qt Jambi and QSA to hook into events even
769 // though QApplication is subclassed...
771 void *cbdata[] = { receiver, event, &result };
772 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
776 // Qt enforces the rule that events can only be sent to objects in
777 // the current thread, so receiver->d_func()->threadData is
778 // equivalent to QThreadData::current(), just without the function
780 QObjectPrivate *d = receiver->d_func();
781 QThreadData *threadData = d->threadData;
783 // Exception-safety without try/catch
786 inline Incrementer(int &variable) : variable(variable)
788 inline ~Incrementer()
791 Incrementer inc(threadData->loopLevel);
793 #ifdef QT_JAMBI_BUILD
795 int *oldDeleteWatch = QObjectPrivate::setDeleteWatch(d, &deleteWatch);
797 bool inEvent = d->inEventHandler;
798 d->inEventHandler = true;
802 returnValue = notify(receiver, event);
804 #ifdef QT_JAMBI_BUILD
805 // Restore the previous state if the object was not deleted..
807 d->inEventHandler = inEvent;
809 QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
816 Sends \a event to \a receiver: \a {receiver}->event(\a event).
817 Returns the value that is returned from the receiver's event
818 handler. Note that this function is called for all events sent to
819 any object in any thread.
821 For certain types of events (e.g. mouse and key events),
822 the event will be propagated to the receiver's parent and so on up to
823 the top-level object if the receiver is not interested in the event
824 (i.e., it returns false).
826 There are five different ways that events can be processed;
827 reimplementing this virtual function is just one of them. All five
828 approaches are listed below:
830 \i Reimplementing paintEvent(), mousePressEvent() and so
831 on. This is the commonest, easiest and least powerful way.
833 \i Reimplementing this function. This is very powerful, providing
834 complete control; but only one subclass can be active at a time.
836 \i Installing an event filter on QCoreApplication::instance(). Such
837 an event filter is able to process all events for all widgets, so
838 it's just as powerful as reimplementing notify(); furthermore, it's
839 possible to have more than one application-global event filter.
840 Global event filters even see mouse events for
841 \l{QWidget::isEnabled()}{disabled widgets}. Note that application
842 event filters are only called for objects that live in the main
845 \i Reimplementing QObject::event() (as QWidget does). If you do
846 this you get Tab key presses, and you get to see the events before
847 any widget-specific event filters.
849 \i Installing an event filter on the object. Such an event filter gets all
850 the events, including Tab and Shift+Tab key press events, as long as they
851 do not change the focus widget.
854 \sa QObject::event(), installEventFilter()
857 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
859 Q_D(QCoreApplication);
860 // no events are delivered after ~QCoreApplication() has started
861 if (QCoreApplicationPrivate::is_app_closing)
864 if (receiver == 0) { // serious error
865 qWarning("QCoreApplication::notify: Unexpected null receiver");
870 d->checkReceiverThread(receiver);
873 return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
876 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
878 if (receiver->d_func()->threadData == this->threadData) {
879 // application event filters are only called for objects in the GUI thread
880 for (int i = 0; i < eventFilters.size(); ++i) {
881 register QObject *obj = eventFilters.at(i);
884 if (obj->d_func()->threadData != threadData) {
885 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
888 if (obj->eventFilter(receiver, event))
895 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
897 Q_Q(QCoreApplication);
899 for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
900 register QObject *obj = receiver->d_func()->eventFilters.at(i);
903 if (obj->d_func()->threadData != receiver->d_func()->threadData) {
904 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
907 if (obj->eventFilter(receiver, event))
916 Helper function called by notify()
918 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
920 // send to all application event filters
921 if (sendThroughApplicationEventFilters(receiver, event))
923 // send to all receiver event filters
924 if (sendThroughObjectEventFilters(receiver, event))
927 return receiver->event(event);
931 Returns true if an application object has not been created yet;
932 otherwise returns false.
937 bool QCoreApplication::startingUp()
939 return !QCoreApplicationPrivate::is_app_running;
943 Returns true if the application objects are being destroyed;
944 otherwise returns false.
949 bool QCoreApplication::closingDown()
951 return QCoreApplicationPrivate::is_app_closing;
956 Processes all pending events for the calling thread according to
957 the specified \a flags until there are no more events to process.
959 You can call this function occasionally when your program is busy
960 performing a long operation (e.g. copying a file).
962 In event you are running a local loop which calls this function
963 continuously, without an event loop, the
964 \l{QEvent::DeferredDelete}{DeferredDelete} events will
965 not be processed. This can affect the behaviour of widgets,
966 e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
967 events to function properly. An alternative would be to call
968 \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
969 within that local loop.
971 Calling this function processes events only for the calling thread.
975 \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
977 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
979 QThreadData *data = QThreadData::current();
980 if (!data->eventDispatcher)
982 if (flags & QEventLoop::DeferredDeletion)
983 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
984 data->eventDispatcher->processEvents(flags);
988 \overload processEvents()
990 Processes pending events for the calling thread for \a maxtime
991 milliseconds or until there are no more events to process,
992 whichever is shorter.
994 You can call this function occasionally when you program is busy
995 doing a long operation (e.g. copying a file).
997 Calling this function processes events only for the calling thread.
1001 \sa exec(), QTimer, QEventLoop::processEvents()
1003 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
1005 QThreadData *data = QThreadData::current();
1006 if (!data->eventDispatcher)
1008 QElapsedTimer start;
1010 if (flags & QEventLoop::DeferredDeletion)
1011 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1012 while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1013 if (start.elapsed() > maxtime)
1015 if (flags & QEventLoop::DeferredDeletion)
1016 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1020 /*****************************************************************************
1021 Main event loop wrappers
1022 *****************************************************************************/
1025 Enters the main event loop and waits until exit() is called.
1026 Returns the value that was set to exit() (which is 0 if exit() is
1029 It is necessary to call this function to start event handling. The
1030 main event loop receives events from the window system and
1031 dispatches these to the application widgets.
1033 To make your application perform idle processing (i.e. executing a
1034 special function whenever there are no pending events), use a
1035 QTimer with 0 timeout. More advanced idle processing schemes can
1036 be achieved using processEvents().
1038 We recommend that you connect clean-up code to the
1039 \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1040 your application's \c{main()} function because on some platforms the
1041 QCoreApplication::exec() call may not return. For example, on Windows
1042 when the user logs off, the system terminates the process after Qt
1043 closes all top-level windows. Hence, there is no guarantee that the
1044 application will have time to exit its event loop and execute code at
1045 the end of the \c{main()} function after the QCoreApplication::exec()
1048 \sa quit(), exit(), processEvents(), QApplication::exec()
1050 int QCoreApplication::exec()
1052 if (!QCoreApplicationPrivate::checkInstance("exec"))
1055 QThreadData *threadData = self->d_func()->threadData;
1056 if (threadData != QThreadData::current()) {
1057 qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1060 if (!threadData->eventLoops.isEmpty()) {
1061 qWarning("QCoreApplication::exec: The event loop is already running");
1065 threadData->quitNow = false;
1066 QEventLoop eventLoop;
1067 self->d_func()->in_exec = true;
1068 self->d_func()->aboutToQuitEmitted = false;
1069 int returnCode = eventLoop.exec();
1070 threadData->quitNow = false;
1072 self->d_func()->in_exec = false;
1073 if (!self->d_func()->aboutToQuitEmitted)
1074 emit self->aboutToQuit();
1075 self->d_func()->aboutToQuitEmitted = true;
1076 sendPostedEvents(0, QEvent::DeferredDelete);
1084 Tells the application to exit with a return code.
1086 After this function has been called, the application leaves the
1087 main event loop and returns from the call to exec(). The exec()
1088 function returns \a returnCode. If the event loop is not running,
1089 this function does nothing.
1091 By convention, a \a returnCode of 0 means success, and any non-zero
1092 value indicates an error.
1094 Note that unlike the C library function of the same name, this
1095 function \e does return to the caller -- it is event processing that
1100 void QCoreApplication::exit(int returnCode)
1104 QThreadData *data = self->d_func()->threadData;
1105 data->quitNow = true;
1106 for (int i = 0; i < data->eventLoops.size(); ++i) {
1107 QEventLoop *eventLoop = data->eventLoops.at(i);
1108 eventLoop->exit(returnCode);
1112 /*****************************************************************************
1113 QCoreApplication management of posted events
1114 *****************************************************************************/
1117 \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1119 Sends event \a event directly to receiver \a receiver, using the
1120 notify() function. Returns the value that was returned from the
1123 The event is \e not deleted when the event has been sent. The normal
1124 approach is to create the event on the stack, for example:
1126 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
1128 \sa postEvent(), notify()
1132 Adds the event \a event, with the object \a receiver as the
1133 receiver of the event, to an event queue and returns immediately.
1135 The event must be allocated on the heap since the post event queue
1136 will take ownership of the event and delete it once it has been
1137 posted. It is \e {not safe} to access the event after
1140 When control returns to the main event loop, all events that are
1141 stored in the queue will be sent using the notify() function.
1143 Events are processed in the order posted. For more control over
1144 the processing order, use the postEvent() overload below, which
1145 takes a priority argument. This function posts all event with a
1146 Qt::NormalEventPriority.
1150 \sa sendEvent(), notify(), sendPostedEvents()
1153 void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
1155 postEvent(receiver, event, Qt::NormalEventPriority);
1160 \overload postEvent()
1163 Adds the event \a event, with the object \a receiver as the
1164 receiver of the event, to an event queue and returns immediately.
1166 The event must be allocated on the heap since the post event queue
1167 will take ownership of the event and delete it once it has been
1168 posted. It is \e {not safe} to access the event after
1171 When control returns to the main event loop, all events that are
1172 stored in the queue will be sent using the notify() function.
1174 Events are sorted in descending \a priority order, i.e. events
1175 with a high \a priority are queued before events with a lower \a
1176 priority. The \a priority can be any integer value, i.e. between
1177 INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1178 details. Events with equal \a priority will be processed in the
1183 \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1185 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1187 if (receiver == 0) {
1188 qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1193 QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1194 QThreadData *data = *pdata;
1196 // posting during destruction? just delete the event to prevent a leak
1201 // lock the post event mutex
1202 data->postEventList.mutex.lock();
1204 // if object has moved to another thread, follow it
1205 while (data != *pdata) {
1206 data->postEventList.mutex.unlock();
1210 // posting during destruction? just delete the event to prevent a leak
1215 data->postEventList.mutex.lock();
1218 QMutexUnlocker locker(&data->postEventList.mutex);
1220 // if this is one of the compressible events, do compression
1221 if (receiver->d_func()->postedEvents
1222 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1226 if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1227 // remember the current running eventloop for DeferredDelete
1228 // events posted in the receiver's thread
1229 event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel));
1232 // delete the event on exceptions to protect against memory leaks till the event is
1233 // properly owned in the postEventList
1234 QScopedPointer<QEvent> eventDeleter(event);
1235 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1236 eventDeleter.take();
1237 event->posted = true;
1238 ++receiver->d_func()->postedEvents;
1239 data->canWait = false;
1242 if (data->eventDispatcher)
1243 data->eventDispatcher->wakeUp();
1248 Returns true if \a event was compressed away (possibly deleted) and should not be added to the list.
1250 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1255 Q_ASSERT(postedEvents);
1257 // compress posted timers to this object.
1258 if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1259 int timerId = ((QTimerEvent *) event)->timerId();
1260 for (int i=0; i<postedEvents->size(); ++i) {
1261 const QPostEvent &e = postedEvents->at(i);
1262 if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1263 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1270 if ((event->type() == QEvent::DeferredDelete
1271 || event->type() == QEvent::Quit)
1272 && receiver->d_func()->postedEvents > 0) {
1273 for (int i = 0; i < postedEvents->size(); ++i) {
1274 const QPostEvent &cur = postedEvents->at(i);
1275 if (cur.receiver != receiver
1277 || cur.event->type() != event->type())
1279 // found an event for this receiver
1288 \fn void QCoreApplication::sendPostedEvents()
1289 \overload sendPostedEvents()
1291 Dispatches all posted events, i.e. empties the event queue.
1295 Immediately dispatches all events which have been previously queued
1296 with QCoreApplication::postEvent() and which are for the object \a receiver
1297 and have the event type \a event_type.
1299 Events from the window system are \e not dispatched by this
1300 function, but by processEvents().
1302 If \a receiver is null, the events of \a event_type are sent for all
1303 objects. If \a event_type is 0, all the events are sent for \a receiver.
1305 \note This method must be called from the same thread as its QObject parameter, \a receiver.
1307 \sa flush(), postEvent()
1310 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1312 QThreadData *data = QThreadData::current();
1314 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1317 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1320 if (event_type == -1) {
1321 // we were called by an obsolete event dispatcher.
1325 if (receiver && receiver->d_func()->threadData != data) {
1326 qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1327 "posted events for objects in another thread");
1331 ++data->postEventList.recursion;
1333 QMutexLocker locker(&data->postEventList.mutex);
1335 // by default, we assume that the event dispatcher can go to sleep after
1336 // processing all events. if any new events are posted while we send
1337 // events, canWait will be set to false.
1338 data->canWait = (data->postEventList.size() == 0);
1340 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1341 --data->postEventList.recursion;
1345 data->canWait = true;
1347 // okay. here is the tricky loop. be careful about optimizing
1348 // this, it looks the way it does for good reasons.
1349 int startOffset = data->postEventList.startOffset;
1350 int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1351 data->postEventList.insertionOffset = data->postEventList.size();
1353 // Exception-safe cleaning up without the need for a try/catch block
1358 bool exceptionCaught;
1360 inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1361 receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1365 if (exceptionCaught) {
1366 // since we were interrupted, we need another pass to make sure we clean everything up
1367 data->canWait = false;
1370 --data->postEventList.recursion;
1371 if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1372 data->eventDispatcher->wakeUp();
1374 // clear the global list, i.e. remove everything that was
1376 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1377 const QPostEventList::iterator it = data->postEventList.begin();
1378 data->postEventList.erase(it, it + data->postEventList.startOffset);
1379 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1380 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1381 data->postEventList.startOffset = 0;
1385 CleanUp cleanup(receiver, event_type, data);
1387 while (i < data->postEventList.size()) {
1389 if (i >= data->postEventList.insertionOffset)
1392 const QPostEvent &pe = data->postEventList.at(i);
1397 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1398 data->canWait = false;
1402 if (pe.event->type() == QEvent::DeferredDelete) {
1403 // DeferredDelete events are only sent when we are explicitly asked to
1404 // (s.a. QEvent::DeferredDelete), and then only if the event loop that
1405 // posted the event has returned.
1406 const bool allowDeferredDelete =
1407 (quintptr(pe.event->d) > unsigned(data->loopLevel)
1408 || (!quintptr(pe.event->d) && data->loopLevel > 0)
1409 || (event_type == QEvent::DeferredDelete
1410 && quintptr(pe.event->d) == unsigned(data->loopLevel)));
1411 if (!allowDeferredDelete) {
1412 // cannot send deferred delete
1413 if (!event_type && !receiver) {
1414 // don't lose the event
1415 data->postEventList.addEvent(pe);
1416 const_cast<QPostEvent &>(pe).event = 0;
1422 // first, we diddle the event so that we can deliver
1423 // it, and that no one will try to touch it later.
1424 pe.event->posted = false;
1425 QScopedPointer<QEvent> e(pe.event);
1426 QObject * r = pe.receiver;
1428 --r->d_func()->postedEvents;
1429 Q_ASSERT(r->d_func()->postedEvents >= 0);
1431 // next, update the data structure so that we're ready
1432 // for the next event.
1433 const_cast<QPostEvent &>(pe).event = 0;
1435 struct MutexUnlocker
1438 MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); }
1439 ~MutexUnlocker() { m.relock(); }
1441 MutexUnlocker unlocker(locker);
1443 // after all that work, it's time to deliver the event.
1444 QCoreApplication::sendEvent(r, e.data());
1446 // careful when adding anything below this point - the
1447 // sendEvent() call might invalidate any invariants this
1448 // function depends on.
1451 cleanup.exceptionCaught = false;
1455 Removes all events posted using postEvent() for \a receiver.
1457 The events are \e not dispatched, instead they are removed from the
1458 queue. You should never need to call this function. If you do call it,
1459 be aware that killing events may cause \a receiver to break one or
1465 void QCoreApplication::removePostedEvents(QObject *receiver)
1467 removePostedEvents(receiver, 0);
1471 \overload removePostedEvents()
1474 Removes all events of the given \a eventType that were posted
1475 using postEvent() for \a receiver.
1477 The events are \e not dispatched, instead they are removed from
1478 the queue. You should never need to call this function. If you do
1479 call it, be aware that killing events may cause \a receiver to
1480 break one or more invariants.
1482 If \a receiver is null, the events of \a eventType are removed for
1483 all objects. If \a eventType is 0, all the events are removed for
1489 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1491 QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1492 QMutexLocker locker(&data->postEventList.mutex);
1494 // the QObject destructor calls this function directly. this can
1495 // happen while the event loop is in the middle of posting events,
1496 // and when we get here, we may not have any more posted events
1498 if (receiver && !receiver->d_func()->postedEvents)
1501 //we will collect all the posted events for the QObject
1502 //and we'll delete after the mutex was unlocked
1503 QVarLengthArray<QEvent*> events;
1504 int n = data->postEventList.size();
1507 for (int i = 0; i < n; ++i) {
1508 const QPostEvent &pe = data->postEventList.at(i);
1510 if ((!receiver || pe.receiver == receiver)
1511 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1512 --pe.receiver->d_func()->postedEvents;
1513 pe.event->posted = false;
1514 events.append(pe.event);
1515 const_cast<QPostEvent &>(pe).event = 0;
1516 } else if (!data->postEventList.recursion) {
1518 data->postEventList.swap(i, j);
1524 if (receiver && eventType == 0) {
1525 Q_ASSERT(!receiver->d_func()->postedEvents);
1529 if (!data->postEventList.recursion) {
1531 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1535 for (int i = 0; i < events.count(); ++i) {
1541 Removes \a event from the queue of posted events, and emits a
1542 warning message if appropriate.
1544 \warning This function can be \e really slow. Avoid using it, if
1550 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1552 if (!event || !event->posted)
1555 QThreadData *data = QThreadData::current();
1557 QMutexLocker locker(&data->postEventList.mutex);
1559 if (data->postEventList.size() == 0) {
1560 #if defined(QT_DEBUG)
1561 qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1562 (void*)event, event->type());
1567 for (int i = 0; i < data->postEventList.size(); ++i) {
1568 const QPostEvent & pe = data->postEventList.at(i);
1569 if (pe.event == event) {
1571 qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1573 pe.receiver->metaObject()->className(),
1574 pe.receiver->objectName().toLocal8Bit().data());
1576 --pe.receiver->d_func()->postedEvents;
1577 pe.event->posted = false;
1579 const_cast<QPostEvent &>(pe).event = 0;
1588 bool QCoreApplication::event(QEvent *e)
1590 if (e->type() == QEvent::Quit) {
1594 return QObject::event(e);
1597 /*! \enum QCoreApplication::Encoding
1599 This enum type defines the 8-bit encoding of character string
1600 arguments to translate():
1602 \value CodecForTr The encoding specified by
1603 QTextCodec::codecForTr() (Latin-1 if none has
1605 \value UnicodeUTF8 UTF-8.
1606 \value DefaultCodec (Obsolete) Use CodecForTr instead.
1608 \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
1612 Tells the application to exit with return code 0 (success).
1613 Equivalent to calling QCoreApplication::exit(0).
1615 It's common to connect the QApplication::lastWindowClosed() signal
1616 to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1617 signals in QAction, QMenu, or QMenuBar to it.
1621 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
1623 \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
1626 void QCoreApplication::quit()
1632 \fn void QCoreApplication::aboutToQuit()
1634 This signal is emitted when the application is about to quit the
1635 main event loop, e.g. when the event loop level drops to zero.
1636 This may happen either after a call to quit() from inside the
1637 application or when the users shuts down the entire desktop session.
1639 The signal is particularly useful if your application has to do some
1640 last-second cleanup. Note that no user interaction is possible in
1646 #ifndef QT_NO_TRANSLATION
1648 Adds the translation file \a translationFile to the list of
1649 translation files to be used for translations.
1651 Multiple translation files can be installed. Translations are
1652 searched for in the reverse order in which they were installed,
1653 so the most recently installed translation file is searched first
1654 and the first translation file installed is searched last.
1655 The search stops as soon as a translation containing a matching
1658 Installing or removing a QTranslator, or changing an installed QTranslator
1659 generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1660 QCoreApplication instance. A QApplication instance will propagate the event
1661 to all toplevel windows, where a reimplementation of changeEvent can
1662 re-translate the user interface by passing user-visible strings via the
1663 tr() function to the respective property setters. User-interface classes
1664 generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
1667 \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
1670 void QCoreApplication::installTranslator(QTranslator *translationFile)
1672 if (!translationFile)
1675 if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1677 QCoreApplicationPrivate *d = self->d_func();
1678 d->translators.prepend(translationFile);
1680 #ifndef QT_NO_TRANSLATION_BUILDER
1681 if (translationFile->isEmpty())
1685 QEvent ev(QEvent::LanguageChange);
1686 QCoreApplication::sendEvent(self, &ev);
1690 Removes the translation file \a translationFile from the list of
1691 translation files used by this application. (It does not delete the
1692 translation file from the file system.)
1694 \sa installTranslator() translate(), QObject::tr()
1697 void QCoreApplication::removeTranslator(QTranslator *translationFile)
1699 if (!translationFile)
1701 if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1703 QCoreApplicationPrivate *d = self->d_func();
1704 if (d->translators.removeAll(translationFile) && !self->closingDown()) {
1705 QEvent ev(QEvent::LanguageChange);
1706 QCoreApplication::sendEvent(self, &ev);
1711 \overload translate()
1713 QString QCoreApplication::translate(const char *context, const char *sourceText,
1714 const char *disambiguation, Encoding encoding)
1716 return translate(context, sourceText, disambiguation, encoding, -1);
1719 static void replacePercentN(QString *result, int n)
1724 while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1727 if (result->at(percentPos + len) == QLatin1Char('L')) {
1729 fmt = QLatin1String("%L1");
1731 fmt = QLatin1String("%1");
1733 if (result->at(percentPos + len) == QLatin1Char('n')) {
1736 result->replace(percentPos, len, fmt);
1747 Returns the translation text for \a sourceText, by querying the
1748 installed translation files. The translation files are searched
1749 from the most recently installed file back to the first
1752 QObject::tr() and QObject::trUtf8() provide this functionality
1755 \a context is typically a class name (e.g., "MyDialog") and \a
1756 sourceText is either English text or a short identifying text.
1758 \a disambiguation is an identifying string, for when the same \a
1759 sourceText is used in different roles within the same context. By
1760 default, it is null.
1762 See the \l QTranslator and \l QObject::tr() documentation for
1763 more information about contexts, disambiguations and comments.
1765 \a encoding indicates the 8-bit encoding of character strings.
1767 \a n is used in conjunction with \c %n to support plural forms.
1768 See QObject::tr() for details.
1770 If none of the translation files contain a translation for \a
1771 sourceText in \a context, this function returns a QString
1772 equivalent of \a sourceText. The encoding of \a sourceText is
1773 specified by \e encoding; it defaults to CodecForTr.
1775 This function is not virtual. You can use alternative translation
1776 techniques by subclassing \l QTranslator.
1778 \warning This method is reentrant only if all translators are
1779 installed \e before calling this method. Installing or removing
1780 translators while performing translations is not supported. Doing
1781 so will most likely result in crashes or other undesirable
1784 \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
1788 QString QCoreApplication::translate(const char *context, const char *sourceText,
1789 const char *disambiguation, Encoding encoding, int n)
1796 if (self && !self->d_func()->translators.isEmpty()) {
1797 QList<QTranslator*>::ConstIterator it;
1798 QTranslator *translationFile;
1799 for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
1800 translationFile = *it;
1801 result = translationFile->translate(context, sourceText, disambiguation, n);
1802 if (!result.isEmpty())
1807 if (result.isEmpty()) {
1808 #ifdef QT_NO_TEXTCODEC
1811 if (encoding == UnicodeUTF8)
1812 result = QString::fromUtf8(sourceText);
1813 else if (QTextCodec::codecForTr() != 0)
1814 result = QTextCodec::codecForTr()->toUnicode(sourceText);
1817 result = QString::fromLatin1(sourceText);
1820 replacePercentN(&result, n);
1824 // Declared in qglobal.h
1825 QString qtTrId(const char *id, int n)
1827 return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n);
1830 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
1832 return QCoreApplication::self
1833 && QCoreApplication::self->d_func()->translators.contains(translator);
1836 #endif //QT_NO_TRANSLATE
1839 Returns the directory that contains the application executable.
1841 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1842 directory, and you run the \c{regexp} example, this function will
1843 return "C:/Trolltech/Qt/examples/tools/regexp".
1845 On Mac OS X this will point to the directory actually containing the
1846 executable, which may be inside of an application bundle (if the
1847 application is bundled).
1849 \warning On Linux, this function will try to get the path from the
1850 \c {/proc} file system. If that fails, it assumes that \c
1851 {argv[0]} contains the absolute file name of the executable. The
1852 function also assumes that the current directory has not been
1853 changed by the application.
1855 In Symbian this function will return the application private directory,
1856 not the path to executable itself, as those are always in \c {/sys/bin}.
1857 If the application is in a read only drive, i.e. ROM, then the private path
1858 on the system drive will be returned.
1860 \sa applicationFilePath()
1862 QString QCoreApplication::applicationDirPath()
1865 qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
1869 QCoreApplicationPrivate *d = self->d_func();
1870 if (d->cachedApplicationDirPath.isNull())
1871 #if defined(Q_OS_SYMBIAN)
1874 RFs& fs = qt_s60GetRFs();
1877 driveChar = (RProcess().FileName())[0];
1879 //Check if the process is installed in a read only drive (typically ROM),
1880 //and use the system drive (typically C:) if so.
1882 TDriveInfo driveInfo;
1883 TInt err = fs.CharToDrive(driveChar, drive);
1884 if (err == KErrNone) {
1885 err = fs.Drive(driveInfo, drive);
1887 if (err != KErrNone || (driveInfo.iDriveAtt & KDriveAttRom) || (driveInfo.iMediaAtt
1888 & KMediaAttWriteProtected)) {
1889 if(!PtrGetSystemDrive)
1890 PtrGetSystemDrive = reinterpret_cast<SystemDriveFunc>(qt_resolveS60PluginFunc(S60Plugin_GetSystemDrive));
1891 Q_ASSERT(PtrGetSystemDrive);
1892 drive = PtrGetSystemDrive(fs);
1893 fs.DriveToChar(drive, driveChar);
1896 qDriveChar = QChar(QLatin1Char(driveChar)).toUpper();
1898 TFileName privatePath;
1899 fs.PrivatePath(privatePath);
1900 appPath = qt_TDesC2QString(privatePath);
1901 appPath.prepend(QLatin1Char(':')).prepend(qDriveChar);
1903 // Create the appPath if it doesn't exist. Non-existing appPath will cause
1904 // Platform Security violations later on if the app doesn't have AllFiles capability.
1905 err = fs.CreatePrivatePath(drive);
1906 if (err != KErrNone)
1907 qWarning("QCoreApplication::applicationDirPath: Failed to create private path.");
1909 d->cachedApplicationDirPath = QFileInfo(appPath).path();
1912 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
1914 return d->cachedApplicationDirPath;
1918 Returns the file path of the application executable.
1920 For example, if you have installed Qt in the \c{/usr/local/qt}
1921 directory, and you run the \c{regexp} example, this function will
1922 return "/usr/local/qt/examples/tools/regexp/regexp".
1924 \warning On Linux, this function will try to get the path from the
1925 \c {/proc} file system. If that fails, it assumes that \c
1926 {argv[0]} contains the absolute file name of the executable. The
1927 function also assumes that the current directory has not been
1928 changed by the application.
1930 \sa applicationDirPath()
1932 QString QCoreApplication::applicationFilePath()
1935 qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
1939 QCoreApplicationPrivate *d = self->d_func();
1940 if (!d->cachedApplicationFilePath.isNull())
1941 return d->cachedApplicationFilePath;
1943 #if defined(Q_OS_WIN)
1944 d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
1945 return d->cachedApplicationFilePath;
1946 #elif defined(Q_WS_MAC)
1947 QString qAppFileName_str = qAppFileName();
1948 if(!qAppFileName_str.isEmpty()) {
1949 QFileInfo fi(qAppFileName_str);
1950 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
1951 return d->cachedApplicationFilePath;
1954 #if defined(Q_OS_SYMBIAN)
1957 TInt err = proc.Open(proc.Id());
1958 if (err == KErrNone) {
1959 TFileName procName = proc.FileName();
1960 appPath.append(QString(reinterpret_cast<const QChar*>(procName.Ptr()), procName.Length()));
1964 d->cachedApplicationFilePath = appPath;
1965 return d->cachedApplicationFilePath;
1967 #elif defined( Q_OS_UNIX )
1969 // Try looking for a /proc/<pid>/exe symlink first which points to
1970 // the absolute path of the executable
1971 QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
1972 if (pfi.exists() && pfi.isSymLink()) {
1973 d->cachedApplicationFilePath = pfi.canonicalFilePath();
1974 return d->cachedApplicationFilePath;
1978 QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
1981 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
1983 If argv0 starts with a slash, it is already an absolute
1987 } else if (argv0.contains(QLatin1Char('/'))) {
1989 If argv0 contains one or more slashes, it is a file path
1990 relative to the current directory.
1992 absPath = QDir::current().absoluteFilePath(argv0);
1995 Otherwise, the file path has to be determined using the
1996 PATH environment variable.
1998 QByteArray pEnv = qgetenv("PATH");
1999 QDir currentDir = QDir::current();
2000 QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
2001 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
2004 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
2005 QFileInfo candidate_fi(candidate);
2006 if (candidate_fi.exists() && !candidate_fi.isDir()) {
2007 absPath = candidate;
2013 absPath = QDir::cleanPath(absPath);
2015 QFileInfo fi(absPath);
2016 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
2017 return d->cachedApplicationFilePath;
2024 Returns the current process ID for the application.
2026 qint64 QCoreApplication::applicationPid()
2028 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
2029 return GetCurrentProcessId();
2030 #elif defined(Q_OS_VXWORKS)
2031 return (pid_t) taskIdCurrent;
2040 Use arguments().size() instead.
2042 int QCoreApplication::argc()
2045 qWarning("QCoreApplication::argc: Please instantiate the QApplication object first");
2048 return self->d_func()->argc;
2055 Use arguments() instead.
2057 char **QCoreApplication::argv()
2060 qWarning("QCoreApplication::argv: Please instantiate the QApplication object first");
2063 return self->d_func()->argv;
2069 Returns the list of command-line arguments.
2071 Usually arguments().at(0) is the program name, arguments().at(1)
2072 is the first argument, and arguments().last() is the last
2073 argument. See the note below about Windows.
2075 Calling this function is slow - you should store the result in a variable
2076 when parsing the command line.
2078 \warning On Unix, this list is built from the argc and argv parameters passed
2079 to the constructor in the main() function. The string-data in argv is
2080 interpreted using QString::fromLocal8Bit(); hence it is not possible to
2081 pass, for example, Japanese command line arguments on a system that runs in a
2082 Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2085 On NT-based Windows, this limitation does not apply either.
2086 On Windows, the arguments() are not built from the contents of argv/argc, as
2087 the content does not support Unicode. Instead, the arguments() are constructed
2088 from the return value of
2089 \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2090 As a result of this, the string given by arguments().at(0) might not be
2091 the program name on Windows, depending on how the application was started.
2093 For Symbian applications started with \c RApaLsSession::StartApp one can specify
2094 arguments using \c CApaCommandLine::SetTailEndL function. Such arguments are only
2095 available via this method; they will not be passed to \c main function. Also note
2096 that only 8-bit string data set with \c CApaCommandLine::SetTailEndL is supported
2099 \sa applicationFilePath()
2102 QStringList QCoreApplication::arguments()
2107 qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2111 QString cmdline = QString::fromWCharArray(GetCommandLine());
2113 #if defined(Q_OS_WINCE)
2114 wchar_t tempFilename[MAX_PATH+1];
2115 if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
2116 tempFilename[MAX_PATH] = 0;
2117 cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
2119 #endif // Q_OS_WINCE
2121 list = qWinCmdArgs(cmdline);
2122 if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
2123 QStringList stripped;
2124 for (int a = 0; a < list.count(); ++a) {
2125 QString arg = list.at(a);
2126 QByteArray l1arg = arg.toLatin1();
2127 if (l1arg == "-qdevel" ||
2128 l1arg == "-qdebug" ||
2129 l1arg == "-reverse" ||
2130 l1arg == "-stylesheet" ||
2131 l1arg == "-widgetcount")
2133 else if (l1arg.startsWith("-style=") ||
2134 l1arg.startsWith("-qmljsdebugger="))
2136 else if (l1arg == "-style" ||
2137 l1arg == "-session" ||
2138 l1arg == "-testability")
2146 const int ac = self->d_func()->argc;
2147 char ** const av = self->d_func()->argv;
2148 for (int a = 0; a < ac; ++a) {
2149 list << QString::fromLocal8Bit(av[a]);
2157 \property QCoreApplication::organizationName
2158 \brief the name of the organization that wrote this application
2160 The value is used by the QSettings class when it is constructed
2161 using the empty constructor. This saves having to repeat this
2162 information each time a QSettings object is created.
2164 On Mac, QSettings uses organizationDomain() as the organization
2165 if it's not an empty string; otherwise it uses
2166 organizationName(). On all other platforms, QSettings uses
2167 organizationName() as the organization.
2169 \sa organizationDomain applicationName
2172 void QCoreApplication::setOrganizationName(const QString &orgName)
2174 coreappdata()->orgName = orgName;
2177 QString QCoreApplication::organizationName()
2179 return coreappdata()->orgName;
2183 \property QCoreApplication::organizationDomain
2184 \brief the Internet domain of the organization that wrote this application
2186 The value is used by the QSettings class when it is constructed
2187 using the empty constructor. This saves having to repeat this
2188 information each time a QSettings object is created.
2190 On Mac, QSettings uses organizationDomain() as the organization
2191 if it's not an empty string; otherwise it uses organizationName().
2192 On all other platforms, QSettings uses organizationName() as the
2195 \sa organizationName applicationName applicationVersion
2197 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2199 coreappdata()->orgDomain = orgDomain;
2202 QString QCoreApplication::organizationDomain()
2204 return coreappdata()->orgDomain;
2208 \property QCoreApplication::applicationName
2209 \brief the name of this application
2211 The value is used by the QSettings class when it is constructed
2212 using the empty constructor. This saves having to repeat this
2213 information each time a QSettings object is created.
2215 \sa organizationName organizationDomain applicationVersion
2217 void QCoreApplication::setApplicationName(const QString &application)
2219 coreappdata()->application = application;
2222 QString QCoreApplication::applicationName()
2224 return coreappdata()->application;
2228 \property QCoreApplication::applicationVersion
2230 \brief the version of this application
2232 \sa applicationName organizationName organizationDomain
2234 void QCoreApplication::setApplicationVersion(const QString &version)
2236 coreappdata()->applicationVersion = version;
2239 QString QCoreApplication::applicationVersion()
2241 return coreappdata()->applicationVersion;
2244 #ifndef QT_NO_LIBRARY
2246 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2249 Returns a list of paths that the application will search when
2250 dynamically loading libraries.
2252 Qt provides default library paths, but they can also be set using
2253 a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2254 will override default values.
2256 This list will include the installation directory for plugins if
2257 it exists (the default installation directory for plugins is \c
2258 INSTALL/plugins, where \c INSTALL is the directory where Qt was
2259 installed). The directory of the application executable (NOT the
2260 working directory) is always added, as well as the colon separated
2261 entries of the QT_PLUGIN_PATH environment variable.
2263 If you want to iterate over the list, you can use the \l foreach
2266 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
2268 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2269 {How to Create Qt Plugins}
2271 QStringList QCoreApplication::libraryPaths()
2273 QMutexLocker locker(libraryPathMutex());
2274 if (!coreappdata()->app_libpaths) {
2275 QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
2276 QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
2277 #if defined(Q_OS_SYMBIAN)
2278 // Add existing path on all drives for relative PluginsPath in Symbian
2279 if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) {
2280 QString tempPath = installPathPlugins;
2281 if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
2282 tempPath += QDir::separator();
2284 RFs& fs = qt_s60GetRFs();
2285 TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
2286 TFindFile finder(fs);
2287 TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
2288 while (err == KErrNone) {
2289 QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
2290 finder.File().Length());
2291 foundDir = QDir(foundDir).canonicalPath();
2292 if (!app_libpaths->contains(foundDir))
2293 app_libpaths->append(foundDir);
2294 err = finder.Find();
2298 if (QFile::exists(installPathPlugins)) {
2299 // Make sure we convert from backslashes to slashes.
2300 installPathPlugins = QDir(installPathPlugins).canonicalPath();
2301 if (!app_libpaths->contains(installPathPlugins))
2302 app_libpaths->append(installPathPlugins);
2306 // If QCoreApplication is not yet instantiated,
2307 // make sure we add the application path when we construct the QCoreApplication
2308 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2310 const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2311 if (!libPathEnv.isEmpty()) {
2312 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
2313 QLatin1Char pathSep(';');
2315 QLatin1Char pathSep(':');
2317 QStringList paths = QString::fromLatin1(libPathEnv).split(pathSep, QString::SkipEmptyParts);
2318 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2319 QString canonicalPath = QDir(*it).canonicalPath();
2320 if (!canonicalPath.isEmpty()
2321 && !app_libpaths->contains(canonicalPath)) {
2322 app_libpaths->append(canonicalPath);
2327 return *(coreappdata()->app_libpaths);
2334 Sets the list of directories to search when loading libraries to
2335 \a paths. All existing paths will be deleted and the path list
2336 will consist of the paths given in \a paths.
2338 In Symbian this function is only useful for setting paths for
2339 finding Qt extension plugin stubs, since the OS can only
2340 load libraries from the \c{/sys/bin} directory.
2342 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2344 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2346 QMutexLocker locker(libraryPathMutex());
2347 if (!coreappdata()->app_libpaths)
2348 coreappdata()->app_libpaths = new QStringList;
2349 *(coreappdata()->app_libpaths) = paths;
2351 QFactoryLoader::refreshAll();
2355 Prepends \a path to the beginning of the library path list, ensuring that
2356 it is searched for libraries first. If \a path is empty or already in the
2357 path list, the path list is not changed.
2359 The default path list consists of a single entry, the installation
2360 directory for plugins. The default installation directory for plugins
2361 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2364 In Symbian this function is only useful for adding paths for
2365 finding Qt extension plugin stubs, since the OS can only
2366 load libraries from the \c{/sys/bin} directory.
2368 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2370 void QCoreApplication::addLibraryPath(const QString &path)
2375 QMutexLocker locker(libraryPathMutex());
2377 // make sure that library paths is initialized
2380 QString canonicalPath = QDir(path).canonicalPath();
2381 if (!canonicalPath.isEmpty()
2382 && !coreappdata()->app_libpaths->contains(canonicalPath)) {
2383 coreappdata()->app_libpaths->prepend(canonicalPath);
2385 QFactoryLoader::refreshAll();
2390 Removes \a path from the library path list. If \a path is empty or not
2391 in the path list, the list is not changed.
2393 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2395 void QCoreApplication::removeLibraryPath(const QString &path)
2400 QMutexLocker locker(libraryPathMutex());
2402 // make sure that library paths is initialized
2405 QString canonicalPath = QDir(path).canonicalPath();
2406 coreappdata()->app_libpaths->removeAll(canonicalPath);
2407 QFactoryLoader::refreshAll();
2410 #endif //QT_NO_LIBRARY
2413 \typedef QCoreApplication::EventFilter
2415 A function with the following signature that can be used as an
2418 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
2420 \sa setEventFilter()
2424 \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
2426 Replaces the event filter function for the QCoreApplication with
2427 \a filter and returns the pointer to the replaced event filter
2428 function. Only the current event filter function is called. If you
2429 want to use both filter functions, save the replaced EventFilter
2430 in a place where yours can call it.
2432 The event filter function set here is called for all messages
2433 received by all threads meant for all Qt objects. It is \e not
2434 called for messages that are not meant for Qt objects.
2436 The event filter function should return true if the message should
2437 be filtered, (i.e. stopped). It should return false to allow
2438 processing the message to continue.
2440 By default, no event filter function is set (i.e., this function
2441 returns a null EventFilter the first time it is called).
2443 \note The filter function set here receives native messages,
2444 i.e. MSG or XEvent structs, that are going to Qt objects. It is
2445 called by QCoreApplication::filterEvent(). If the filter function
2446 returns false to indicate the message should be processed further,
2447 the native message can then be translated into a QEvent and
2448 handled by the standard Qt \l{QEvent} {event} filering, e.g.
2449 QObject::installEventFilter().
2451 \note The filter function set here is different form the filter
2452 function set via QAbstractEventDispatcher::setEventFilter(), which
2453 gets all messages received by its thread, even messages meant for
2454 objects that are not handled by Qt.
2456 \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
2458 QCoreApplication::EventFilter
2459 QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
2461 Q_D(QCoreApplication);
2462 EventFilter old = d->eventFilter;
2463 d->eventFilter = filter;
2468 Sends \a message through the event filter that was set by
2469 setEventFilter(). If no event filter has been set, this function
2470 returns false; otherwise, this function returns the result of the
2471 event filter function in the \a result parameter.
2473 \sa setEventFilter()
2475 bool QCoreApplication::filterEvent(void *message, long *result)
2477 Q_D(QCoreApplication);
2481 return d->eventFilter(message, result);
2483 return winEventFilter(reinterpret_cast<MSG *>(message), result);
2490 This function returns true if there are pending events; otherwise
2491 returns false. Pending events can be either from the window
2492 system or posted events using postEvent().
2494 \sa QAbstractEventDispatcher::hasPendingEvents()
2496 bool QCoreApplication::hasPendingEvents()
2498 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2499 if (eventDispatcher)
2500 return eventDispatcher->hasPendingEvents();
2505 \fn void QCoreApplication::watchUnixSignal(int signal, bool watch)
2510 \fn void QCoreApplication::unixSignal(int number)
2513 This signal is emitted whenever a Unix signal is received by the
2514 application. The Unix signal received is specified by its \a number.
2518 \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2519 \relates QCoreApplication
2521 Adds a global routine that will be called from the QApplication
2522 destructor. This function is normally used to add cleanup routines
2523 for program-wide functionality.
2525 The function specified by \a ptr should take no arguments and should
2526 return nothing. For example:
2528 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
2530 Note that for an application- or module-wide cleanup,
2531 qAddPostRoutine() is often not suitable. For example, if the
2532 program is split into dynamically loaded modules, the relevant
2533 module may be unloaded long before the QApplication destructor is
2536 For modules and libraries, using a reference-counted
2537 initialization manager or Qt's parent-child deletion mechanism may
2538 be better. Here is an example of a private class that uses the
2539 parent-child mechanism to call a cleanup function at the right
2542 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
2544 By selecting the right parent object, this can often be made to
2545 clean up the module's data at the right moment.
2549 \macro Q_DECLARE_TR_FUNCTIONS(context)
2550 \relates QCoreApplication
2552 The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2553 translation functions, \c tr() and \c trUtf8(), with these
2556 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
2558 This macro is useful if you want to use QObject::tr() or
2559 QObject::trUtf8() in classes that don't inherit from QObject.
2561 Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2562 class definition (before the first \c{public:} or \c{protected:}).
2565 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
2567 The \a context parameter is normally the class name, but it can
2570 \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2575 #include "moc_qcoreapplication.cpp"