Handle application paths larger than MAX_PATH, and fix potential buffer overflow
[qt-netbsd.git] / src / corelib / kernel / qcoreapplication.cpp
blobe2708c3316f587fdda371706fc0fb1848fca8812
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** No Commercial Usage
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the either Technology Preview License Agreement or the
13 ** Beta Release License Agreement.
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at http://www.qtsoftware.com/contact.
38 ** $QT_END_LICENSE$
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>
50 #include <qdatetime.h>
51 #include <qdebug.h>
52 #include <qdir.h>
53 #include <qfile.h>
54 #include <qfileinfo.h>
55 #include <qhash.h>
56 #include <private/qprocess_p.h>
57 #include <qtextcodec.h>
58 #include <qthread.h>
59 #include <qthreadpool.h>
60 #include <qthreadstorage.h>
61 #include <private/qthread_p.h>
62 #include <qlibraryinfo.h>
63 #include <private/qfactoryloader_p.h>
65 #ifdef Q_OS_UNIX
66 # if !defined(QT_NO_GLIB)
67 # include "qeventdispatcher_glib_p.h"
68 # endif
69 # include "qeventdispatcher_unix_p.h"
70 #endif
72 #ifdef Q_OS_WIN
73 # include "qeventdispatcher_win_p.h"
74 #endif
76 #ifdef Q_OS_MAC
77 # include "qcore_mac_p.h"
78 #endif
80 #include <stdlib.h>
82 #ifdef Q_OS_UNIX
83 # include <locale.h>
84 #endif
86 QT_BEGIN_NAMESPACE
88 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
89 extern QString qAppFileName();
90 #endif
92 #if !defined(Q_OS_WIN)
93 #ifdef Q_OS_MAC
94 QString QCoreApplicationPrivate::macMenuBarName()
96 QString bundleName;
97 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
98 if (string)
99 bundleName = QCFString::toQString(static_cast<CFStringRef>(string));
100 return bundleName;
102 #endif
103 QString QCoreApplicationPrivate::appName() const
105 static QString applName;
106 #ifdef Q_OS_MAC
107 applName = macMenuBarName();
108 #endif
109 if (applName.isEmpty() && argv[0]) {
110 char *p = strrchr(argv[0], '/');
111 applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
113 return applName;
115 #endif
117 bool QCoreApplicationPrivate::checkInstance(const char *function)
119 bool b = (QCoreApplication::self != 0);
120 if (!b)
121 qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
122 return b;
125 // Support for introspection
127 QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
129 void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
131 qt_signal_spy_callback_set = callback_set;
134 extern "C" void Q_CORE_EXPORT qt_startup_hook()
138 typedef QList<QtCleanUpFunction> QVFuncList;
139 Q_GLOBAL_STATIC(QVFuncList, postRList)
141 void qAddPostRoutine(QtCleanUpFunction p)
143 QVFuncList *list = postRList();
144 if (!list)
145 return;
146 list->prepend(p);
149 void qRemovePostRoutine(QtCleanUpFunction p)
151 QVFuncList *list = postRList();
152 if (!list)
153 return;
154 list->removeAll(p);
157 void Q_CORE_EXPORT qt_call_post_routines()
159 QVFuncList *list = postRList();
160 if (!list)
161 return;
162 while (!list->isEmpty())
163 (list->takeFirst())();
167 // app starting up if false
168 bool QCoreApplicationPrivate::is_app_running = false;
169 // app closing down if true
170 bool QCoreApplicationPrivate::is_app_closing = false;
171 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
172 Q_CORE_EXPORT bool qt_locale_initialized = false;
175 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
177 QThreadData *currentThreadData = QThreadData::current();
178 return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
182 void qt_set_current_thread_to_main_thread()
184 QCoreApplicationPrivate::theMainThread = QThread::currentThread();
189 QCoreApplication *QCoreApplication::self = 0;
190 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
191 uint QCoreApplicationPrivate::attribs;
193 #ifdef Q_OS_UNIX
194 Qt::HANDLE qt_application_thread_id = 0;
195 #endif
197 struct QCoreApplicationData {
198 QCoreApplicationData() {
199 #ifndef QT_NO_LIBRARY
200 app_libpaths = 0;
201 #endif
203 ~QCoreApplicationData() {
204 #ifndef QT_NO_LIBRARY
205 delete app_libpaths;
206 #endif
208 // cleanup the QAdoptedThread created for the main() thread
209 if (QCoreApplicationPrivate::theMainThread) {
210 QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
211 QCoreApplicationPrivate::theMainThread = 0;
212 data->deref(); // deletes the data and the adopted thread
215 QString orgName, orgDomain, application;
216 QString applicationVersion;
218 #ifndef QT_NO_LIBRARY
219 QStringList *app_libpaths;
220 #endif
224 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
226 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv)
227 : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
228 in_exec(false), aboutToQuitEmitted(false)
230 static const char *const empty = "";
231 if (argc == 0 || argv == 0) {
232 argc = 0;
233 argv = (char **)&empty; // ouch! careful with QCoreApplication::argv()!
235 QCoreApplicationPrivate::is_app_closing = false;
237 #ifdef Q_OS_UNIX
238 qt_application_thread_id = QThread::currentThreadId();
239 #endif
241 // note: this call to QThread::currentThread() may end up setting theMainThread!
242 if (QThread::currentThread() != theMainThread)
243 qWarning("WARNING: QApplication was not created in the main() thread.");
246 QCoreApplicationPrivate::~QCoreApplicationPrivate()
248 #ifndef QT_NO_THREAD
249 void *data = &threadData->tls;
250 QThreadStorageData::finish((void **)data);
251 #endif
253 // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
254 QMutexLocker locker(&threadData->postEventList.mutex);
255 for (int i = 0; i < threadData->postEventList.size(); ++i) {
256 const QPostEvent &pe = threadData->postEventList.at(i);
257 if (pe.event) {
258 --pe.receiver->d_func()->postedEvents;
259 pe.event->posted = false;
260 delete pe.event;
263 threadData->postEventList.clear();
264 threadData->postEventList.recursion = 0;
265 threadData->quitNow = false;
268 void QCoreApplicationPrivate::createEventDispatcher()
270 Q_Q(QCoreApplication);
271 #if defined(Q_OS_UNIX)
272 # if !defined(QT_NO_GLIB)
273 if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
274 eventDispatcher = new QEventDispatcherGlib(q);
275 else
276 # endif
277 eventDispatcher = new QEventDispatcherUNIX(q);
278 #elif defined(Q_OS_WIN)
279 eventDispatcher = new QEventDispatcherWin32(q);
280 #else
281 # error "QEventDispatcher not yet ported to this platform"
282 #endif
285 QThread *QCoreApplicationPrivate::theMainThread = 0;
286 QThread *QCoreApplicationPrivate::mainThread()
288 Q_ASSERT(theMainThread != 0);
289 return theMainThread;
292 #if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
293 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
295 QThread *currentThread = QThread::currentThread();
296 QThread *thr = receiver->thread();
297 Q_ASSERT_X(currentThread == thr || !thr,
298 "QCoreApplication::sendEvent",
299 QString::fromLatin1("Cannot send events to objects owned by a different thread. "
300 "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
301 .arg(QString::number((quintptr) currentThread, 16))
302 .arg(receiver->objectName())
303 .arg(QLatin1String(receiver->metaObject()->className()))
304 .arg(QString::number((quintptr) thr, 16))
305 .toLocal8Bit().data());
306 Q_UNUSED(currentThread);
307 Q_UNUSED(thr);
309 #endif
311 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
313 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
314 QStringList *app_libpaths = coreappdata()->app_libpaths;
315 Q_ASSERT(app_libpaths);
316 QString app_location( QCoreApplication::applicationFilePath() );
317 app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
318 app_location = QDir(app_location).canonicalPath();
319 if (app_location != QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location) && !app_libpaths->contains(app_location))
320 app_libpaths->append(app_location);
321 #endif
324 QString qAppName()
326 if (!QCoreApplicationPrivate::checkInstance("qAppName"))
327 return QString();
328 return QCoreApplication::instance()->d_func()->appName();
332 \class QCoreApplication
333 \brief The QCoreApplication class provides an event loop for console Qt
334 applications.
336 \ingroup application
337 \mainclass
339 This class is used by non-GUI applications to provide their event
340 loop. For non-GUI application that uses Qt, there should be exactly
341 one QCoreApplication object. For GUI applications, see
342 QApplication.
344 QCoreApplication contains the main event loop, where all events
345 from the operating system (e.g., timer and network events) and
346 other sources are processed and dispatched. It also handles the
347 application's initialization and finalization, as well as
348 system-wide and application-wide settings.
350 The command line arguments which QCoreApplication's constructor
351 should be called with are accessible using arguments(). The
352 event loop is started with a call to exec(). Long running
353 operations can call processEvents() to keep the application
354 responsive.
356 Some Qt classes, such as QString, can be used without a
357 QCoreApplication object. However, in general, we recommend that
358 you create a QCoreApplication or a QApplication object in your \c
359 main() function as early as possible. The application will enter
360 the event loop when exec() is called. exit() will not return
361 until the event loop exits, e.g., when quit() is called.
363 An application has an applicationDirPath() and an
364 applicationFilePath(). Translation files can be added or removed
365 using installTranslator() and removeTranslator(). Application
366 strings can be translated using translate(). The QObject::tr()
367 and QObject::trUtf8() functions are implemented in terms of
368 translate().
370 The class provides a quit() slot and an aboutToQuit() signal.
372 Several static convenience functions are also provided. The
373 QCoreApplication object is available from instance(). Events can
374 be sent or posted using sendEvent(), postEvent(), and
375 sendPostedEvents(). Pending events can be removed with
376 removePostedEvents() or flushed with flush(). Library paths (see
377 QLibrary) can be retrieved with libraryPaths() and manipulated by
378 setLibraryPaths(), addLibraryPath(), and removeLibraryPath().
380 On Unix/Linux Qt is configured to use the system local settings by
381 default. This can cause a conflict when using POSIX functions, for
382 instance, when converting between data types such as floats and
383 strings, since the notation may differ between locales. To get
384 around this problem call the POSIX function setlocale(LC_NUMERIC,"C")
385 right after initializing QApplication or QCoreApplication to reset
386 the locale that is used for number formatting to "C"-locale.
388 \sa QApplication, QAbstractEventDispatcher, QEventLoop,
389 {Semaphores Example}, {Wait Conditions Example}
393 \fn static QCoreApplication *QCoreApplication::instance()
395 Returns a pointer to the application's QCoreApplication (or
396 QApplication) instance.
398 If no instance has been allocated, \c null is returned.
401 /*!\internal
403 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
404 : QObject(p, 0)
406 init();
407 // note: it is the subclasses' job to call
408 // QCoreApplicationPrivate::eventDispatcher->startingUp();
412 Flushes the platform specific event queues.
414 If you are doing graphical changes inside a loop that does not
415 return to the event loop on asynchronous window systems like X11
416 or double buffered window systems like Mac OS X, and you want to
417 visualize these changes immediately (e.g. Splash Screens), call
418 this function.
420 \sa sendPostedEvents()
422 void QCoreApplication::flush()
424 if (self && self->d_func()->eventDispatcher)
425 self->d_func()->eventDispatcher->flush();
429 Constructs a Qt kernel application. Kernel applications are
430 applications without a graphical user interface. These type of
431 applications are used at the console or as server processes.
433 The \a argc and \a argv arguments are processed by the application,
434 and made available in a more convenient form by the arguments()
435 function.
437 \warning The data referred to by \a argc and \a argv must stay valid
438 for the entire lifetime of the QCoreApplication object. In addition,
439 \a argc must be greater than zero and \a argv must contain at least
440 one valid character string.
442 QCoreApplication::QCoreApplication(int &argc, char **argv)
443 : QObject(*new QCoreApplicationPrivate(argc, argv))
445 init();
446 QCoreApplicationPrivate::eventDispatcher->startingUp();
449 extern void set_winapp_name();
451 // ### move to QCoreApplicationPrivate constructor?
452 void QCoreApplication::init()
454 Q_D(QCoreApplication);
456 #ifdef Q_OS_UNIX
457 setlocale(LC_ALL, ""); // use correct char set mapping
458 qt_locale_initialized = true;
459 #endif
461 #ifdef Q_WS_WIN
462 // Get the application name/instance if qWinMain() was not invoked
463 set_winapp_name();
464 #endif
466 Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
467 QCoreApplication::self = this;
469 #ifndef QT_NO_THREAD
470 QThread::initialize();
471 #endif
473 // use the event dispatcher created by the app programmer (if any)
474 if (!QCoreApplicationPrivate::eventDispatcher)
475 QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
476 // otherwise we create one
477 if (!QCoreApplicationPrivate::eventDispatcher)
478 d->createEventDispatcher();
479 Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
481 if (!QCoreApplicationPrivate::eventDispatcher->parent())
482 QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
484 d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
486 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
487 if (!coreappdata()->app_libpaths) {
488 // make sure that library paths is initialized
489 libraryPaths();
490 } else {
491 d->appendApplicationPathToLibraryPaths();
493 #endif
495 #if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
496 // Make sure the process manager thread object is created in the main
497 // thread.
498 QProcessPrivate::initializeProcessManager();
499 #endif
501 #ifdef QT_EVAL
502 extern void qt_core_eval_init(uint);
503 qt_core_eval_init(d->application_type);
504 #endif
506 qt_startup_hook();
510 Destroys the QCoreApplication object.
512 QCoreApplication::~QCoreApplication()
514 qt_call_post_routines();
516 self = 0;
517 QCoreApplicationPrivate::is_app_closing = true;
518 QCoreApplicationPrivate::is_app_running = false;
520 #if !defined(QT_NO_THREAD)
521 #if !defined(QT_NO_CONCURRENT)
522 // Synchronize and stop the global thread pool threads.
523 QThreadPool::globalInstance()->waitForDone();
524 #endif
525 QThread::cleanup();
526 #endif
528 d_func()->threadData->eventDispatcher = 0;
529 if (QCoreApplicationPrivate::eventDispatcher)
530 QCoreApplicationPrivate::eventDispatcher->closingDown();
531 QCoreApplicationPrivate::eventDispatcher = 0;
533 #ifndef QT_NO_LIBRARY
534 delete coreappdata()->app_libpaths;
535 coreappdata()->app_libpaths = 0;
536 #endif
541 Sets the attribute \a attribute if \a on is true;
542 otherwise clears the attribute.
544 One of the attributes that can be set with this method is
545 Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
546 windows immediately. Normally, resources for widgets are allocated
547 on demand to improve efficiency and minimize resource usage.
548 Therefore, if it is important to minimize resource consumption, do
549 not set this attribute.
551 \sa testAttribute()
553 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
555 if (on)
556 QCoreApplicationPrivate::attribs |= 1 << attribute;
557 else
558 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
559 #ifdef Q_OS_MAC
560 // Turn on the no native menubar here, since we used to
561 // do this implicitly. We DO NOT flip it off if someone sets
562 // it to false.
563 // Ideally, we'd have magic that would be something along the lines of
564 // "follow MacPluginApplication" unless explicitly set.
565 // Considering this attribute isn't only at the beginning
566 // it's unlikely it will ever be a problem, but I want
567 // to have the behavior documented here.
568 if (attribute == Qt::AA_MacPluginApplication && on
569 && !testAttribute(Qt::AA_DontUseNativeMenuBar)) {
570 setAttribute(Qt::AA_DontUseNativeMenuBar, true);
572 #endif
576 Returns true if attribute \a attribute is set;
577 otherwise returns false.
579 \sa setAttribute()
581 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
583 return QCoreApplicationPrivate::testAttribute(attribute);
588 \internal
590 This function is here to make it possible for Qt extensions to
591 hook into event notification without subclassing QApplication
593 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
595 // Make it possible for Qt Jambi and QSA to hook into events even
596 // though QApplication is subclassed...
597 bool result = false;
598 void *cbdata[] = { receiver, event, &result };
599 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
600 return result;
603 // Qt enforces the rule that events can only be sent to objects in
604 // the current thread, so receiver->d_func()->threadData is
605 // equivalent to QThreadData::current(), just without the function
606 // call overhead.
607 QObjectPrivate *d = receiver->d_func();
608 QThreadData *threadData = d->threadData;
609 ++threadData->loopLevel;
611 #ifdef QT_JAMBI_BUILD
612 int deleteWatch = 0;
613 int *oldDeleteWatch = QObjectPrivate::setDeleteWatch(d, &deleteWatch);
615 bool inEvent = d->inEventHandler;
616 d->inEventHandler = true;
617 #endif
619 #if defined(QT_NO_EXCEPTIONS)
620 bool returnValue = notify(receiver, event);
621 #else
622 bool returnValue;
623 try {
624 returnValue = notify(receiver, event);
625 } catch(...) {
626 --threadData->loopLevel;
627 throw;
629 #endif
631 #ifdef QT_JAMBI_BUILD
632 // Restore the previous state if the object was not deleted..
633 if (!deleteWatch) {
634 d->inEventHandler = inEvent;
636 QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
637 #endif
638 --threadData->loopLevel;
639 return returnValue;
644 Sends \a event to \a receiver: \a {receiver}->event(\a event).
645 Returns the value that is returned from the receiver's event
646 handler. Note that this function is called for all events sent to
647 any object in any thread.
649 For certain types of events (e.g. mouse and key events),
650 the event will be propagated to the receiver's parent and so on up to
651 the top-level object if the receiver is not interested in the event
652 (i.e., it returns false).
654 There are five different ways that events can be processed;
655 reimplementing this virtual function is just one of them. All five
656 approaches are listed below:
657 \list 1
658 \i Reimplementing paintEvent(), mousePressEvent() and so
659 on. This is the commonest, easiest and least powerful way.
661 \i Reimplementing this function. This is very powerful, providing
662 complete control; but only one subclass can be active at a time.
664 \i Installing an event filter on QCoreApplication::instance(). Such
665 an event filter is able to process all events for all widgets, so
666 it's just as powerful as reimplementing notify(); furthermore, it's
667 possible to have more than one application-global event filter.
668 Global event filters even see mouse events for
669 \l{QWidget::isEnabled()}{disabled widgets}. Note that application
670 event filters are only called for objects that live in the main
671 thread.
673 \i Reimplementing QObject::event() (as QWidget does). If you do
674 this you get Tab key presses, and you get to see the events before
675 any widget-specific event filters.
677 \i Installing an event filter on the object. Such an event filter gets all
678 the events, including Tab and Shift+Tab key press events, as long as they
679 do not change the focus widget.
680 \endlist
682 \sa QObject::event(), installEventFilter()
685 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
687 Q_D(QCoreApplication);
688 // no events are delivered after ~QCoreApplication() has started
689 if (QCoreApplicationPrivate::is_app_closing)
690 return true;
692 if (receiver == 0) { // serious error
693 qWarning("QCoreApplication::notify: Unexpected null receiver");
694 return true;
697 #ifndef QT_NO_DEBUG
698 d->checkReceiverThread(receiver);
699 #endif
701 #ifdef QT3_SUPPORT
702 if (event->type() == QEvent::ChildRemoved && !receiver->d_func()->pendingChildInsertedEvents.isEmpty())
703 receiver->d_func()->removePendingChildInsertedEvents(static_cast<QChildEvent *>(event)->child());
704 #endif // QT3_SUPPORT
706 return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
709 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
711 if (receiver->d_func()->threadData == this->threadData) {
712 // application event filters are only called for objects in the GUI thread
713 for (int i = 0; i < eventFilters.size(); ++i) {
714 register QObject *obj = eventFilters.at(i);
715 if (!obj)
716 continue;
717 if (obj->d_func()->threadData != threadData) {
718 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
719 continue;
721 if (obj->eventFilter(receiver, event))
722 return true;
725 return false;
728 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
730 Q_Q(QCoreApplication);
731 if (receiver != q) {
732 for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
733 register QObject *obj = receiver->d_func()->eventFilters.at(i);
734 if (!obj)
735 continue;
736 if (obj->d_func()->threadData != receiver->d_func()->threadData) {
737 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
738 continue;
740 if (obj->eventFilter(receiver, event))
741 return true;
744 return false;
747 /*!\internal
749 Helper function called by notify()
751 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
753 // send to all application event filters
754 if (sendThroughApplicationEventFilters(receiver, event))
755 return true;
756 // send to all receiver event filters
757 if (sendThroughObjectEventFilters(receiver, event))
758 return true;
759 // deliver the event
760 return receiver->event(event);
764 Returns true if an application object has not been created yet;
765 otherwise returns false.
767 \sa closingDown()
770 bool QCoreApplication::startingUp()
772 return !QCoreApplicationPrivate::is_app_running;
776 Returns true if the application objects are being destroyed;
777 otherwise returns false.
779 \sa startingUp()
782 bool QCoreApplication::closingDown()
784 return QCoreApplicationPrivate::is_app_closing;
789 Processes all pending events for the calling thread according to
790 the specified \a flags until there are no more events to process.
792 You can call this function occasionally when your program is busy
793 performing a long operation (e.g. copying a file).
795 In event you are running a local loop which calls this function
796 continuously, without an event loop, the
797 \l{QEvent::DeferredDelete}{DeferredDelete} events will
798 not be processed. This can affect the behaviour of widgets,
799 e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
800 events to function properly. An alternative would be to call
801 \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
802 within that local loop.
804 Calling this function processes events only for the calling thread.
806 \threadsafe
808 \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
810 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
812 QThreadData *data = QThreadData::current();
813 if (!data->eventDispatcher)
814 return;
815 if (flags & QEventLoop::DeferredDeletion)
816 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
817 data->eventDispatcher->processEvents(flags);
821 \overload processEvents()
823 Processes pending events for the calling thread for \a maxtime
824 milliseconds or until there are no more events to process,
825 whichever is shorter.
827 You can call this function occasionally when you program is busy
828 doing a long operation (e.g. copying a file).
830 Calling this function processes events only for the calling thread.
832 \threadsafe
834 \sa exec(), QTimer, QEventLoop::processEvents()
836 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
838 QThreadData *data = QThreadData::current();
839 if (!data->eventDispatcher)
840 return;
841 QTime start;
842 start.start();
843 if (flags & QEventLoop::DeferredDeletion)
844 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
845 while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
846 if (start.elapsed() > maxtime)
847 break;
848 if (flags & QEventLoop::DeferredDeletion)
849 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
853 /*****************************************************************************
854 Main event loop wrappers
855 *****************************************************************************/
858 Enters the main event loop and waits until exit() is called.
859 Returns the value that was set to exit() (which is 0 if exit() is
860 called via quit()).
862 It is necessary to call this function to start event handling. The
863 main event loop receives events from the window system and
864 dispatches these to the application widgets.
866 To make your application perform idle processing (i.e. executing a
867 special function whenever there are no pending events), use a
868 QTimer with 0 timeout. More advanced idle processing schemes can
869 be achieved using processEvents().
871 We recommend that you connect clean-up code to the
872 \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
873 your application's \c{main()} function because on some platforms the
874 QCoreApplication::exec() call may not return. For example, on Windows
875 when the user logs off, the system terminates the process after Qt
876 closes all top-level windows. Hence, there is no guarantee that the
877 application will have time to exit its event loop and execute code at
878 the end of the \c{main()} function after the QCoreApplication::exec()
879 call.
881 \sa quit(), exit(), processEvents(), QApplication::exec()
883 int QCoreApplication::exec()
885 if (!QCoreApplicationPrivate::checkInstance("exec"))
886 return -1;
888 QThreadData *threadData = self->d_func()->threadData;
889 if (threadData != QThreadData::current()) {
890 qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
891 return -1;
893 if (!threadData->eventLoops.isEmpty()) {
894 qWarning("QCoreApplication::exec: The event loop is already running");
895 return -1;
898 threadData->quitNow = false;
899 QEventLoop eventLoop;
900 self->d_func()->in_exec = true;
901 self->d_func()->aboutToQuitEmitted = false;
902 int returnCode = eventLoop.exec();
903 threadData->quitNow = false;
904 if (self) {
905 self->d_func()->in_exec = false;
906 if (!self->d_func()->aboutToQuitEmitted)
907 emit self->aboutToQuit();
908 self->d_func()->aboutToQuitEmitted = true;
909 sendPostedEvents(0, QEvent::DeferredDelete);
912 return returnCode;
916 Tells the application to exit with a return code.
918 After this function has been called, the application leaves the
919 main event loop and returns from the call to exec(). The exec()
920 function returns \a returnCode. If the event loop is not running,
921 this function does nothing.
923 By convention, a \a returnCode of 0 means success, and any non-zero
924 value indicates an error.
926 Note that unlike the C library function of the same name, this
927 function \e does return to the caller -- it is event processing that
928 stops.
930 \sa quit(), exec()
932 void QCoreApplication::exit(int returnCode)
934 if (!self)
935 return;
936 QThreadData *data = self->d_func()->threadData;
937 data->quitNow = true;
938 for (int i = 0; i < data->eventLoops.size(); ++i) {
939 QEventLoop *eventLoop = data->eventLoops.at(i);
940 eventLoop->exit(returnCode);
944 /*****************************************************************************
945 QCoreApplication management of posted events
946 *****************************************************************************/
949 \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
951 Sends event \a event directly to receiver \a receiver, using the
952 notify() function. Returns the value that was returned from the
953 event handler.
955 The event is \e not deleted when the event has been sent. The normal
956 approach is to create the event on the stack, for example:
958 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
960 \sa postEvent(), notify()
964 Adds the event \a event, with the object \a receiver as the
965 receiver of the event, to an event queue and returns immediately.
967 The event must be allocated on the heap since the post event queue
968 will take ownership of the event and delete it once it has been
969 posted. It is \e {not safe} to modify or delete the event after
970 it has been posted.
972 When control returns to the main event loop, all events that are
973 stored in the queue will be sent using the notify() function.
975 Events are processed in the order posted. For more control over
976 the processing order, use the postEvent() overload below, which
977 takes a priority argument. This function posts all event with a
978 Qt::NormalEventPriority.
980 \threadsafe
982 \sa sendEvent(), notify(), sendPostedEvents()
985 void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
987 postEvent(receiver, event, Qt::NormalEventPriority);
992 \overload postEvent()
993 \since 4.3
995 Adds the event \a event, with the object \a receiver as the
996 receiver of the event, to an event queue and returns immediately.
998 The event must be allocated on the heap since the post event queue
999 will take ownership of the event and delete it once it has been
1000 posted. It is \e {not safe} to modify or delete the event after
1001 it has been posted.
1003 When control returns to the main event loop, all events that are
1004 stored in the queue will be sent using the notify() function.
1006 Events are sorted in descending \a priority order, i.e. events
1007 with a high \a priority are queued before events with a lower \a
1008 priority. The \a priority can be any integer value, i.e. between
1009 INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1010 details. Events with equal \a priority will be processed in the
1011 order posted.
1013 \threadsafe
1015 \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1017 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1019 if (receiver == 0) {
1020 qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1021 delete event;
1022 return;
1025 QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1026 QThreadData *data = *pdata;
1027 if (!data) {
1028 // posting during destruction? just delete the event to prevent a leak
1029 delete event;
1030 return;
1033 // lock the post event mutex
1034 data->postEventList.mutex.lock();
1036 // if object has moved to another thread, follow it
1037 while (data != *pdata) {
1038 data->postEventList.mutex.unlock();
1040 data = *pdata;
1041 if (!data) {
1042 // posting during destruction? just delete the event to prevent a leak
1043 delete event;
1044 return;
1047 data->postEventList.mutex.lock();
1050 // if this is one of the compressible events, do compression
1051 if (receiver->d_func()->postedEvents
1052 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1053 data->postEventList.mutex.unlock();
1054 return;
1057 event->posted = true;
1058 ++receiver->d_func()->postedEvents;
1059 if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1060 // remember the current running eventloop for DeferredDelete
1061 // events posted in the receiver's thread
1062 event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel));
1065 if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) {
1066 // optimization: we can simply append if the last event in
1067 // the queue has higher or equal priority
1068 data->postEventList.append(QPostEvent(receiver, event, priority));
1069 } else {
1070 // insert event in descending priority order, using upper
1071 // bound for a given priority (to ensure proper ordering
1072 // of events with the same priority)
1073 QPostEventList::iterator begin = data->postEventList.begin()
1074 + data->postEventList.insertionOffset,
1075 end = data->postEventList.end();
1076 QPostEventList::iterator at = qUpperBound(begin, end, priority);
1077 data->postEventList.insert(at, QPostEvent(receiver, event, priority));
1079 data->canWait = false;
1080 data->postEventList.mutex.unlock();
1082 if (data->eventDispatcher)
1083 data->eventDispatcher->wakeUp();
1087 \internal
1088 Returns true if \a event was compressed away (possibly deleted) and should not be added to the list.
1090 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1092 #ifdef Q_WS_WIN
1093 Q_ASSERT(event);
1094 Q_ASSERT(receiver);
1095 Q_ASSERT(postedEvents);
1097 // compress posted timers to this object.
1098 if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1099 int timerId = ((QTimerEvent *) event)->timerId();
1100 for (int i=0; i<postedEvents->size(); ++i) {
1101 const QPostEvent &e = postedEvents->at(i);
1102 if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1103 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1104 delete event;
1105 return true;
1108 } else
1109 #endif
1110 if ((event->type() == QEvent::DeferredDelete
1111 || event->type() == QEvent::Quit)
1112 && receiver->d_func()->postedEvents > 0) {
1113 for (int i = 0; i < postedEvents->size(); ++i) {
1114 const QPostEvent &cur = postedEvents->at(i);
1115 if (cur.receiver != receiver
1116 || cur.event == 0
1117 || cur.event->type() != event->type())
1118 continue;
1119 // found an event for this receiver
1120 delete event;
1121 return true;
1124 return false;
1128 \fn void QCoreApplication::sendPostedEvents()
1129 \overload sendPostedEvents()
1131 Dispatches all posted events, i.e. empties the event queue.
1135 Immediately dispatches all events which have been previously queued
1136 with QCoreApplication::postEvent() and which are for the object \a receiver
1137 and have the event type \a event_type.
1139 Events from the window system are \e not dispatched by this
1140 function, but by processEvents().
1142 If \a receiver is null, the events of \a event_type are sent for all
1143 objects. If \a event_type is 0, all the events are sent for \a receiver.
1145 \note This method must be called from the same thread as its QObject parameter, \a receiver.
1147 \sa flush(), postEvent()
1150 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1152 QThreadData *data = QThreadData::current();
1154 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1157 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1158 QThreadData *data)
1160 if (event_type == -1) {
1161 // we were called by an obsolete event dispatcher.
1162 event_type = 0;
1165 if (receiver && receiver->d_func()->threadData != data) {
1166 qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1167 "posted events for objects in another thread");
1168 return;
1171 ++data->postEventList.recursion;
1173 #ifdef QT3_SUPPORT
1174 if (event_type == QEvent::ChildInserted) {
1175 if (receiver) {
1176 // optimize sendPostedEvents(w, QEvent::ChildInserted) calls away
1177 receiver->d_func()->sendPendingChildInsertedEvents();
1178 --data->postEventList.recursion;
1179 return;
1182 // ChildInserted events are sent in response to *Request
1183 event_type = QEvent::ChildInsertedRequest;
1185 #endif
1187 QMutexLocker locker(&data->postEventList.mutex);
1189 // by default, we assume that the event dispatcher can go to sleep after
1190 // processing all events. if any new events are posted while we send
1191 // events, canWait will be set to false.
1192 data->canWait = (data->postEventList.size() == 0);
1194 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1195 --data->postEventList.recursion;
1196 return;
1199 data->canWait = true;
1201 // okay. here is the tricky loop. be careful about optimizing
1202 // this, it looks the way it does for good reasons.
1203 int startOffset = data->postEventList.startOffset;
1204 int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1205 data->postEventList.insertionOffset = data->postEventList.size();
1207 while (i < data->postEventList.size()) {
1208 // avoid live-lock
1209 if (i >= data->postEventList.insertionOffset)
1210 break;
1212 const QPostEvent &pe = data->postEventList.at(i);
1213 ++i;
1215 if (!pe.event)
1216 continue;
1217 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1218 data->canWait = false;
1219 continue;
1222 if (pe.event->type() == QEvent::DeferredDelete) {
1223 // DeferredDelete events are only sent when we are explicitly asked to
1224 // (s.a. QEvent::DeferredDelete), and then only if the event loop that
1225 // posted the event has returned.
1226 const bool allowDeferredDelete =
1227 (quintptr(pe.event->d) > unsigned(data->loopLevel)
1228 || (!quintptr(pe.event->d) && data->loopLevel > 0)
1229 || (event_type == QEvent::DeferredDelete
1230 && quintptr(pe.event->d) == unsigned(data->loopLevel)));
1231 if (!allowDeferredDelete) {
1232 // cannot send deferred delete
1233 if (!event_type && !receiver) {
1234 // don't lose the event
1235 data->postEventList.append(pe);
1236 const_cast<QPostEvent &>(pe).event = 0;
1238 continue;
1242 // first, we diddle the event so that we can deliver
1243 // it, and that no one will try to touch it later.
1244 pe.event->posted = false;
1245 QEvent * e = pe.event;
1246 QObject * r = pe.receiver;
1248 --r->d_func()->postedEvents;
1249 Q_ASSERT(r->d_func()->postedEvents >= 0);
1251 // next, update the data structure so that we're ready
1252 // for the next event.
1253 const_cast<QPostEvent &>(pe).event = 0;
1255 locker.unlock();
1256 // after all that work, it's time to deliver the event.
1257 #ifdef QT_NO_EXCEPTIONS
1258 QCoreApplication::sendEvent(r, e);
1259 #else
1260 try {
1261 QCoreApplication::sendEvent(r, e);
1262 } catch (...) {
1263 delete e;
1264 locker.relock();
1266 // since we were interrupted, we need another pass to make sure we clean everything up
1267 data->canWait = false;
1269 // uglehack: copied from below
1270 --data->postEventList.recursion;
1271 if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1272 data->eventDispatcher->wakeUp();
1273 throw; // rethrow
1275 #endif
1277 delete e;
1278 locker.relock();
1280 // careful when adding anything below this point - the
1281 // sendEvent() call might invalidate any invariants this
1282 // function depends on.
1285 --data->postEventList.recursion;
1286 if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1287 data->eventDispatcher->wakeUp();
1289 // clear the global list, i.e. remove everything that was
1290 // delivered.
1291 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1292 const QPostEventList::iterator it = data->postEventList.begin();
1293 data->postEventList.erase(it, it + data->postEventList.startOffset);
1294 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1295 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1296 data->postEventList.startOffset = 0;
1301 Removes all events posted using postEvent() for \a receiver.
1303 The events are \e not dispatched, instead they are removed from the
1304 queue. You should never need to call this function. If you do call it,
1305 be aware that killing events may cause \a receiver to break one or
1306 more invariants.
1308 \threadsafe
1311 void QCoreApplication::removePostedEvents(QObject *receiver)
1313 removePostedEvents(receiver, 0);
1317 \overload removePostedEvents()
1318 \since 4.3
1320 Removes all events of the given \a eventType that were posted
1321 using postEvent() for \a receiver.
1323 The events are \e not dispatched, instead they are removed from
1324 the queue. You should never need to call this function. If you do
1325 call it, be aware that killing events may cause \a receiver to
1326 break one or more invariants.
1328 If \a receiver is null, the events of \a eventType are removed for
1329 all objects. If \a eventType is 0, all the events are removed for
1330 \a receiver.
1332 \threadsafe
1335 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1337 #ifdef QT3_SUPPORT
1338 if (eventType == QEvent::ChildInserted)
1339 eventType = QEvent::ChildInsertedRequest;
1340 #endif
1342 QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1343 QMutexLocker locker(&data->postEventList.mutex);
1345 // the QObject destructor calls this function directly. this can
1346 // happen while the event loop is in the middle of posting events,
1347 // and when we get here, we may not have any more posted events
1348 // for this object.
1349 if (receiver && !receiver->d_func()->postedEvents)
1350 return;
1351 QCoreApplicationPrivate::removePostedEvents_unlocked(receiver, eventType, data);
1354 void QCoreApplicationPrivate::removePostedEvents_unlocked(QObject *receiver,
1355 int eventType,
1356 QThreadData *data)
1358 int n = data->postEventList.size();
1359 int j = 0;
1361 for (int i = 0; i < n; ++i) {
1362 const QPostEvent &pe = data->postEventList.at(i);
1364 if ((!receiver || pe.receiver == receiver)
1365 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1366 --pe.receiver->d_func()->postedEvents;
1367 #ifdef QT3_SUPPORT
1368 if (pe.event->type() == QEvent::ChildInsertedRequest)
1369 pe.receiver->d_func()->removePendingChildInsertedEvents(0);
1370 #endif
1371 pe.event->posted = false;
1372 delete pe.event;
1373 const_cast<QPostEvent &>(pe).event = 0;
1374 } else if (!data->postEventList.recursion) {
1375 if (i != j)
1376 data->postEventList.swap(i, j);
1377 ++j;
1381 #ifdef QT_DEBUG
1382 if (receiver && eventType == 0) {
1383 Q_ASSERT(!receiver->d_func()->postedEvents);
1385 #endif
1387 if (!data->postEventList.recursion) {
1388 // truncate list
1389 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1395 Removes \a event from the queue of posted events, and emits a
1396 warning message if appropriate.
1398 \warning This function can be \e really slow. Avoid using it, if
1399 possible.
1401 \threadsafe
1404 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1406 if (!event || !event->posted)
1407 return;
1409 QThreadData *data = QThreadData::current();
1411 QMutexLocker locker(&data->postEventList.mutex);
1413 if (data->postEventList.size() == 0) {
1414 #if defined(QT_DEBUG)
1415 qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1416 (void*)event, event->type());
1417 return;
1418 #endif
1421 for (int i = 0; i < data->postEventList.size(); ++i) {
1422 const QPostEvent & pe = data->postEventList.at(i);
1423 if (pe.event == event) {
1424 #ifndef QT_NO_DEBUG
1425 qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1426 event->type(),
1427 pe.receiver->metaObject()->className(),
1428 pe.receiver->objectName().toLocal8Bit().data());
1429 #endif
1430 --pe.receiver->d_func()->postedEvents;
1431 pe.event->posted = false;
1432 delete pe.event;
1433 const_cast<QPostEvent &>(pe).event = 0;
1434 return;
1439 /*!\reimp
1442 bool QCoreApplication::event(QEvent *e)
1444 if (e->type() == QEvent::Quit) {
1445 quit();
1446 return true;
1448 return QObject::event(e);
1451 /*! \enum QCoreApplication::Encoding
1453 This enum type defines the 8-bit encoding of character string
1454 arguments to translate():
1456 \value CodecForTr The encoding specified by
1457 QTextCodec::codecForTr() (Latin-1 if none has
1458 been set).
1459 \value UnicodeUTF8 UTF-8.
1460 \value DefaultCodec (Obsolete) Use CodecForTr instead.
1462 \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
1466 Tells the application to exit with return code 0 (success).
1467 Equivalent to calling QCoreApplication::exit(0).
1469 It's common to connect the QApplication::lastWindowClosed() signal
1470 to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1471 signals in QAction, QMenu, or QMenuBar to it.
1473 Example:
1475 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
1477 \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
1480 void QCoreApplication::quit()
1482 exit(0);
1486 \fn void QCoreApplication::aboutToQuit()
1488 This signal is emitted when the application is about to quit the
1489 main event loop, e.g. when the event loop level drops to zero.
1490 This may happen either after a call to quit() from inside the
1491 application or when the users shuts down the entire desktop session.
1493 The signal is particularly useful if your application has to do some
1494 last-second cleanup. Note that no user interaction is possible in
1495 this state.
1497 \sa quit()
1500 #ifndef QT_NO_TRANSLATION
1502 Adds the translation file \a translationFile to the list of
1503 translation files to be used for translations.
1505 Multiple translation files can be installed. Translations are
1506 searched for in the reverse order in which they were installed,
1507 so the most recently installed translation file is searched first
1508 and the first translation file installed is searched last.
1509 The search stops as soon as a translation containing a matching
1510 string is found.
1512 Installing or removing a QTranslator, or changing an installed QTranslator
1513 generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1514 QCoreApplication instance. A QApplication instance will propagate the event
1515 to all toplevel windows, where a reimplementation of changeEvent can
1516 re-translate the user interface by passing user-visible strings via the
1517 tr() function to the respective property setters. User-interface classes
1518 generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
1519 called.
1521 \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
1524 void QCoreApplication::installTranslator(QTranslator *translationFile)
1526 if (!translationFile)
1527 return;
1529 if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1530 return;
1531 QCoreApplicationPrivate *d = self->d_func();
1532 d->translators.prepend(translationFile);
1534 #ifndef QT_NO_TRANSLATION_BUILDER
1535 if (translationFile->isEmpty())
1536 return;
1537 #endif
1539 QEvent ev(QEvent::LanguageChange);
1540 QCoreApplication::sendEvent(self, &ev);
1544 Removes the translation file \a translationFile from the list of
1545 translation files used by this application. (It does not delete the
1546 translation file from the file system.)
1548 \sa installTranslator() translate(), QObject::tr()
1551 void QCoreApplication::removeTranslator(QTranslator *translationFile)
1553 if (!translationFile)
1554 return;
1555 if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1556 return;
1557 QCoreApplicationPrivate *d = self->d_func();
1558 if (d->translators.removeAll(translationFile) && !self->closingDown()) {
1559 QEvent ev(QEvent::LanguageChange);
1560 QCoreApplication::sendEvent(self, &ev);
1565 \overload translate()
1567 QString QCoreApplication::translate(const char *context, const char *sourceText,
1568 const char *disambiguation, Encoding encoding)
1570 return translate(context, sourceText, disambiguation, encoding, -1);
1573 static void replacePercentN(QString *result, int n)
1575 if (n >= 0) {
1576 int percentPos = 0;
1577 int len = 0;
1578 while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1579 len = 1;
1580 QString fmt;
1581 if (result->at(percentPos + len) == QLatin1Char('L')) {
1582 ++len;
1583 fmt = QLatin1String("%L1");
1584 } else {
1585 fmt = QLatin1String("%1");
1587 if (result->at(percentPos + len) == QLatin1Char('n')) {
1588 fmt = fmt.arg(n);
1589 ++len;
1590 result->replace(percentPos, len, fmt);
1591 len = fmt.length();
1598 \reentrant
1599 \since 4.5
1601 Returns the translation text for \a sourceText, by querying the
1602 installed translation files. The translation files are searched
1603 from the most recently installed file back to the first
1604 installed file.
1606 QObject::tr() and QObject::trUtf8() provide this functionality
1607 more conveniently.
1609 \a context is typically a class name (e.g., "MyDialog") and \a
1610 sourceText is either English text or a short identifying text.
1612 \a disambiguation is an identifying string, for when the same \a
1613 sourceText is used in different roles within the same context. By
1614 default, it is null.
1616 See the \l QTranslator and \l QObject::tr() documentation for
1617 more information about contexts, disambiguations and comments.
1619 \a encoding indicates the 8-bit encoding of character strings.
1621 \a n is used in conjunction with \c %n to support plural forms.
1622 See QObject::tr() for details.
1624 If none of the translation files contain a translation for \a
1625 sourceText in \a context, this function returns a QString
1626 equivalent of \a sourceText. The encoding of \a sourceText is
1627 specified by \e encoding; it defaults to CodecForTr.
1629 This function is not virtual. You can use alternative translation
1630 techniques by subclassing \l QTranslator.
1632 \warning This method is reentrant only if all translators are
1633 installed \e before calling this method. Installing or removing
1634 translators while performing translations is not supported. Doing
1635 so will most likely result in crashes or other undesirable
1636 behavior.
1638 \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
1642 QString QCoreApplication::translate(const char *context, const char *sourceText,
1643 const char *disambiguation, Encoding encoding, int n)
1645 QString result;
1647 if (!sourceText)
1648 return result;
1650 if (self && !self->d_func()->translators.isEmpty()) {
1651 QList<QTranslator*>::ConstIterator it;
1652 QTranslator *translationFile;
1653 for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
1654 translationFile = *it;
1655 result = translationFile->translate(context, sourceText, disambiguation, n);
1656 if (!result.isEmpty())
1657 break;
1661 if (result.isEmpty()) {
1662 #ifdef QT_NO_TEXTCODEC
1663 Q_UNUSED(encoding)
1664 #else
1665 if (encoding == UnicodeUTF8)
1666 result = QString::fromUtf8(sourceText);
1667 else if (QTextCodec::codecForTr() != 0)
1668 result = QTextCodec::codecForTr()->toUnicode(sourceText);
1669 else
1670 #endif
1671 result = QString::fromLatin1(sourceText);
1674 replacePercentN(&result, n);
1675 return result;
1678 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
1680 return QCoreApplication::self
1681 && QCoreApplication::self->d_func()->translators.contains(translator);
1684 #endif //QT_NO_TRANSLATE
1687 Returns the directory that contains the application executable.
1689 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1690 directory, and you run the \c{regexp} example, this function will
1691 return "C:/Trolltech/Qt/examples/tools/regexp".
1693 On Mac OS X this will point to the directory actually containing the
1694 executable, which may be inside of an application bundle (if the
1695 application is bundled).
1697 \warning On Linux, this function will try to get the path from the
1698 \c {/proc} file system. If that fails, it assumes that \c
1699 {argv[0]} contains the absolute file name of the executable. The
1700 function also assumes that the current directory has not been
1701 changed by the application.
1703 \sa applicationFilePath()
1705 QString QCoreApplication::applicationDirPath()
1707 if (!self) {
1708 qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
1709 return QString();
1712 QCoreApplicationPrivate *d = self->d_func();
1713 if (d->cachedApplicationDirPath.isNull())
1714 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
1715 return d->cachedApplicationDirPath;
1719 Returns the file path of the application executable.
1721 For example, if you have installed Qt in the \c{/usr/local/qt}
1722 directory, and you run the \c{regexp} example, this function will
1723 return "/usr/local/qt/examples/tools/regexp/regexp".
1725 \warning On Linux, this function will try to get the path from the
1726 \c {/proc} file system. If that fails, it assumes that \c
1727 {argv[0]} contains the absolute file name of the executable. The
1728 function also assumes that the current directory has not been
1729 changed by the application.
1731 \sa applicationDirPath()
1733 QString QCoreApplication::applicationFilePath()
1735 if (!self) {
1736 qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
1737 return QString();
1740 QCoreApplicationPrivate *d = self->d_func();
1741 if (!d->cachedApplicationFilePath.isNull())
1742 return d->cachedApplicationFilePath;
1744 #if defined(Q_WS_WIN)
1745 d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
1746 return d->cachedApplicationFilePath;
1747 #elif defined(Q_WS_MAC)
1748 QString qAppFileName_str = qAppFileName();
1749 if(!qAppFileName_str.isEmpty()) {
1750 QFileInfo fi(qAppFileName_str);
1751 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
1752 return d->cachedApplicationFilePath;
1754 #endif
1755 #if defined( Q_OS_UNIX )
1756 # ifdef Q_OS_LINUX
1757 // Try looking for a /proc/<pid>/exe symlink first which points to
1758 // the absolute path of the executable
1759 QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
1760 if (pfi.exists() && pfi.isSymLink()) {
1761 d->cachedApplicationFilePath = pfi.canonicalFilePath();
1762 return d->cachedApplicationFilePath;
1764 # endif
1766 QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
1767 QString absPath;
1769 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
1771 If argv0 starts with a slash, it is already an absolute
1772 file path.
1774 absPath = argv0;
1775 } else if (argv0.contains(QLatin1Char('/'))) {
1777 If argv0 contains one or more slashes, it is a file path
1778 relative to the current directory.
1780 absPath = QDir::current().absoluteFilePath(argv0);
1781 } else {
1783 Otherwise, the file path has to be determined using the
1784 PATH environment variable.
1786 QByteArray pEnv = qgetenv("PATH");
1787 QDir currentDir = QDir::current();
1788 QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
1789 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
1790 if ((*p).isEmpty())
1791 continue;
1792 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
1793 QFileInfo candidate_fi(candidate);
1794 if (candidate_fi.exists() && !candidate_fi.isDir()) {
1795 absPath = candidate;
1796 break;
1801 absPath = QDir::cleanPath(absPath);
1803 QFileInfo fi(absPath);
1804 d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
1805 return d->cachedApplicationFilePath;
1806 #endif
1810 \since 4.4
1812 Returns the current process ID for the application.
1814 qint64 QCoreApplication::applicationPid()
1816 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
1817 return GetCurrentProcessId();
1818 #else
1819 // UNIX
1820 return getpid();
1821 #endif
1825 \obsolete
1827 Use arguments().size() instead.
1829 int QCoreApplication::argc()
1831 if (!self) {
1832 qWarning("QCoreApplication::argc: Please instantiate the QApplication object first");
1833 return 0;
1835 return self->d_func()->argc;
1840 \obsolete
1842 Use arguments() instead.
1844 char **QCoreApplication::argv()
1846 if (!self) {
1847 qWarning("QCoreApplication::argv: Please instantiate the QApplication object first");
1848 return 0;
1850 return self->d_func()->argv;
1854 \since 4.1
1856 Returns the list of command-line arguments.
1858 Usually arguments().at(0) is the program name, arguments().at(1)
1859 is the first argument, and arguments().last() is the last
1860 argument. See the note below about Windows.
1862 Calling this function is slow - you should store the result in a variable
1863 when parsing the command line.
1865 \warning On Unix, this list is built from the argc and argv parameters passed
1866 to the constructor in the main() function. The string-data in argv is
1867 interpreted using QString::fromLocal8Bit(); hence it is not possible to
1868 pass i.e. Japanese command line arguments on a system that runs in a latin1
1869 locale. Most modern Unix systems do not have this limitation, as they are
1870 Unicode based.
1872 On NT-based Windows, this limitation does not apply either.
1873 On Windows, the arguments() are not built from the contents of argv/argc, as
1874 the content does not support Unicode. Instead, the arguments() are constructed
1875 from the return value of
1876 \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
1877 As a result of this, the string given by arguments().at(0) might not be
1878 the program name on Windows, depending on how the application was started.
1880 \sa applicationFilePath()
1883 QStringList QCoreApplication::arguments()
1885 QStringList list;
1887 if (!self) {
1888 qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
1889 return list;
1891 #ifdef Q_OS_WIN
1892 QString cmdline = QString::fromWCharArray(GetCommandLine());
1894 #if defined(Q_OS_WINCE)
1895 wchar_t tempFilename[MAX_PATH+1];
1896 if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
1897 tempFilename[MAX_PATH] = 0;
1898 cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
1900 #endif // Q_OS_WINCE
1902 list = qWinCmdArgs(cmdline);
1903 if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
1904 QStringList stripped;
1905 for (int a = 0; a < list.count(); ++a) {
1906 QString arg = list.at(a);
1907 QByteArray l1arg = arg.toLatin1();
1908 if (l1arg == "-qdevel" ||
1909 l1arg == "-qdebug" ||
1910 l1arg == "-reverse" ||
1911 l1arg == "-stylesheet" ||
1912 l1arg == "-widgetcount")
1914 else if (l1arg.startsWith("-style="))
1916 else if (l1arg == "-style" ||
1917 l1arg == "-session" ||
1918 l1arg == "-graphicssystem")
1919 ++a;
1920 else
1921 stripped += arg;
1923 list = stripped;
1925 #else
1926 const int ac = self->d_func()->argc;
1927 char ** const av = self->d_func()->argv;
1928 for (int a = 0; a < ac; ++a) {
1929 list << QString::fromLocal8Bit(av[a]);
1931 #endif
1933 return list;
1937 \property QCoreApplication::organizationName
1938 \brief the name of the organization that wrote this application
1940 The value is used by the QSettings class when it is constructed
1941 using the empty constructor. This saves having to repeat this
1942 information each time a QSettings object is created.
1944 On Mac, QSettings uses organizationDomain() as the organization
1945 if it's not an empty string; otherwise it uses
1946 organizationName(). On all other platforms, QSettings uses
1947 organizationName() as the organization.
1949 \sa organizationDomain applicationName
1952 void QCoreApplication::setOrganizationName(const QString &orgName)
1954 coreappdata()->orgName = orgName;
1957 QString QCoreApplication::organizationName()
1959 return coreappdata()->orgName;
1963 \property QCoreApplication::organizationDomain
1964 \brief the Internet domain of the organization that wrote this application
1966 The value is used by the QSettings class when it is constructed
1967 using the empty constructor. This saves having to repeat this
1968 information each time a QSettings object is created.
1970 On Mac, QSettings uses organizationDomain() as the organization
1971 if it's not an empty string; otherwise it uses organizationName().
1972 On all other platforms, QSettings uses organizationName() as the
1973 organization.
1975 \sa organizationName applicationName applicationVersion
1977 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
1979 coreappdata()->orgDomain = orgDomain;
1982 QString QCoreApplication::organizationDomain()
1984 return coreappdata()->orgDomain;
1988 \property QCoreApplication::applicationName
1989 \brief the name of this application
1991 The value is used by the QSettings class when it is constructed
1992 using the empty constructor. This saves having to repeat this
1993 information each time a QSettings object is created.
1995 \sa organizationName organizationDomain applicationVersion
1997 void QCoreApplication::setApplicationName(const QString &application)
1999 coreappdata()->application = application;
2002 QString QCoreApplication::applicationName()
2004 return coreappdata()->application;
2008 \property QCoreApplication::applicationVersion
2009 \since 4.4
2010 \brief the version of this application
2012 \sa applicationName organizationName organizationDomain
2014 void QCoreApplication::setApplicationVersion(const QString &version)
2016 coreappdata()->applicationVersion = version;
2019 QString QCoreApplication::applicationVersion()
2021 return coreappdata()->applicationVersion;
2024 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
2026 Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2029 Returns a list of paths that the application will search when
2030 dynamically loading libraries.
2032 Qt provides default library paths, but they can also be set using
2033 a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2034 will override default values.
2036 This list will include the installation directory for plugins if
2037 it exists (the default installation directory for plugins is \c
2038 INSTALL/plugins, where \c INSTALL is the directory where Qt was
2039 installed). The directory of the application executable (NOT the
2040 working directory) is always added, as well as the colon separated
2041 entries of the QT_PLUGIN_PATH environment variable.
2043 If you want to iterate over the list, you can use the \l foreach
2044 pseudo-keyword:
2046 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
2048 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2049 {How to Create Qt Plugins}
2051 QStringList QCoreApplication::libraryPaths()
2053 QMutexLocker locker(libraryPathMutex());
2054 if (!coreappdata()->app_libpaths) {
2055 QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
2056 QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
2057 if (QFile::exists(installPathPlugins)) {
2058 // Make sure we convert from backslashes to slashes.
2059 installPathPlugins = QDir(installPathPlugins).canonicalPath();
2060 if (!app_libpaths->contains(installPathPlugins))
2061 app_libpaths->append(installPathPlugins);
2064 // If QCoreApplication is not yet instantiated,
2065 // make sure we add the application path when we construct the QCoreApplication
2066 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2068 const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2069 if (!libPathEnv.isEmpty()) {
2070 #ifdef Q_OS_WIN
2071 QLatin1Char pathSep(';');
2072 #else
2073 QLatin1Char pathSep(':');
2074 #endif
2075 QStringList paths = QString::fromLatin1(libPathEnv).split(pathSep, QString::SkipEmptyParts);
2076 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2077 QString canonicalPath = QDir(*it).canonicalPath();
2078 if (!canonicalPath.isEmpty()
2079 && !app_libpaths->contains(canonicalPath)) {
2080 app_libpaths->append(canonicalPath);
2085 return *(coreappdata()->app_libpaths);
2092 Sets the list of directories to search when loading libraries to
2093 \a paths. All existing paths will be deleted and the path list
2094 will consist of the paths given in \a paths.
2096 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2098 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2100 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
2101 QMutexLocker locker(libraryPathMutex());
2102 if (!coreappdata()->app_libpaths)
2103 coreappdata()->app_libpaths = new QStringList;
2104 *(coreappdata()->app_libpaths) = paths;
2105 QFactoryLoader::refreshAll();
2106 #endif
2110 Prepends \a path to the beginning of the library path list, ensuring that
2111 it is searched for libraries first. If \a path is empty or already in the
2112 path list, the path list is not changed.
2114 The default path list consists of a single entry, the installation
2115 directory for plugins. The default installation directory for plugins
2116 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2117 installed.
2119 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2121 void QCoreApplication::addLibraryPath(const QString &path)
2123 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
2124 if (path.isEmpty())
2125 return;
2127 QMutexLocker locker(libraryPathMutex());
2129 // make sure that library paths is initialized
2130 libraryPaths();
2132 QString canonicalPath = QDir(path).canonicalPath();
2133 if (!canonicalPath.isEmpty()
2134 && !coreappdata()->app_libpaths->contains(canonicalPath)) {
2135 coreappdata()->app_libpaths->prepend(canonicalPath);
2136 QFactoryLoader::refreshAll();
2138 #endif
2142 Removes \a path from the library path list. If \a path is empty or not
2143 in the path list, the list is not changed.
2145 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2147 void QCoreApplication::removeLibraryPath(const QString &path)
2149 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
2150 if (path.isEmpty())
2151 return;
2153 QMutexLocker locker(libraryPathMutex());
2155 // make sure that library paths is initialized
2156 libraryPaths();
2158 QString canonicalPath = QDir(path).canonicalPath();
2159 coreappdata()->app_libpaths->removeAll(canonicalPath);
2160 QFactoryLoader::refreshAll();
2161 #endif
2164 #endif //QT_NO_LIBRARY
2167 \typedef QCoreApplication::EventFilter
2169 A function with the following signature that can be used as an
2170 event filter:
2172 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
2174 \sa setEventFilter()
2178 \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
2180 Sets the event filter \a filter. Returns a pointer to the filter
2181 function previously defined.
2183 The event filter is a function that is called for every message
2184 received in all threads. This does \e not include messages to
2185 objects that are not handled by Qt.
2187 The function can return true to stop the event to be processed by
2188 Qt, or false to continue with the standard event processing.
2190 Only one filter can be defined, but the filter can use the return
2191 value to call the previously set event filter. By default, no
2192 filter is set (i.e., the function returns 0).
2194 \sa installEventFilter()
2196 QCoreApplication::EventFilter
2197 QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
2199 Q_D(QCoreApplication);
2200 EventFilter old = d->eventFilter;
2201 d->eventFilter = filter;
2202 return old;
2206 Sends \a message through the event filter that was set by
2207 setEventFilter(). If no event filter has been set, this function
2208 returns false; otherwise, this function returns the result of the
2209 event filter function in the \a result parameter.
2211 \sa setEventFilter()
2213 bool QCoreApplication::filterEvent(void *message, long *result)
2215 Q_D(QCoreApplication);
2216 if (result)
2217 *result = 0;
2218 if (d->eventFilter)
2219 return d->eventFilter(message, result);
2220 #ifdef Q_OS_WIN
2221 return winEventFilter(reinterpret_cast<MSG *>(message), result);
2222 #else
2223 return false;
2224 #endif
2228 This function returns true if there are pending events; otherwise
2229 returns false. Pending events can be either from the window
2230 system or posted events using postEvent().
2232 \sa QAbstractEventDispatcher::hasPendingEvents()
2234 bool QCoreApplication::hasPendingEvents()
2236 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2237 if (eventDispatcher)
2238 return eventDispatcher->hasPendingEvents();
2239 return false;
2242 #ifdef QT3_SUPPORT
2243 /*! \fn void QCoreApplication::lock()
2245 In Qt 3, this function locked the Qt library mutex, allowing
2246 non-GUI threads to perform basic printing operations using
2247 QPainter.
2249 In Qt 4, this is no longer supported, since painting is only
2250 supported from within a paint event handler. This function does
2251 nothing.
2253 \sa QWidget::paintEvent()
2256 /*! \fn void QCoreApplication::unlock(bool wakeUpGui)
2258 In Qt 3, this function unlocked the Qt library mutex. The mutex
2259 allowed non-GUI threads to perform basic printing operations
2260 using QPainter.
2262 In Qt 4, this is no longer supported, since painting is only
2263 supported from within a paint event handler. This function does
2264 nothing.
2267 /*! \fn bool QCoreApplication::locked()
2269 This function does nothing. It is there to keep old code working.
2270 It always returns false.
2272 See lock() for details.
2275 /*! \fn bool QCoreApplication::tryLock()
2277 This function does nothing. It is there to keep old code working.
2278 It always returns false.
2280 See lock() for details.
2283 /*! \fn void QCoreApplication::processOneEvent()
2284 \obsolete
2286 Waits for an event to occur, processes it, then returns.
2288 This function is useful for adapting Qt to situations where the
2289 event processing must be grafted onto existing program loops.
2291 Using this function in new applications may be an indication of design
2292 problems.
2294 \sa processEvents(), exec(), QTimer
2297 /*! \obsolete
2299 This function enters the main event loop (recursively). Do not call
2300 it unless you really know what you are doing.
2302 int QCoreApplication::enter_loop()
2304 if (!QCoreApplicationPrivate::checkInstance("enter_loop"))
2305 return -1;
2306 if (QThreadData::current() != self->d_func()->threadData) {
2307 qWarning("QCoreApplication::enter_loop: Must be called from the main thread");
2308 return -1;
2310 QEventLoop eventLoop;
2311 int returnCode = eventLoop.exec();
2312 return returnCode;
2315 /*! \obsolete
2317 This function exits from a recursive call to the main event loop.
2318 Do not call it unless you are an expert.
2320 void QCoreApplication::exit_loop()
2322 if (!QCoreApplicationPrivate::checkInstance("exit_loop"))
2323 return;
2324 QThreadData *data = QThreadData::current();
2325 if (data != self->d_func()->threadData) {
2326 qWarning("QCoreApplication::exit_loop: Must be called from the main thread");
2327 return;
2329 if (!data->eventLoops.isEmpty())
2330 data->eventLoops.top()->exit();
2333 /*! \obsolete
2335 Returns the current loop level.
2337 int QCoreApplication::loopLevel()
2339 if (!QCoreApplicationPrivate::checkInstance("loopLevel"))
2340 return -1;
2341 return self->d_func()->threadData->eventLoops.size();
2343 #endif
2346 \fn void QCoreApplication::watchUnixSignal(int signal, bool watch)
2347 \internal
2351 \fn void QCoreApplication::unixSignal(int number)
2352 \internal
2354 This signal is emitted whenever a Unix signal is received by the
2355 application. The Unix signal received is specified by its \a number.
2359 \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2360 \relates QCoreApplication
2362 Adds a global routine that will be called from the QApplication
2363 destructor. This function is normally used to add cleanup routines
2364 for program-wide functionality.
2366 The function specified by \a ptr should take no arguments and should
2367 return nothing. For example:
2369 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
2371 Note that for an application- or module-wide cleanup,
2372 qAddPostRoutine() is often not suitable. For example, if the
2373 program is split into dynamically loaded modules, the relevant
2374 module may be unloaded long before the QApplication destructor is
2375 called.
2377 For modules and libraries, using a reference-counted
2378 initialization manager or Qt's parent-child deletion mechanism may
2379 be better. Here is an example of a private class that uses the
2380 parent-child mechanism to call a cleanup function at the right
2381 time:
2383 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
2385 By selecting the right parent object, this can often be made to
2386 clean up the module's data at the right moment.
2390 \macro Q_DECLARE_TR_FUNCTIONS(context)
2391 \relates QCoreApplication
2393 The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2394 translation functions, \c tr() and \c trUtf8(), with these
2395 signatures:
2397 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
2399 This macro is useful if you want to use QObject::tr() or
2400 QObject::trUtf8() in classes that don't inherit from QObject.
2402 Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2403 class definition (before the first \c{public:} or \c{protected:}).
2404 For example:
2406 \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
2408 The \a context parameter is normally the class name, but it can
2409 be any string.
2411 \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2414 QT_END_NAMESPACE