From 2a742eba7a9be98354dc0e60c3644db484fe09db Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 18 Jan 2012 09:51:03 +0100 Subject: core as a directory name is usually not a good idea Let's follow the other places in qtbase where the directory is named corelib. Change-Id: Ib426f4ee7311f622a89b252b9915aca1d3dd688d Reviewed-by: Casper van Donderen Reviewed-by: Thiago Macieira --- doc/src/core/containers.qdoc | 803 ----------------------- doc/src/core/implicit-sharing.qdoc | 138 ---- doc/src/core/objectmodel/metaobjects.qdoc | 137 ---- doc/src/core/objectmodel/object.qdoc | 124 ---- doc/src/core/objectmodel/objecttrees.qdoc | 102 --- doc/src/core/objectmodel/properties.qdoc | 273 -------- doc/src/core/objectmodel/signalsandslots.qdoc | 468 ------------- doc/src/core/qtcore.qdoc | 42 -- doc/src/core/threads-basics.qdoc | 572 ---------------- doc/src/core/threads.qdoc | 705 -------------------- doc/src/corelib/containers.qdoc | 803 +++++++++++++++++++++++ doc/src/corelib/implicit-sharing.qdoc | 138 ++++ doc/src/corelib/objectmodel/metaobjects.qdoc | 137 ++++ doc/src/corelib/objectmodel/object.qdoc | 124 ++++ doc/src/corelib/objectmodel/objecttrees.qdoc | 102 +++ doc/src/corelib/objectmodel/properties.qdoc | 273 ++++++++ doc/src/corelib/objectmodel/signalsandslots.qdoc | 468 +++++++++++++ doc/src/corelib/qtcore.qdoc | 42 ++ doc/src/corelib/threads-basics.qdoc | 572 ++++++++++++++++ doc/src/corelib/threads.qdoc | 705 ++++++++++++++++++++ 20 files changed, 3364 insertions(+), 3364 deletions(-) delete mode 100644 doc/src/core/containers.qdoc delete mode 100644 doc/src/core/implicit-sharing.qdoc delete mode 100644 doc/src/core/objectmodel/metaobjects.qdoc delete mode 100644 doc/src/core/objectmodel/object.qdoc delete mode 100644 doc/src/core/objectmodel/objecttrees.qdoc delete mode 100644 doc/src/core/objectmodel/properties.qdoc delete mode 100644 doc/src/core/objectmodel/signalsandslots.qdoc delete mode 100644 doc/src/core/qtcore.qdoc delete mode 100644 doc/src/core/threads-basics.qdoc delete mode 100644 doc/src/core/threads.qdoc create mode 100644 doc/src/corelib/containers.qdoc create mode 100644 doc/src/corelib/implicit-sharing.qdoc create mode 100644 doc/src/corelib/objectmodel/metaobjects.qdoc create mode 100644 doc/src/corelib/objectmodel/object.qdoc create mode 100644 doc/src/corelib/objectmodel/objecttrees.qdoc create mode 100644 doc/src/corelib/objectmodel/properties.qdoc create mode 100644 doc/src/corelib/objectmodel/signalsandslots.qdoc create mode 100644 doc/src/corelib/qtcore.qdoc create mode 100644 doc/src/corelib/threads-basics.qdoc create mode 100644 doc/src/corelib/threads.qdoc (limited to 'doc') diff --git a/doc/src/core/containers.qdoc b/doc/src/core/containers.qdoc deleted file mode 100644 index ca9bcc6b47..0000000000 --- a/doc/src/core/containers.qdoc +++ /dev/null @@ -1,803 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \group tools - \title Non-GUI Classes - \ingroup groups - - \brief Collection classes such as list, queue, stack and string, along - with other classes that can be used without needing QApplication. - - The non-GUI classes are general-purpose collection and string classes - that may be used independently of the GUI classes. - - In particular, these classes do not depend on QApplication at all, - and so can be used in non-GUI programs. - -*/ - -/*! - \page containers.html - \title Container Classes - \ingroup technology-apis - \ingroup groups - \ingroup qt-basic-concepts - \keyword container class - \keyword container classes - - \brief Qt's template-based container classes. - - \tableofcontents - - \section1 Introduction - - The Qt library provides a set of general purpose template-based - container classes. These classes can be used to store items of a - specified type. For example, if you need a resizable array of - \l{QString}s, use QVector. - - These container classes are designed to be lighter, safer, and - easier to use than the STL containers. If you are unfamiliar with - the STL, or prefer to do things the "Qt way", you can use these - classes instead of the STL classes. - - The container classes are \l{implicitly shared}, they are - \l{reentrant}, and they are optimized for speed, low memory - consumption, and minimal inline code expansion, resulting in - smaller executables. In addition, they are \l{thread-safe} - in situations where they are used as read-only containers - by all threads used to access them. - - For traversing the items stored in a container, you can use one - of two types of iterators: \l{Java-style iterators} and - \l{STL-style iterators}. The Java-style iterators are easier to - use and provide high-level functionality, whereas the STL-style - iterators are slightly more efficient and can be used together - with Qt's and STL's \l{generic algorithms}. - - Qt also offers a \l{foreach} keyword that make it very - easy to iterate over all the items stored in a container. - - \section1 The Container Classes - - Qt provides the following sequential containers: QList, - QLinkedList, QVector, QStack, and QQueue. For most - applications, QList is the best type to use. Although it is - implemented as an array-list, it provides very fast prepends and - appends. If you really need a linked-list, use QLinkedList; if you - want your items to occupy consecutive memory locations, use QVector. - QStack and QQueue are convenience classes that provide LIFO and - FIFO semantics. - - Qt also provides these associative containers: QMap, - QMultiMap, QHash, QMultiHash, and QSet. The "Multi" containers - conveniently support multiple values associated with a single - key. The "Hash" containers provide faster lookup by using a hash - function instead of a binary search on a sorted set. - - As special cases, the QCache and QContiguousCache classes provide - efficient hash-lookup of objects in a limited cache storage. - - \table - \header \o Class \o Summary - - \row \o \l{QList} - \o This is by far the most commonly used container class. It - stores a list of values of a given type (T) that can be accessed - by index. Internally, the QList is implemented using an array, - ensuring that index-based access is very fast. - - Items can be added at either end of the list using - QList::append() and QList::prepend(), or they can be inserted in - the middle using QList::insert(). More than any other container - class, QList is highly optimized to expand to as little code as - possible in the executable. QStringList inherits from - QList. - - \row \o \l{QLinkedList} - \o This is similar to QList, except that it uses - iterators rather than integer indexes to access items. It also - provides better performance than QList when inserting in the - middle of a huge list, and it has nicer iterator semantics. - (Iterators pointing to an item in a QLinkedList remain valid as - long as the item exists, whereas iterators to a QList can become - invalid after any insertion or removal.) - - \row \o \l{QVector} - \o This stores an array of values of a given type at adjacent - positions in memory. Inserting at the front or in the middle of - a vector can be quite slow, because it can lead to large numbers - of items having to be moved by one position in memory. - - \row \o \l{QStack} - \o This is a convenience subclass of QVector that provides - "last in, first out" (LIFO) semantics. It adds the following - functions to those already present in QVector: - \l{QStack::push()}{push()}, \l{QStack::pop()}{pop()}, - and \l{QStack::top()}{top()}. - - \row \o \l{QQueue} - \o This is a convenience subclass of QList that provides - "first in, first out" (FIFO) semantics. It adds the following - functions to those already present in QList: - \l{QQueue::enqueue()}{enqueue()}, - \l{QQueue::dequeue()}{dequeue()}, and \l{QQueue::head()}{head()}. - - \row \o \l{QSet} - \o This provides a single-valued mathematical set with fast - lookups. - - \row \o \l{QMap} - \o This provides a dictionary (associative array) that maps keys - of type Key to values of type T. Normally each key is associated - with a single value. QMap stores its data in Key order; if order - doesn't matter QHash is a faster alternative. - - \row \o \l{QMultiMap} - \o This is a convenience subclass of QMap that provides a nice - interface for multi-valued maps, i.e. maps where one key can be - associated with multiple values. - - \row \o \l{QHash} - \o This has almost the same API as QMap, but provides - significantly faster lookups. QHash stores its data in an - arbitrary order. - - \row \o \l{QMultiHash} - \o This is a convenience subclass of QHash that - provides a nice interface for multi-valued hashes. - - \endtable - - Containers can be nested. For example, it is perfectly possible - to use a QMap >, where the key type is - QString and the value type QList. The only pitfall is that - you must insert a space between the closing angle brackets (>); - otherwise the C++ compiler will misinterpret the two >'s as a - right-shift operator (>>) and report a syntax error. - - The containers are defined in individual header files with the - same name as the container (e.g., \c ). For - convenience, the containers are forward declared in \c - . - - \keyword assignable data type - \keyword assignable data types - - The values stored in the various containers can be of any - \e{assignable data type}. To qualify, a type must provide a - default constructor, a copy constructor, and an assignment - operator. This covers most data types you are likely to want to - store in a container, including basic types such as \c int and \c - double, pointer types, and Qt data types such as QString, QDate, - and QTime, but it doesn't cover QObject or any QObject subclass - (QWidget, QDialog, QTimer, etc.). If you attempt to instantiate a - QList, the compiler will complain that QWidget's copy - constructor and assignment operators are disabled. If you want to - store these kinds of objects in a container, store them as - pointers, for example as QList. - - Here's an example custom data type that meets the requirement of - an assignable data type: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 0 - - If we don't provide a copy constructor or an assignment operator, - C++ provides a default implementation that performs a - member-by-member copy. In the example above, that would have been - sufficient. Also, if you don't provide any constructors, C++ - provides a default constructor that initializes its member using - default constructors. Although it doesn't provide any - explicit constructors or assignment operator, the following data - type can be stored in a container: - - \snippet doc/src/snippets/streaming/main.cpp 0 - - Some containers have additional requirements for the data types - they can store. For example, the Key type of a QMap must - provide \c operator<(). Such special requirements are documented - in a class's detailed description. In some cases, specific - functions have special requirements; these are described on a - per-function basis. The compiler will always emit an error if a - requirement isn't met. - - Qt's containers provide operator<<() and operator>>() so that they - can easily be read and written using a QDataStream. This means - that the data types stored in the container must also support - operator<<() and operator>>(). Providing such support is - straightforward; here's how we could do it for the Movie struct - above: - - \snippet doc/src/snippets/streaming/main.cpp 1 - \codeline - \snippet doc/src/snippets/streaming/main.cpp 2 - - \keyword default-constructed values - - The documentation of certain container class functions refer to - \e{default-constructed values}; for example, QVector - automatically initializes its items with default-constructed - values, and QMap::value() returns a default-constructed value if - the specified key isn't in the map. For most value types, this - simply means that a value is created using the default - constructor (e.g. an empty string for QString). But for primitive - types like \c{int} and \c{double}, as well as for pointer types, - the C++ language doesn't specify any initialization; in those - cases, Qt's containers automatically initialize the value to 0. - - \section1 The Iterator Classes - - Iterators provide a uniform means to access items in a container. - Qt's container classes provide two types of iterators: Java-style - iterators and STL-style iterators. Iterators of both types are - invalidated when the data in the container is modified or detached - from \l{Implicit Sharing}{implicitly shared copies} due to a call - to a non-const member function. - - \section2 Java-Style Iterators - - The Java-style iterators are new in Qt 4 and are the standard - ones used in Qt applications. They are more convenient to use than - the STL-style iterators, at the price of being slightly less - efficient. Their API is modelled on Java's iterator classes. - - For each container class, there are two Java-style iterator data - types: one that provides read-only access and one that provides - read-write access. - - \table - \header \o Containers \o Read-only iterator - \o Read-write iterator - \row \o QList, QQueue \o QListIterator - \o QMutableListIterator - \row \o QLinkedList \o QLinkedListIterator - \o QMutableLinkedListIterator - \row \o QVector, QStack \o QVectorIterator - \o QMutableVectorIterator - \row \o QSet \o QSetIterator - \o QMutableSetIterator - \row \o QMap, QMultiMap \o QMapIterator - \o QMutableMapIterator - \row \o QHash, QMultiHash \o QHashIterator - \o QMutableHashIterator - \endtable - - In this discussion, we will concentrate on QList and QMap. The - iterator types for QLinkedList, QVector, and QSet have exactly - the same interface as QList's iterators; similarly, the iterator - types for QHash have the same interface as QMap's iterators. - - Unlike STL-style iterators (covered \l{STL-style - iterators}{below}), Java-style iterators point \e between items - rather than directly \e at items. For this reason, they are - either pointing to the very beginning of the container (before - the first item), at the very end of the container (after the last - item), or between two items. The diagram below shows the valid - iterator positions as red arrows for a list containing four - items: - - \img javaiterators1.png - - Here's a typical loop for iterating through all the elements of a - QList in order and printing them to the console: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 1 - - It works as follows: The QList to iterate over is passed to the - QListIterator constructor. At that point, the iterator is located - just in front of the first item in the list (before item "A"). - Then we call \l{QListIterator::hasNext()}{hasNext()} to - check whether there is an item after the iterator. If there is, we - call \l{QListIterator::next()}{next()} to jump over that - item. The next() function returns the item that it jumps over. For - a QList, that item is of type QString. - - Here's how to iterate backward in a QList: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 2 - - The code is symmetric with iterating forward, except that we - start by calling \l{QListIterator::toBack()}{toBack()} - to move the iterator after the last item in the list. - - The diagram below illustrates the effect of calling - \l{QListIterator::next()}{next()} and - \l{QListIterator::previous()}{previous()} on an iterator: - - \img javaiterators2.png - - The following table summarizes the QListIterator API: - - \table - \header \o Function \o Behavior - \row \o \l{QListIterator::toFront()}{toFront()} - \o Moves the iterator to the front of the list (before the first item) - \row \o \l{QListIterator::toBack()}{toBack()} - \o Moves the iterator to the back of the list (after the last item) - \row \o \l{QListIterator::hasNext()}{hasNext()} - \o Returns true if the iterator isn't at the back of the list - \row \o \l{QListIterator::next()}{next()} - \o Returns the next item and advances the iterator by one position - \row \o \l{QListIterator::peekNext()}{peekNext()} - \o Returns the next item without moving the iterator - \row \o \l{QListIterator::hasPrevious()}{hasPrevious()} - \o Returns true if the iterator isn't at the front of the list - \row \o \l{QListIterator::previous()}{previous()} - \o Returns the previous item and moves the iterator back by one position - \row \o \l{QListIterator::peekPrevious()}{peekPrevious()} - \o Returns the previous item without moving the iterator - \endtable - - QListIterator provides no functions to insert or remove items - from the list as we iterate. To accomplish this, you must use - QMutableListIterator. Here's an example where we remove all - odd numbers from a QList using QMutableListIterator: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 3 - - The next() call in the loop is made every time. It jumps over the - next item in the list. The - \l{QMutableListIterator::remove()}{remove()} function removes the - last item that we jumped over from the list. The call to - \l{QMutableListIterator::remove()}{remove()} does not invalidate - the iterator, so it is safe to continue using it. This works just - as well when iterating backward: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 4 - - If we just want to modify the value of an existing item, we can - use \l{QMutableListIterator::setValue()}{setValue()}. In the code - below, we replace any value larger than 128 with 128: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 5 - - Just like \l{QMutableListIterator::remove()}{remove()}, - \l{QMutableListIterator::setValue()}{setValue()} operates on the - last item that we jumped over. If we iterate forward, this is the - item just before the iterator; if we iterate backward, this is - the item just after the iterator. - - The \l{QMutableListIterator::next()}{next()} function returns a - non-const reference to the item in the list. For simple - operations, we don't even need - \l{QMutableListIterator::setValue()}{setValue()}: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 6 - - As mentioned above, QLinkedList's, QVector's, and QSet's iterator - classes have exactly the same API as QList's. We will now turn to - QMapIterator, which is somewhat different because it iterates on - (key, value) pairs. - - Like QListIterator, QMapIterator provides - \l{QMapIterator::toFront()}{toFront()}, - \l{QMapIterator::toBack()}{toBack()}, - \l{QMapIterator::hasNext()}{hasNext()}, - \l{QMapIterator::next()}{next()}, - \l{QMapIterator::peekNext()}{peekNext()}, - \l{QMapIterator::hasPrevious()}{hasPrevious()}, - \l{QMapIterator::previous()}{previous()}, and - \l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and - value components are extracted by calling key() and value() on - the object returned by next(), peekNext(), previous(), or - peekPrevious(). - - The following example removes all (capital, country) pairs where - the capital's name ends with "City": - - \snippet doc/src/snippets/code/doc_src_containers.cpp 7 - - QMapIterator also provides a key() and a value() function that - operate directly on the iterator and that return the key and - value of the last item that the iterator jumped above. For - example, the following code copies the contents of a QMap into a - QHash: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 8 - - If we want to iterate through all the items with the same - value, we can use \l{QMapIterator::findNext()}{findNext()} - or \l{QMapIterator::findPrevious()}{findPrevious()}. - Here's an example where we remove all the items with a particular - value: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 9 - - \section2 STL-Style Iterators - - STL-style iterators have been available since the release of Qt - 2.0. They are compatible with Qt's and STL's \l{generic - algorithms} and are optimized for speed. - - For each container class, there are two STL-style iterator types: - one that provides read-only access and one that provides - read-write access. Read-only iterators should be used wherever - possible because they are faster than read-write iterators. - - \table - \header \o Containers \o Read-only iterator - \o Read-write iterator - \row \o QList, QQueue \o QList::const_iterator - \o QList::iterator - \row \o QLinkedList \o QLinkedList::const_iterator - \o QLinkedList::iterator - \row \o QVector, QStack \o QVector::const_iterator - \o QVector::iterator - \row \o QSet \o QSet::const_iterator - \o QSet::iterator - \row \o QMap, QMultiMap \o QMap::const_iterator - \o QMap::iterator - \row \o QHash, QMultiHash \o QHash::const_iterator - \o QHash::iterator - \endtable - - The API of the STL iterators is modelled on pointers in an array. - For example, the \c ++ operator advances the iterator to the next - item, and the \c * operator returns the item that the iterator - points to. In fact, for QVector and QStack, which store their - items at adjacent memory positions, the - \l{QVector::iterator}{iterator} type is just a typedef for \c{T *}, - and the \l{QVector::iterator}{const_iterator} type is - just a typedef for \c{const T *}. - - In this discussion, we will concentrate on QList and QMap. The - iterator types for QLinkedList, QVector, and QSet have exactly - the same interface as QList's iterators; similarly, the iterator - types for QHash have the same interface as QMap's iterators. - - Here's a typical loop for iterating through all the elements of a - QList in order and converting them to lowercase: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 10 - - Unlike \l{Java-style iterators}, STL-style iterators point - directly at items. The begin() function of a container returns an - iterator that points to the first item in the container. The - end() function of a container returns an iterator to the - imaginary item one position past the last item in the container. - end() marks an invalid position; it must never be dereferenced. - It is typically used in a loop's break condition. If the list is - empty, begin() equals end(), so we never execute the loop. - - The diagram below shows the valid iterator positions as red - arrows for a vector containing four items: - - \img stliterators1.png - - Iterating backward with an STL-style iterator requires us to - decrement the iterator \e before we access the item. This - requires a \c while loop: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 11 - - In the code snippets so far, we used the unary \c * operator to - retrieve the item (of type QString) stored at a certain iterator - position, and we then called QString::toLower() on it. Most C++ - compilers also allow us to write \c{i->toLower()}, but some - don't. - - For read-only access, you can use const_iterator, constBegin(), - and constEnd(). For example: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 12 - - The following table summarizes the STL-style iterators' API: - - \table - \header \o Expression \o Behavior - \row \o \c{*i} \o Returns the current item - \row \o \c{++i} \o Advances the iterator to the next item - \row \o \c{i += n} \o Advances the iterator by \c n items - \row \o \c{--i} \o Moves the iterator back by one item - \row \o \c{i -= n} \o Moves the iterator back by \c n items - \row \o \c{i - j} \o Returns the number of items between iterators \c i and \c j - \endtable - - The \c{++} and \c{--} operators are available both as prefix - (\c{++i}, \c{--i}) and postfix (\c{i++}, \c{i--}) operators. The - prefix versions modify the iterators and return a reference to - the modified iterator; the postfix versions take a copy of the - iterator before they modify it, and return that copy. In - expressions where the return value is ignored, we recommend that - you use the prefix operators (\c{++i}, \c{--i}), as these are - slightly faster. - - For non-const iterator types, the return value of the unary \c{*} - operator can be used on the left side of the assignment operator. - - For QMap and QHash, the \c{*} operator returns the value - component of an item. If you want to retrieve the key, call key() - on the iterator. For symmetry, the iterator types also provide a - value() function to retrieve the value. For example, here's how - we would print all items in a QMap to the console: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 13 - - Thanks to \l{implicit sharing}, it is very inexpensive for a - function to return a container per value. The Qt API contains - dozens of functions that return a QList or QStringList per value - (e.g., QSplitter::sizes()). If you want to iterate over these - using an STL iterator, you should always take a copy of the - container and iterate over the copy. For example: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 14 - - This problem doesn't occur with functions that return a const or - non-const reference to a container. - - \l{Implicit sharing} has another consequence on STL-style - iterators: You must not take a copy of a container while - non-const iterators are active on that container. Java-style - iterators don't suffer from that limitation. - - \keyword foreach - \section1 The foreach Keyword - - If you just want to iterate over all the items in a container - in order, you can use Qt's \c foreach keyword. The keyword is a - Qt-specific addition to the C++ language, and is implemented - using the preprocessor. - - Its syntax is: \c foreach (\e variable, \e container) \e - statement. For example, here's how to use \c foreach to iterate - over a QLinkedList: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 15 - - The \c foreach code is significantly shorter than the equivalent - code that uses iterators: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 16 - - Unless the data type contains a comma (e.g., \c{QPair}), the variable used for iteration can be defined within the - \c foreach statement: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 17 - - And like any other C++ loop construct, you can use braces around - the body of a \c foreach loop, and you can use \c break to leave - the loop: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 18 - - With QMap and QHash, \c foreach accesses the value component of - the (key, value) pairs. If you want to iterate over both the keys - and the values, you can use iterators (which are fastest), or you - can write code like this: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 19 - - For a multi-valued map: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 20 - - Qt automatically takes a copy of the container when it enters a - \c foreach loop. If you modify the container as you are - iterating, that won't affect the loop. (If you do not modify the - container, the copy still takes place, but thanks to \l{implicit - sharing} copying a container is very fast.) - - Since foreach creates a copy of the container, using a non-const - reference for the variable does not allow you to modify the original - container. It only affects the copy, which is probably not what you - want. - - In addition to \c foreach, Qt also provides a \c forever - pseudo-keyword for infinite loops: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 21 - - If you're worried about namespace pollution, you can disable - these macros by adding the following line to your \c .pro file: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 22 - - \section1 Other Container-Like Classes - - Qt includes three template classes that resemble containers in - some respects. These classes don't provide iterators and cannot - be used with the \c foreach keyword. - - \list - \o QVarLengthArray provides a low-level - variable-length array. It can be used instead of QVector in - places where speed is particularly important. - - \o QCache provides a cache to store objects of a certain - type T associated with keys of type Key. - - \o QContiguousCache provides an efficient way of caching data - that is typically accessed in a contiguous way. - - \o QPair stores a pair of elements. - \endlist - - Additional non-template types that compete with Qt's template - containers are QBitArray, QByteArray, QString, and QStringList. - - \section1 Algorithmic Complexity - - Algorithmic complexity is concerned about how fast (or slow) each - function is as the number of items in the container grow. For - example, inserting an item in the middle of a QLinkedList is an - extremely fast operation, irrespective of the number of items - stored in the QLinkedList. On the other hand, inserting an item - in the middle of a QVector is potentially very expensive if the - QVector contains many items, since half of the items must be - moved one position in memory. - - To describe algorithmic complexity, we use the following - terminology, based on the "big Oh" notation: - - \keyword constant time - \keyword logarithmic time - \keyword linear time - \keyword linear-logarithmic time - \keyword quadratic time - - \list - \o \bold{Constant time:} O(1). A function is said to run in constant - time if it requires the same amount of time no matter how many - items are present in the container. One example is - QLinkedList::insert(). - - \o \bold{Logarithmic time:} O(log \e n). A function that runs in - logarithmic time is a function whose running time is - proportional to the logarithm of the number of items in the - container. One example is qBinaryFind(). - - \o \bold{Linear time:} O(\e n). A function that runs in linear time - will execute in a time directly proportional to the number of - items stored in the container. One example is - QVector::insert(). - - \o \bold{Linear-logarithmic time:} O(\e{n} log \e n). A function - that runs in linear-logarithmic time is asymptotically slower - than a linear-time function, but faster than a quadratic-time - function. - - \o \bold{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function - executes in a time that is proportional to the square of the - number of items stored in the container. - \endlist - - The following table summarizes the algorithmic complexity of Qt's - sequential container classes: - - \table - \header \o \o Index lookup \o Insertion \o Prepending \o Appending - \row \o QLinkedList \o O(\e n) \o O(1) \o O(1) \o O(1) - \row \o QList \o O(1) \o O(n) \o Amort. O(1) \o Amort. O(1) - \row \o QVector \o O(1) \o O(n) \o O(n) \o Amort. O(1) - \endtable - - In the table, "Amort." stands for "amortized behavior". For - example, "Amort. O(1)" means that if you call the function - only once, you might get O(\e n) behavior, but if you call it - multiple times (e.g., \e n times), the average behavior will be - O(1). - - The following table summarizes the algorithmic complexity of Qt's - associative containers and sets: - - \table - \header \o{1,2} \o{2,1} Key lookup \o{2,1} Insertion - \header \o Average \o Worst case \o Average \o Worst case - \row \o QMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) - \row \o QMultiMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) - \row \o QHash \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) - \row \o QSet \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) - \endtable - - With QVector, QHash, and QSet, the performance of appending items - is amortized O(log \e n). It can be brought down to O(1) by - calling QVector::reserve(), QHash::reserve(), or QSet::reserve() - with the expected number of items before you insert the items. - The next section discusses this topic in more depth. - - \section1 Growth Strategies - - QVector, QString, and QByteArray store their items - contiguously in memory; QList maintains an array of pointers - to the items it stores to provide fast index-based access (unless - T is a pointer type or a basic type of the size of a pointer, in - which case the value itself is stored in the array); QHash keeps a hash table whose size is proportional to the number - of items in the hash. To avoid reallocating the data every single - time an item is added at the end of the container, these classes - typically allocate more memory than necessary. - - Consider the following code, which builds a QString from another - QString: - - \snippet doc/src/snippets/code/doc_src_containers.cpp 23 - - We build the string \c out dynamically by appending one character - to it at a time. Let's assume that we append 15000 characters to - the QString string. Then the following 18 reallocations (out of a - possible 15000) occur when QString runs out of space: 4, 8, 12, - 16, 20, 52, 116, 244, 500, 1012, 2036, 4084, 6132, 8180, 10228, - 12276, 14324, 16372. At the end, the QString has 16372 Unicode - characters allocated, 15000 of which are occupied. - - The values above may seem a bit strange, but here are the guiding - principles: - \list - \o QString allocates 4 characters at a time until it reaches size 20. - \o From 20 to 4084, it advances by doubling the size each time. - More precisely, it advances to the next power of two, minus - 12. (Some memory allocators perform worst when requested exact - powers of two, because they use a few bytes per block for - book-keeping.) - \o From 4084 on, it advances by blocks of 2048 characters (4096 - bytes). This makes sense because modern operating systems - don't copy the entire data when reallocating a buffer; the - physical memory pages are simply reordered, and only the data - on the first and last pages actually needs to be copied. - \endlist - - QByteArray and QList use more or less the same algorithm as - QString. - - QVector also uses that algorithm for data types that can be - moved around in memory using memcpy() (including the basic C++ - types, the pointer types, and Qt's \l{shared classes}) but uses a - different algorithm for data types that can only be moved by - calling the copy constructor and a destructor. Since the cost of - reallocating is higher in that case, QVector reduces the - number of reallocations by always doubling the memory when - running out of space. - - QHash is a totally different case. QHash's internal hash - table grows by powers of two, and each time it grows, the items - are relocated in a new bucket, computed as qHash(\e key) % - QHash::capacity() (the number of buckets). This remark applies to - QSet and QCache as well. - - For most applications, the default growing algorithm provided by - Qt does the trick. If you need more control, QVector, - QHash, QSet, QString, and QByteArray provide a trio of - functions that allow you to check and specify how much memory to - use to store the items: - - \list - \o \l{QString::capacity()}{capacity()} returns the - number of items for which memory is allocated (for QHash and - QSet, the number of buckets in the hash table). - \o \l{QString::reserve()}{reserve}(\e size) explicitly - preallocates memory for \e size items. - \o \l{QString::squeeze()}{squeeze()} frees any memory - not required to store the items. - \endlist - - If you know approximately how many items you will store in a - container, you can start by calling reserve(), and when you are - done populating the container, you can call squeeze() to release - the extra preallocated memory. -*/ diff --git a/doc/src/core/implicit-sharing.qdoc b/doc/src/core/implicit-sharing.qdoc deleted file mode 100644 index e745d127d5..0000000000 --- a/doc/src/core/implicit-sharing.qdoc +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* TODO: Move some of the documentation from QSharedDataPointer into this - document. */ - -/*! - \group shared - \title Implicitly Shared Classes -*/ - -/*! - \page implicit-sharing.html - \title Implicit Sharing - \ingroup qt-basic-concepts - - \brief Reference counting for fast copying. - - \keyword implicit data sharing - \keyword implicit sharing - \keyword implicitly shared - \keyword reference counting - \keyword shared implicitly - \keyword shared classes - - Many C++ classes in Qt use implicit data sharing to maximize - resource usage and minimize copying. Implicitly shared classes are - both safe and efficient when passed as arguments, because only a - pointer to the data is passed around, and the data is copied only - if and when a function writes to it, i.e., \e {copy-on-write}. - - \tableofcontents - - \section1 Overview - - A shared class consists of a pointer to a shared data block that - contains a reference count and the data. - - When a shared object is created, it sets the reference count to 1. The - reference count is incremented whenever a new object references the - shared data, and decremented when the object dereferences the shared - data. The shared data is deleted when the reference count becomes - zero. - - \keyword deep copy - \keyword shallow copy - - When dealing with shared objects, there are two ways of copying an - object. We usually speak about \e deep and \e shallow copies. A deep - copy implies duplicating an object. A shallow copy is a reference - copy, i.e. just a pointer to a shared data block. Making a deep copy - can be expensive in terms of memory and CPU. Making a shallow copy is - very fast, because it only involves setting a pointer and incrementing - the reference count. - - Object assignment (with operator=()) for implicitly shared objects is - implemented using shallow copies. - - The benefit of sharing is that a program does not need to duplicate - data unnecessarily, which results in lower memory use and less copying - of data. Objects can easily be assigned, sent as function arguments, - and returned from functions. - - Implicit sharing takes place behind the scenes; the programmer - does not need to worry about it. Even in multithreaded - applications, implicit sharing takes place, as explained in - \l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes} - {Threads and Implicitly Shared Classes}. - - When implementing your own implicitly shared classes, use the - QSharedData and QSharedDataPointer classes. - - \section1 Implicit Sharing in Detail - - Implicit sharing automatically detaches the object from a shared - block if the object is about to change and the reference count is - greater than one. (This is often called \e {copy-on-write} or - \e {value semantics}.) - - An implicitly shared class has total control of its internal data. In - any member functions that modify its data, it automatically detaches - before modifying the data. - - The QPen class, which uses implicit sharing, detaches from the shared - data in all member functions that change the internal data. - - Code fragment: - \snippet doc/src/snippets/code/doc_src_groups.cpp 0 - - - \section1 List of Classes - - The classes listed below automatically detach from common data if - an object is about to be changed. The programmer will not even - notice that the objects are shared. Thus you should treat - separate instances of them as separate objects. They will always - behave as separate objects but with the added benefit of sharing - data whenever possible. For this reason, you can pass instances - of these classes as arguments to functions by value without - concern for the copying overhead. - - Example: - \snippet doc/src/snippets/code/doc_src_groups.cpp 1 - - In this example, \c p1 and \c p2 share data until QPainter::begin() - is called for \c p2, because painting a pixmap will modify it. - - \warning Do not copy an implicitly shared container (QMap, - QVector, etc.) while you are iterating over it using an non-const - \l{STL-style iterator}. - - \keyword implicitly shared classes - \annotatedlist shared -*/ diff --git a/doc/src/core/objectmodel/metaobjects.qdoc b/doc/src/core/objectmodel/metaobjects.qdoc deleted file mode 100644 index 0a4756f899..0000000000 --- a/doc/src/core/objectmodel/metaobjects.qdoc +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page metaobjects.html - \title The Meta-Object System - \brief An overview of Qt's meta-object system and introspection capabilities. - - \ingroup qt-basic-concepts - \keyword meta-object - \target Meta-Object System - - Qt's meta-object system provides the signals and slots mechanism for - inter-object communication, run-time type information, and the dynamic - property system. - - The meta-object system is based on three things: - - \list 1 - \o The \l QObject class provides a base class for objects that can - take advantage of the meta-object system. - \o The Q_OBJECT macro inside the private section of the class - declaration is used to enable meta-object features, such as - dynamic properties, signals, and slots. - \o The \l{moc}{Meta-Object Compiler} (\c moc) supplies each - QObject subclass with the necessary code to implement - meta-object features. - \endlist - - The \c moc tool reads a C++ source file. If it finds one or more - class declarations that contain the Q_OBJECT macro, it - produces another C++ source file which contains the meta-object - code for each of those classes. This generated source file is - either \c{#include}'d into the class's source file or, more - usually, compiled and linked with the class's implementation. - - In addition to providing the \l{signals and slots} mechanism for - communication between objects (the main reason for introducing - the system), the meta-object code provides the following - additional features: - - \list - \o QObject::metaObject() returns the associated - \l{QMetaObject}{meta-object} for the class. - \o QMetaObject::className() returns the class name as a - string at run-time, without requiring native run-time type information - (RTTI) support through the C++ compiler. - \o QObject::inherits() function returns whether an object is an - instance of a class that inherits a specified class within the - QObject inheritance tree. - \o QObject::tr() and QObject::trUtf8() translate strings for - \l{Internationalization with Qt}{internationalization}. - \o QObject::setProperty() and QObject::property() - dynamically set and get properties by name. - \o QMetaObject::newInstance() constructs a new instance of the class. - \endlist - - \target qobjectcast - It is also possible to perform dynamic casts using qobject_cast() - on QObject classes. The qobject_cast() function behaves similarly - to the standard C++ \c dynamic_cast(), with the advantages - that it doesn't require RTTI support and it works across dynamic - library boundaries. It attempts to cast its argument to the pointer - type specified in angle-brackets, returning a non-zero pointer if the - object is of the correct type (determined at run-time), or 0 - if the object's type is incompatible. - - For example, let's assume \c MyWidget inherits from QWidget and - is declared with the Q_OBJECT macro: - - \snippet doc/src/snippets/qtcast/qtcast.cpp 0 - - The \c obj variable, of type \c{QObject *}, actually refers to a - \c MyWidget object, so we can cast it appropriately: - - \snippet doc/src/snippets/qtcast/qtcast.cpp 1 - - The cast from QObject to QWidget is successful, because the - object is actually a \c MyWidget, which is a subclass of QWidget. - Since we know that \c obj is a \c MyWidget, we can also cast it to - \c{MyWidget *}: - - \snippet doc/src/snippets/qtcast/qtcast.cpp 2 - - The cast to \c MyWidget is successful because qobject_cast() - makes no distinction between built-in Qt types and custom types. - - \snippet doc/src/snippets/qtcast/qtcast.cpp 3 - \snippet doc/src/snippets/qtcast/qtcast.cpp 4 - - The cast to QLabel, on the other hand, fails. The pointer is then - set to 0. This makes it possible to handle objects of different - types differently at run-time, based on the type: - - \snippet doc/src/snippets/qtcast/qtcast.cpp 5 - \snippet doc/src/snippets/qtcast/qtcast.cpp 6 - - While it is possible to use QObject as a base class without the - Q_OBJECT macro and without meta-object code, neither signals - and slots nor the other features described here will be available - if the Q_OBJECT macro is not used. From the meta-object - system's point of view, a QObject subclass without meta code is - equivalent to its closest ancestor with meta-object code. This - means for example, that QMetaObject::className() will not return - the actual name of your class, but the class name of this - ancestor. - - Therefore, we strongly recommend that all subclasses of QObject - use the Q_OBJECT macro regardless of whether or not they - actually use signals, slots, and properties. - - \sa QMetaObject, {Qt's Property System}, {Signals and Slots} -*/ diff --git a/doc/src/core/objectmodel/object.qdoc b/doc/src/core/objectmodel/object.qdoc deleted file mode 100644 index 535c4cc8f2..0000000000 --- a/doc/src/core/objectmodel/object.qdoc +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page object.html - \title Object Model - \ingroup qt-basic-concepts - \brief A description of the powerful features made possible by Qt's dynamic object model. - - The standard C++ object model provides very efficient runtime - support for the object paradigm. But its static nature is - inflexibile in certain problem domains. Graphical user interface - programming is a domain that requires both runtime efficiency and - a high level of flexibility. Qt provides this, by combining the - speed of C++ with the flexibility of the Qt Object Model. - - Qt adds these features to C++: - - \list - \o a very powerful mechanism for seamless object - communication called \l{signals and slots} - \o queryable and designable \l{Qt's Property System}{object - properties} - \o powerful \l{The Event System}{events and event filters} - \o contextual \l{i18n}{string translation for internationalization} - \o sophisticated interval driven \l timers that make it possible - to elegantly integrate many tasks in an event-driven GUI - \o hierarchical and queryable \l{Object Trees & Ownership}{object - trees} that organize object ownership in a natural way - \o guarded pointers (QPointer) that are automatically - set to 0 when the referenced object is destroyed, unlike normal C++ - pointers which become dangling pointers when their objects are destroyed - \o a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across - library boundaries. - \endlist - - Many of these Qt features are implemented with standard C++ - techniques, based on inheritance from QObject. Others, like the - object communication mechanism and the dynamic property system, - require the \l{Meta-Object System} provided - by Qt's own \l{moc}{Meta-Object Compiler (moc)}. - - The meta-object system is a C++ extension that makes the language - better suited to true component GUI programming. Although - templates can be used to extend C++, the meta-object system - provides benefits using standard C++ that cannot be achieved with - templates; see \l{Why Doesn't Qt Use Templates for Signals and - Slots?} - - \section1 Important Classes - - These classes form the basis of the Qt Object Model. - - \annotatedlist objectmodel - - \target Identity vs Value - \section1 Qt Objects: Identity vs Value - - Some of the added features listed above for the Qt Object Model, - require that we think of Qt Objects as identities, not values. - Values are copied or assigned; identities are cloned. Cloning - means to create a new identity, not an exact copy of the old - one. For example, twins have different identities. They may look - identical, but they have different names, different locations, and - may have completely different social networks. - - Then cloning an identity is a more complex operation than copying - or assigning a value. We can see what this means in the Qt Object - Model. - - \bold{A Qt Object...} - - \list - - \o might have a unique \l{QObject::objectName()}. If we copy a Qt - Object, what name should we give the copy? - - \o has a location in an \l{Object Trees & Ownership} - {object hierarchy}. If we copy a Qt Object, where should the copy - be located? - - \o can be connected to other Qt Objects to emit signals to them or - to receive signals emitted by them. If we copy a Qt Object, how - should we transfer these connections to the copy? - - \o can have \l{Qt's Property System} {new properties} added to it - at runtime that are not declared in the C++ class. If we copy a Qt - Object, should the copy include the properties that were added to - the original? - - \endlist - - For these reasons, Qt Objects should be treated as identities, not - as values. Identities are cloned, not copied or assigned, and - cloning an identity is a more complex operation than copying or - assigning a value. Therefore, QObject and all subclasses of - QObject (direct or indirect) have their \l{No copy constructor} - {copy constructor and assignment operator} disabled. - - */ diff --git a/doc/src/core/objectmodel/objecttrees.qdoc b/doc/src/core/objectmodel/objecttrees.qdoc deleted file mode 100644 index d8f9501748..0000000000 --- a/doc/src/core/objectmodel/objecttrees.qdoc +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page objecttrees.html - \title Object Trees & Ownership - \ingroup qt-basic-concepts - \brief Information about the parent-child pattern used to describe - object ownership in Qt. - - \section1 Overview - - \link QObject QObjects\endlink organize themselves in object trees. - When you create a QObject with another object as parent, it's added to - the parent's \link QObject::children() children() \endlink list, and - is deleted when the parent is. It turns out that this approach fits - the needs of GUI objects very well. For example, a \l QShortcut - (keyboard shortcut) is a child of the relevant window, so when the - user closes that window, the shorcut is deleted too. - - \l QWidget, the base class of everything that appears on the screen, - extends the parent-child relationship. A child normally also becomes a - child widget, i.e. it is displayed in its parent's coordinate system - and is graphically clipped by its parent's boundaries. For example, - when the application deletes a message box after it has been - closed, the message box's buttons and label are also deleted, just as - we'd want, because the buttons and label are children of the message - box. - - You can also delete child objects yourself, and they will remove - themselves from their parents. For example, when the user removes a - toolbar it may lead to the application deleting one of its \l QToolBar - objects, in which case the tool bar's \l QMainWindow parent would - detect the change and reconfigure its screen space accordingly. - - The debugging functions \l QObject::dumpObjectTree() and \l - QObject::dumpObjectInfo() are often useful when an application looks or - acts strangely. - - \target note on the order of construction/destruction of QObjects - \section1 Construction/Destruction Order of QObjects - - When \l {QObject} {QObjects} are created on the heap (i.e., created - with \e new), a tree can be constructed from them in any order, and - later, the objects in the tree can be destroyed in any order. When any - QObject in the tree is deleted, if the object has a parent, the - destructor automatically removes the object from its parent. If the - object has children, the destructor automatically deletes each - child. No QObject is deleted twice, regardless of the order of - destruction. - - When \l {QObject} {QObjects} are created on the stack, the same - behavior applies. Normally, the order of destruction still doesn't - present a problem. Consider the following snippet: - - \snippet doc/src/snippets/code/doc_src_objecttrees.cpp 0 - - The parent, \c window, and the child, \c quit, are both \l {QObject} - {QObjects} because QPushButton inherits QWidget, and QWidget inherits - QObject. This code is correct: the destructor of \c quit is \e not - called twice because the C++ language standard \e {(ISO/IEC 14882:2003)} - specifies that destructors of local objects are called in the reverse - order of their constructors. Therefore, the destructor of - the child, \c quit, is called first, and it removes itself from its - parent, \c window, before the destructor of \c window is called. - - But now consider what happens if we swap the order of construction, as - shown in this second snippet: - - \snippet doc/src/snippets/code/doc_src_objecttrees.cpp 1 - - In this case, the order of destruction causes a problem. The parent's - destructor is called first because it was created last. It then calls - the destructor of its child, \c quit, which is incorrect because \c - quit is a local variable. When \c quit subsequently goes out of scope, - its destructor is called again, this time correctly, but the damage has - already been done. -*/ diff --git a/doc/src/core/objectmodel/properties.qdoc b/doc/src/core/objectmodel/properties.qdoc deleted file mode 100644 index 0350f19be4..0000000000 --- a/doc/src/core/objectmodel/properties.qdoc +++ /dev/null @@ -1,273 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page properties.html - \title The Property System - \brief An overview of Qt's property system. - - \ingroup qt-basic-concepts - \target Qt's Property System - - Qt provides a sophisticated property system similar to the ones - supplied by some compiler vendors. However, as a compiler- and - platform-independent library, Qt does not rely on non-standard - compiler features like \c __property or \c [property]. The Qt - solution works with \e any standard C++ compiler on every platform - Qt supports. It is based on the \l {Meta-Object System} that also - provides inter-object communication via \l{signals and slots}. - - \section1 Requirements for Declaring Properties - - To declare a property, use the \l {Q_PROPERTY()} {Q_PROPERTY()} - macro in a class that inherits QObject. - - \snippet doc/src/snippets/code/doc_src_properties.cpp 0 - - Here are some typical examples of property declarations taken from - class QWidget. - - \snippet doc/src/snippets/code/doc_src_properties.cpp 1 - - A property behaves like a class data member, but it has additional - features accessible through the \l {Meta-Object System}. - - \list - - \o A \c READ accessor function is required. It is for reading the - property value. Ideally, a const function is used for this purpose, - and it must return either the property's type or a pointer or - reference to that type. e.g., QWidget::focus is a read-only property - with \c READ function, QWidget::hasFocus(). - - \o A \c WRITE accessor function is optional. It is for setting the - property value. It must return void and must take exactly one - argument, either of the property's type or a pointer or reference - to that type. e.g., QWidget::enabled has the \c WRITE function - QWidget::setEnabled(). Read-only properties do not need \c WRITE - functions. e.g., QWidget::focus has no \c WRITE function. - - \o A \c RESET function is optional. It is for setting the property - back to its context specific default value. e.g., QWidget::cursor - has the typical \c READ and \c WRITE functions, QWidget::cursor() - and QWidget::setCursor(), and it also has a \c RESET function, - QWidget::unsetCursor(), since no call to QWidget::setCursor() can - mean \e {reset to the context specific cursor}. The \c RESET - function must return void and take no parameters. - - \o A \c NOTIFY signal is optional. If defined, it should specify one - existing signal in that class that is emitted whenever the value - of the property changes. - - \o A \c REVISION number is optional. If included, it defines the - the property and its notifier signal to be used in a particular - revision of the API that is exposed to QML. - - \o The \c DESIGNABLE attribute indicates whether the property - should be visible in the property editor of GUI design tool (e.g., - \l {Qt Designer}). Most properties are \c DESIGNABLE (default - true). Instead of true or false, you can specify a boolean - member function. - - \o The \c SCRIPTABLE attribute indicates whether this property - should be accessible by a scripting engine (default true). - Instead of true or false, you can specify a boolean member - function. - - \o The \c STORED attribute indicates whether the property should - be thought of as existing on its own or as depending on other - values. It also indicates whether the property value must be saved - when storing the object's state. Most properties are \c STORED - (default true), but e.g., QWidget::minimumWidth() has \c STORED - false, because its value is just taken from the width component - of property QWidget::minimumSize(), which is a QSize. - - \o The \c USER attribute indicates whether the property is - designated as the user-facing or user-editable property for the - class. Normally, there is only one \c USER property per class - (default false). e.g., QAbstractButton::checked is the user - editable property for (checkable) buttons. Note that QItemDelegate - gets and sets a widget's \c USER property. - - \o The presence of the \c CONSTANT attibute indicates that the property - value is constant. For a given object instance, the READ method of a - constant property must return the same value every time it is called. This - constant value may be different for different instances of the object. A - constant property cannot have a WRITE method or a NOTIFY signal. - - \o The presence of the \c FINAL attribute indicates that the property - will not be overridden by a derived class. This can be used for performance - optimizations in some cases, but is not enforced by moc. Care must be taken - never to override a \c FINAL property. - - \endlist - - The \c READ, \c WRITE, and \c RESET functions can be inherited. - They can also be virtual. When they are inherited in classes where - multiple inheritance is used, they must come from the first - inherited class. - - The property type can be any type supported by QVariant, or it can - be a user-defined type. In this example, class QDate is considered - to be a user-defined type. - - \snippet doc/src/snippets/code/doc_src_properties.cpp 2 - - Because QDate is user-defined, you must include the \c{} - header file with the property declaration. - - For QMap, QList, and QValueList properties, the property value is - a QVariant whose value is the entire list or map. Note that the - Q_PROPERTY string cannot contain commas, because commas separate - macro arguments. Therefore, you must use \c QMap as the property - type instead of \c QMap. For consistency, also - use \c QList and \c QValueList instead of \c QList and - \c QValueList. - - \section1 Reading and Writing Properties with the Meta-Object System - - A property can be read and written using the generic functions - QObject::property() and QObject::setProperty(), without knowing - anything about the owning class except the property's name. In - the code snippet below, the call to QAbstractButton::setDown() and - the call to QObject::setProperty() both set property "down". - - \snippet doc/src/snippets/code/doc_src_properties.cpp 3 - - Accessing a property through its \c WRITE accessor is the better - of the two, because it is faster and gives better diagnostics at - compile time, but setting the property this way requires that you - know about the class at compile time. Accessing properties by name - lets you access classes you don't know about at compile time. You - can \e discover a class's properties at run time by querying its - QObject, QMetaObject, and \l {QMetaProperty} {QMetaProperties}. - - \snippet doc/src/snippets/code/doc_src_properties.cpp 4 - - In the above snippet, QMetaObject::property() is used to get \l - {QMetaProperty} {metadata} about each property defined in some - unknown class. The property name is fetched from the metadata and - passed to QObject::property() to get the \l {QVariant} {value} of - the property in the current \l {QObject}{object}. - - \section1 A Simple Example - - Suppose we have a class MyClass, which is derived from QObject and - which uses the Q_OBJECT macro in its private section. We want to - declare a property in MyClass to keep track of a priorty - value. The name of the property will be \e priority, and its type - will be an enumeration type named \e Priority, which is defined in - MyClass. - - We declare the property with the Q_PROPERTY() macro in the private - section of the class. The required \c READ function is named \c - priority, and we include a \c WRITE function named \c setPriority. - The enumeration type must be registered with the \l {Meta-Object - System} using the Q_ENUMS() macro. Registering an enumeration type - makes the enumerator names available for use in calls to - QObject::setProperty(). We must also provide our own declarations - for the \c READ and \c WRITE functions. The declaration of MyClass - then might look like this: - - \snippet doc/src/snippets/code/doc_src_properties.cpp 5 - - The \c READ function is const and returns the property type. The - \c WRITE function returns void and has exactly one parameter of - the property type. The meta-object compiler enforces these - requirements. - - Given a pointer to an instance of MyClass or a pointer to a - QObject that is an instance of MyClass, we have two ways to set - its priority property: - - \snippet doc/src/snippets/code/doc_src_properties.cpp 6 - - In the example, the enumeration type that is the property type is - declared in MyClass and registered with the \l{Meta-Object System} - using the Q_ENUMS() macro. This makes the enumeration values - available as strings for use as in the call to setProperty(). Had - the enumeration type been declared in another class, its fully - qualified name (i.e., OtherClass::Priority) would be required, and - that other class would also have to inherit QObject and register - the enumeration type there using the Q_ENUMS() macro. - - A similar macro, Q_FLAGS(), is also available. Like Q_ENUMS(), it - registers an enumeration type, but it marks the type as being a - set of \e flags, i.e. values that can be OR'd together. An I/O - class might have enumeration values \c Read and \c Write and then - QObject::setProperty() could accept \c{Read | Write}. Q_FLAGS() - should be used to register this enumeration type. - - \section1 Dynamic Properties - - QObject::setProperty() can also be used to add \e new properties - to an instance of a class at runtime. When it is called with a - name and a value, if a property with the given name exists in the - QObject, and if the given value is compatible with the property's - type, the value is stored in the property, and true is returned. - If the value is \e not compatible with the property's type, the - property is \e not changed, and false is returned. But if the - property with the given name doesn't exist in the QObject (i.e., - if it wasn't declared with Q_PROPERTY(), a new property with the - given name and value is automatically added to the QObject, but - false is still returned. This means that a return of false can't - be used to determine whether a particular property was actually - set, unless you know in advance that the property already exists - in the QObject. - - Note that \e dynamic properties are added on a per instance basis, - i.e., they are added to QObject, not QMetaObject. A property can - be removed from an instance by passing the property name and an - invalid QVariant value to QObject::setProperty(). The default - constructor for QVariant constructs an invalid QVariant. - - Dynamic properties can be queried with QObject::property(), just - like properties declared at compile time with Q_PROPERTY(). - - \sa {Meta-Object System}, {Signals and Slots} - - \section1 Properties and Custom Types - - Custom types used by properties need to be registered using the - Q_DECLARE_METATYPE() macro so that their values can be stored in - QVariant objects. This makes them suitable for use with both - static properties declared using the Q_PROPERTY() macro in class - definitions and dynamic properties created at run-time. - - \sa Q_DECLARE_METATYPE(), QMetaType, QVariant - - \section1 Adding Additional Information to a Class - - Connected to the property system is an additional macro, - Q_CLASSINFO(), that can be used to attach additional - \e{name}--\e{value} pairs to a class's meta-object, for example: - - \snippet doc/src/snippets/code/doc_src_properties.cpp 7 - - Like other meta-data, class information is accessible at run-time - through the meta-object; see QMetaObject::classInfo() for details. -*/ diff --git a/doc/src/core/objectmodel/signalsandslots.qdoc b/doc/src/core/objectmodel/signalsandslots.qdoc deleted file mode 100644 index f976e74c7d..0000000000 --- a/doc/src/core/objectmodel/signalsandslots.qdoc +++ /dev/null @@ -1,468 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page signalsandslots.html - \title Signals & Slots - \ingroup qt-basic-concepts - \brief An overview of Qt's signals and slots inter-object - communication mechanism. - - Signals and slots are used for communication between objects. The - signals and slots mechanism is a central feature of Qt and - probably the part that differs most from the features provided by - other frameworks. - - \tableofcontents - - \section1 Introduction - - In GUI programming, when we change one widget, we often want - another widget to be notified. More generally, we want objects of - any kind to be able to communicate with one another. For example, - if a user clicks a \gui{Close} button, we probably want the - window's \l{QWidget::close()}{close()} function to be called. - - Older toolkits achieve this kind of communication using - callbacks. A callback is a pointer to a function, so if you want - a processing function to notify you about some event you pass a - pointer to another function (the callback) to the processing - function. The processing function then calls the callback when - appropriate. Callbacks have two fundamental flaws: Firstly, they - are not type-safe. We can never be certain that the processing - function will call the callback with the correct arguments. - Secondly, the callback is strongly coupled to the processing - function since the processing function must know which callback - to call. - - \section1 Signals and Slots - - In Qt, we have an alternative to the callback technique: We use - signals and slots. A signal is emitted when a particular event - occurs. Qt's widgets have many predefined signals, but we can - always subclass widgets to add our own signals to them. A slot - is a function that is called in response to a particular signal. - Qt's widgets have many pre-defined slots, but it is common - practice to subclass widgets and add your own slots so that you - can handle the signals that you are interested in. - - \img abstract-connections.png - \omit - \caption An abstract view of some signals and slots connections - \endomit - - The signals and slots mechanism is type safe: The signature of a - signal must match the signature of the receiving slot. (In fact a - slot may have a shorter signature than the signal it receives - because it can ignore extra arguments.) Since the signatures are - compatible, the compiler can help us detect type mismatches. - Signals and slots are loosely coupled: A class which emits a - signal neither knows nor cares which slots receive the signal. - Qt's signals and slots mechanism ensures that if you connect a - signal to a slot, the slot will be called with the signal's - parameters at the right time. Signals and slots can take any - number of arguments of any type. They are completely type safe. - - All classes that inherit from QObject or one of its subclasses - (e.g., QWidget) can contain signals and slots. Signals are emitted by - objects when they change their state in a way that may be interesting - to other objects. This is all the object does to communicate. It - does not know or care whether anything is receiving the signals it - emits. This is true information encapsulation, and ensures that the - object can be used as a software component. - - Slots can be used for receiving signals, but they are also normal - member functions. Just as an object does not know if anything receives - its signals, a slot does not know if it has any signals connected to - it. This ensures that truly independent components can be created with - Qt. - - You can connect as many signals as you want to a single slot, and a - signal can be connected to as many slots as you need. It is even - possible to connect a signal directly to another signal. (This will - emit the second signal immediately whenever the first is emitted.) - - Together, signals and slots make up a powerful component programming - mechanism. - - \section1 A Small Example - - A minimal C++ class declaration might read: - - \snippet doc/src/snippets/signalsandslots/signalsandslots.h 0 - - A small QObject-based class might read: - - \snippet doc/src/snippets/signalsandslots/signalsandslots.h 1 - \codeline - \snippet doc/src/snippets/signalsandslots/signalsandslots.h 2 - \snippet doc/src/snippets/signalsandslots/signalsandslots.h 3 - - The QObject-based version has the same internal state, and provides - public methods to access the state, but in addition it has support - for component programming using signals and slots. This class can - tell the outside world that its state has changed by emitting a - signal, \c{valueChanged()}, and it has a slot which other objects - can send signals to. - - All classes that contain signals or slots must mention - Q_OBJECT at the top of their declaration. They must also derive - (directly or indirectly) from QObject. - - Slots are implemented by the application programmer. - Here is a possible implementation of the \c{Counter::setValue()} - slot: - - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 0 - - The \c{emit} line emits the signal \c valueChanged() from the - object, with the new value as argument. - - In the following code snippet, we create two \c Counter objects - and connect the first object's \c valueChanged() signal to the - second object's \c setValue() slot using QObject::connect(): - - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 1 - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 2 - \codeline - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 3 - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 4 - - Calling \c{a.setValue(12)} makes \c{a} emit a - \c{valueChanged(12)} signal, which \c{b} will receive in its - \c{setValue()} slot, i.e. \c{b.setValue(12)} is called. Then - \c{b} emits the same \c{valueChanged()} signal, but since no slot - has been connected to \c{b}'s \c{valueChanged()} signal, the - signal is ignored. - - Note that the \c{setValue()} function sets the value and emits - the signal only if \c{value != m_value}. This prevents infinite - looping in the case of cyclic connections (e.g., if - \c{b.valueChanged()} were connected to \c{a.setValue()}). - - By default, for every connection you make, a signal is emitted; - two signals are emitted for duplicate connections. You can break - all of these connections with a single disconnect() call. - If you pass the Qt::UniqueConnection \a type, the connection will only - be made if it is not a duplicate. If there is already a duplicate - (exact same signal to the exact same slot on the same objects), - the connection will fail and connect will return false - - This example illustrates that objects can work together without needing to - know any information about each other. To enable this, the objects only - need to be connected together, and this can be achieved with some simple - QObject::connect() function calls, or with \c{uic}'s - \l{Using a Designer UI File in Your Application#Automatic Connections} - {automatic connections} feature. - - \section1 Building the Example - - The C++ preprocessor changes or removes the \c{signals}, - \c{slots}, and \c{emit} keywords so that the compiler is - presented with standard C++. - - By running the \l moc on class definitions that contain signals - or slots, a C++ source file is produced which should be compiled - and linked with the other object files for the application. If - you use \l qmake, the makefile rules to automatically invoke \c - moc will be added to your project's makefile. - - \section1 Signals - - Signals are emitted by an object when its internal state has changed - in some way that might be interesting to the object's client or owner. - Signals are public access functions and can be emitted from anywhere, - but we recommend to only emit them from the class that defines the - signal and its subclasses. - - When a signal is emitted, the slots connected to it are usually - executed immediately, just like a normal function call. When this - happens, the signals and slots mechanism is totally independent of - any GUI event loop. Execution of the code following the \c emit - statement will occur once all slots have returned. The situation is - slightly different when using \l{Qt::ConnectionType}{queued - connections}; in such a case, the code following the \c emit keyword - will continue immediately, and the slots will be executed later. - - If several slots are connected to one signal, the slots will be - executed one after the other, in the order they have been connected, - when the signal is emitted. - - Signals are automatically generated by the \l moc and must not be - implemented in the \c .cpp file. They can never have return types - (i.e. use \c void). - - A note about arguments: Our experience shows that signals and slots - are more reusable if they do not use special types. If - QScrollBar::valueChanged() were to use a special type such as the - hypothetical QScrollBar::Range, it could only be connected to - slots designed specifically for QScrollBar. Connecting different - input widgets together would be impossible. - - \section1 Slots - - A slot is called when a signal connected to it is emitted. Slots are - normal C++ functions and can be called normally; their only special - feature is that signals can be connected to them. - - Since slots are normal member functions, they follow the normal C++ - rules when called directly. However, as slots, they can be invoked - by any component, regardless of its access level, via a signal-slot - connection. This means that a signal emitted from an instance of an - arbitrary class can cause a private slot to be invoked in an instance - of an unrelated class. - - You can also define slots to be virtual, which we have found quite - useful in practice. - - Compared to callbacks, signals and slots are slightly slower - because of the increased flexibility they provide, although the - difference for real applications is insignificant. In general, - emitting a signal that is connected to some slots, is - approximately ten times slower than calling the receivers - directly, with non-virtual function calls. This is the overhead - required to locate the connection object, to safely iterate over - all connections (i.e. checking that subsequent receivers have not - been destroyed during the emission), and to marshall any - parameters in a generic fashion. While ten non-virtual function - calls may sound like a lot, it's much less overhead than any \c - new or \c delete operation, for example. As soon as you perform a - string, vector or list operation that behind the scene requires - \c new or \c delete, the signals and slots overhead is only - responsible for a very small proportion of the complete function - call costs. The same is true whenever you do a system call in a slot; - or indirectly call more than ten functions. - The simplicity and flexibility of the signals and slots mechanism is - well worth the overhead, which your users won't even notice. - - Note that other libraries that define variables called \c signals - or \c slots may cause compiler warnings and errors when compiled - alongside a Qt-based application. To solve this problem, \c - #undef the offending preprocessor symbol. - - \section1 Meta-Object Information - - The meta-object compiler (\l moc) parses the class declaration in - a C++ file and generates C++ code that initializes the - meta-object. The meta-object contains the names of all the signal - and slot members, as well as pointers to these functions. - - The meta-object contains additional information such as the - object's \link QObject::className() class name\endlink. You can - also check if an object \link QObject::inherits() - inherits\endlink a specific class, for example: - - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 5 - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 6 - - The meta-object information is also used by qobject_cast(), which - is similar to QObject::inherits() but is less error-prone: - - \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 7 - - See \l{Meta-Object System} for more information. - - \section1 A Real Example - - Here is a simple commented example of a widget. - - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 0 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 1 - \codeline - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 2 - \codeline - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 3 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 4 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 5 - - \c LcdNumber inherits QObject, which has most of the signal-slot - knowledge, via QFrame and QWidget. It is somewhat similar to the - built-in QLCDNumber widget. - - The Q_OBJECT macro is expanded by the preprocessor to declare - several member functions that are implemented by the \c{moc}; if - you get compiler errors along the lines of "undefined reference - to vtable for \c{LcdNumber}", you have probably forgotten to - \l{moc}{run the moc} or to include the moc output in the link - command. - - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 6 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 7 - - It's not obviously relevant to the moc, but if you inherit - QWidget you almost certainly want to have the \c parent argument - in your constructor and pass it to the base class's constructor. - - Some destructors and member functions are omitted here; the \c - moc ignores member functions. - - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 8 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 9 - - \c LcdNumber emits a signal when it is asked to show an impossible - value. - - If you don't care about overflow, or you know that overflow - cannot occur, you can ignore the \c overflow() signal, i.e. don't - connect it to any slot. - - If on the other hand you want to call two different error - functions when the number overflows, simply connect the signal to - two different slots. Qt will call both (in the order they were connected). - - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 10 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 11 - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 12 - \codeline - \snippet doc/src/snippets/signalsandslots/lcdnumber.h 13 - - A slot is a receiving function used to get information about - state changes in other widgets. \c LcdNumber uses it, as the code - above indicates, to set the displayed number. Since \c{display()} - is part of the class's interface with the rest of the program, - the slot is public. - - Several of the example programs connect the - \l{QScrollBar::valueChanged()}{valueChanged()} signal of a - QScrollBar to the \c display() slot, so the LCD number - continuously shows the value of the scroll bar. - - Note that \c display() is overloaded; Qt will select the - appropriate version when you connect a signal to the slot. With - callbacks, you'd have to find five different names and keep track - of the types yourself. - - Some irrelevant member functions have been omitted from this - example. - - \section1 Signals And Slots With Default Arguments - - The signatures of signals and slots may contain arguments, and the - arguments can have default values. Consider QObject::destroyed(): - - \code - void destroyed(QObject* = 0); - \endcode - - When a QObject is deleted, it emits this QObject::destroyed() - signal. We want to catch this signal, wherever we might have a - dangling reference to the deleted QObject, so we can clean it up. - A suitable slot signature might be: - - \code - void objectDestroyed(QObject* obj = 0); - \endcode - - To connect the signal to the slot, we use QObject::connect(). - There are several ways to connect signal and slots. The first is to use - function pointers: - \code - connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); - \endcode - - There are several advantages to using connect() with function pointers. - First, it allows the compiler to check that the signal's arguments are - compatible with the slot's arguments. Arguments can also be implicitly - converted by the compiler, if needed. - - You can also connect to functors or C++11 lamdas: - - \code - connect(sender, &QObject::destroyed, [=](){ this->m_objects.remove(sender); }); - \endcode - - Note that if your compiler does not support C++11 variadic templates, - this syntax only works if the signal and slot have 6 arguments or less. - - The other way to connect a signal to a slot is to use QObject::connect() - and the \c{SIGNAL} and \c{SLOT} macros. - The rule about whether to - include arguments or not in the \c{SIGNAL()} and \c{SLOT()} - macros, if the arguments have default values, is that the - signature passed to the \c{SIGNAL()} macro must \e not have fewer - arguments than the signature passed to the \c{SLOT()} macro. - - All of these would work: - \code - connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*))); - connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed())); - connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed())); - \endcode - But this one won't work: - \code - connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*))); - \endcode - - ...because the slot will be expecting a QObject that the signal - will not send. This connection will report a runtime error. - - Note that signal and slot arguments are not checked by the compiler when - using this QObject::connect() overload. - - \section1 Advanced Signals and Slots Usage - - For cases where you may require information on the sender of the - signal, Qt provides the QObject::sender() function, which returns - a pointer to the object that sent the signal. - - The QSignalMapper class is provided for situations where many - signals are connected to the same slot and the slot needs to - handle each signal differently. - - Suppose you have three push buttons that determine which file you - will open: "Tax File", "Accounts File", or "Report File". - - In order to open the correct file, you use QSignalMapper::setMapping() to - map all the clicked() signals to a QSignalMapper object. Then you connect - the file's QPushButton::clicked() signal to the QSignalMapper::map() slot. - - \snippet doc/src/snippets/signalmapper/filereader.cpp 0 - - Then, you connect the \l{QSignalMapper::}{mapped()} signal to - \c{readFile()} where a different file will be opened, depending on - which push button is pressed. - - \snippet doc/src/snippets/signalmapper/filereader.cpp 1 - - \sa {Meta-Object System}, {Qt's Property System} - - \target 3rd Party Signals and Slots - \section2 Using Qt with 3rd Party Signals and Slots - - It is possible to use Qt with a 3rd party signal/slot mechanism. - You can even use both mechanisms in the same project. Just add the - following line to your qmake project (.pro) file. - - \snippet doc/src/snippets/code/doc_src_containers.cpp 22 - - It tells Qt not to define the moc keywords \c{signals}, \c{slots}, - and \c{emit}, because these names will be used by a 3rd party - library, e.g. Boost. Then to continue using Qt signals and slots - with the \c{no_keywords} flag, simply replace all uses of the Qt - moc keywords in your sources with the corresponding Qt macros - Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT. -*/ diff --git a/doc/src/core/qtcore.qdoc b/doc/src/core/qtcore.qdoc deleted file mode 100644 index 0d1654c9f0..0000000000 --- a/doc/src/core/qtcore.qdoc +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \module QtCore - \title QtCore Module - \ingroup modules - - \keyword QtCore - - \brief The QtCore module contains core non-GUI functionality. - - All other Qt modules rely on this module. To include the - definitions of the module's classes, use the following directive: - - \snippet doc/src/snippets/code/doc_src_qtcore.cpp 0 -*/ - diff --git a/doc/src/core/threads-basics.qdoc b/doc/src/core/threads-basics.qdoc deleted file mode 100644 index 547c7fc50c..0000000000 --- a/doc/src/core/threads-basics.qdoc +++ /dev/null @@ -1,572 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page thread-basics.html - \ingroup tutorials - \startpage {index.html}{Qt Reference Documentation} - - \title Threading Basics - \brief An introduction to threads - - \section1 What Are Threads? - - Threads are about doing things in parallel, just like processes. So how do - threads differ from processes? While you are making calculations on a - spreadsheet, there may also be a media player running on the same desktop - playing your favorite song. Here is an example of two processes working in - parallel: one running the spreadsheet program; one running a media player. - Multitasking is a well known term for this. A closer look at the media - player reveals that there are again things going on in parallel within one - single process. While the media player is sending music to the audio driver, - the user interface with all its bells and whistles is being constantly - updated. This is what threads are for \mdash concurrency within one single - process. - - So how is concurrency implemented? Parallel work on single core CPUs is an - illusion which is somewhat similar to the illusion of moving images in - cinema. - For processes, the illusion is produced by interrupting the processor's - work on one process after a very short time. Then the processor moves on to - the next process. In order to switch between processes, the current program - counter is saved and the next processor's program counter is loaded. This - is not sufficient because the same needs to be done with registers and - certain architecture and OS specific data. - - Just as one CPU can power two or more processes, it is also possible to let - the CPU run on two different code segments of one single process. When a - process starts, it always executes one code segment and therefore the - process is said to have one thread. However, the program may decide to - start a second thread. Then, two different code sequences are processed - simultaneously inside one process. Concurrency is achieved on single core - CPUs by repeatedly saving program counters and registers then loading the - next thread's program counters and registers. No cooperation from the - program is required to cycle between the active threads. A thread may be in - any state when the switch to the next thread occurs. - - The current trend in CPU design is to have several cores. A typical - single-threaded application can make use of only one core. However, a - program with multiple threads can be assigned to multiple cores, making - things happen in a truly concurrent way. As a result, distributing work - to more than one thread can make a program run much faster on multicore - CPUs because additional cores can be used. - - \section2 GUI Thread and Worker Thread - - As mentioned, each program has one thread when it is started. This thread - is called the "main thread" (also known as the "GUI thread" in Qt - applications). The Qt GUI must run in this thread. All widgets and several - related classes, for example QPixmap, don't work in secondary threads. - A secondary thread is commonly referred to as a "worker thread" because it - is used to offload processing work from the main thread. - - \section2 Simultaneous Access to Data - - Each thread has its own stack, which means each thread has its own call - history and local variables. Unlike processes, threads share the same - address space. The following diagram shows how the building blocks of - threads are located in memory. Program counter and registers of inactive - threads are typically kept in kernel space. There is a shared copy of the - code and a separate stack for each thread. - - \image threadvisual-example.png "Thread visualization" - - If two threads have a pointer to the same object, it is possible that both - threads will access that object at the same time and this can potentially - destroy the object's integrity. It's easy to imagine the many things that - can go wrong when two methods of the same object are executed - simultaneously. - - Sometimes it is necessary to access one object from different threads; - for example, when objects living in different threads need to communicate. - Since threads use the same address space, it is easier and faster for - threads to exchange data than it is for processes. Data does not have to be - serialized and copied. Passing pointers is possible, but there must be a - strict coordination of what thread touches which object. Simultaneous - execution of operations on one object must be prevented. There are several - ways of achieving this and some of them are described below. - - So what can be done safely? All objects created in a thread can be used - safely within that thread provided that other threads don't have references - to them and objects don't have implicit coupling with other threads. Such - implicit coupling may happen when data is shared between instances as with - static members, singletons or global data. Familiarize yourself with the - concept of \l{Reentrancy and Thread-Safety}{thread safe and reentrant} - classes and functions. - - \section1 Using Threads - - There are basically two use cases for threads: - - \list - \o Make processing faster by making use of multicore processors. - \o Keep the GUI thread or other time critical threads responsive by - offloading long lasting processing or blocking calls to other threads. - \endlist - - \section2 When to Use Alternatives to Threads - - Developers need to be very careful with threads. It is easy to start other - threads, but very hard to ensure that all shared data remains consistent. - Problems are often hard to find because they may only show up once in a - while or only on specific hardware configurations. Before creating threads - to solve certain problems, possible alternatives should be considered. - - \table - \header - \o Alternative - \o Comment - \row - \o QEventLoop::processEvents() - \o Calling QEventLoop::processEvents() repeatedly during a - time-consuming calculation prevents GUI blocking. However, this - solution doesn't scale well because the call to processEvents() may - occur too often, or not often enough, depending on hardware. - \row - \o QTimer - \o Background processing can sometimes be done conveniently using a - timer to schedule execution of a slot at some point in the future. - A timer with an interval of 0 will time out as soon as there are no - more events to process. - \row - \o QSocketNotifier QNetworkAccessManager QIODevice::readyRead() - \o This is an alternative to having one or multiple threads, each with - a blocking read on a slow network connection. As long as the - calculation in response to a chunk of network data can be executed - quickly, this reactive design is better than synchronous waiting in - threads. Reactive design is less error prone and energy efficient - than threading. In many cases there are also performance benefits. - \endtable - - In general, it is recommended to only use safe and tested paths and to - avoid introducing ad-hoc threading concepts. QtConcurrent provides an easy - interface for distributing work to all of the processor's cores. The - threading code is completely hidden in the QtConcurrent framework, so you - don't have to take care of the details. However, QtConcurrent can't be used - when communication with the running thread is needed, and it shouldn't be - used to handle blocking operations. - - \section2 Which Qt Thread Technology Should You Use? - - Sometimes you want to do more than just running a method in the context of - another thread. You may want to have an object which lives in another - thread that provides a service to the GUI thread. Maybe you want another - thread to stay alive forever to poll hardware ports and send a signal to - the GUI thread when something noteworthy has happened. Qt provides - different solutions for developing threaded applications. The right - solution depends on the purpose of the new thread as well as on the - thread's lifetime. - - \table - \header - \o Lifetime of thread - \o Development task - \o Solution - \row - \o One call - \o Run one method within another thread and quit the thread when the - method is finished. - \o Qt provides different solutions: - \list - \o Write a function and run it with QtConcurrent::run() - \o Derive a class from QRunnable and run it in the global thread - pool with QThreadPool::globalInstance()->start() - \o Derive a class from QThread, reimplement the QThread::run() - method and use QThread::start() to run it. - \endlist - - \row - \o One call - \o Operations are to be performed on all items of a container. - Processing should be performed using all available cores. A common - example is to produce thumbnails from a list of images. - \o QtConcurrent provides the \l{QtConcurrent::}{map()} function for - applying operations on every container element, - \l{QtConcurrent::}{filter()} for selecting container elements, and - the option of specifying a reduce function for combining the - remaining elements. - \row - \o One call - \o A long running operation has to be put in another thread. During the - course of processing, status information should be sent to the GUI - thread. - \o Use QThread, reimplement run and emit signals as needed. Connect the - signals to the GUI thread's slots using queued signal/slot - connections. - - \row - \o Permanent - \o Have an object living in another thread and let it perform different - tasks upon request. - This means communication to and from the worker thread is required. - \o Derive a class from QObject and implement the necessary slots and - signals, move the object to a thread with a running event loop and - communicate with the object over queued signal/slot connections. - \row - \o Permanent - \o Have an object living in another thread, let the object perform - repeated tasks such as polling a port and enable communication with - the GUI thread. - \o Same as above but also use a timer in the worker thread to implement - polling. However, the best solution for polling is to avoid it - completely. Sometimes using QSocketNotifier is an alternative. - \endtable - - - \section1 Qt Thread Basics - - QThread is a very convenient cross platform abstraction of native platform - threads. Starting a thread is very simple. Let us look at a short piece of - code that generates another thread which says hello in that thread and then - exits. - - \snippet examples/tutorials/threads/hellothread/hellothread.h 1 - - We derive a class from QThread and reimplement the \l{QThread::}{run()} - method. - - \snippet examples/tutorials/threads/hellothread/hellothread.cpp 1 - - The run method contains the code that will be run in a separate thread. In - this example, a message containing the thread ID will be printed. - QThread::start() will call the method in another thread. - - \snippet examples/tutorials/threads/hellothread/main.cpp 1 - - To start the thread, our thread object needs to be instantiated. The - \l{QThread::}{start()} method creates a new thread and calls the - reimplemented \l{QThread::}{run()} method in this new thread. Right after - \l{QThread::}{start()} is called, two program counters walk through the - program code. The main function starts with only the GUI thread running and - it should terminate with only the GUI thread running. Exiting the program - when another thread is still busy is a programming error, and therefore, - wait is called which blocks the calling thread until the - \l{QThread::}{run()} method has completed. - - This is the result of running the code: - - \badcode - hello from GUI thread 3079423696 - hello from worker thread 3076111216 - \endcode - - - \section2 QObject and Threads - - A QObject is said to have a \e{thread affinity} or, in other words, that it - lives in a certain thread. This means that, at creation time, QObject saves - a pointer to the current thread. This information becomes relevant when an - event is posted with \l{QCoreApplication::}{postEvent()}. The event will be - put in the corresponding thread's event loop. If the thread where the - QObject lives doesn't have an event loop, the event will never be delivered. - - To start an event loop, \l{QThread::}{exec()} must be called inside - \l{QThread::}{run()}. Thread affinity can be changed using - \l{QObject::}{moveToThread()}. - - As mentioned above, developers must always be careful when calling objects' - methods from other threads. Thread affinity does not change this situation. - Qt documentation marks several methods as thread-safe. - \l{QCoreApplication::}{postEvent()} is a noteworthy example. A thread-safe - method may be called from different threads simultaneously. - - In cases where there is usually no concurrent access to methods, calling - non-thread-safe methods of objects in other threads may work thousands - of times before a concurrent access occurs, causing unexpected behavior. - Writing test code does not entirely ensure thread correctness, but it is - still important. - On Linux, Valgrind and Helgrind can help detect threading errors. - - The anatomy of QThread is quite interesting: - - \list - \o QThread does not live in the new thread where \l{QThread::}{run()} is - executed. It lives in the old thread. - \o Most QThread methods are the thread's control interface and are meant to - be called from the old thread. Do not move this interface to the newly - created thread using \l{QObject::}{moveToThread()}; i.e., calling - \l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad - practice. - \o \l{QThread::}{exec()} and the static methods - \l{QThread::}{usleep()}, \l{QThread::}{msleep()}, - \l{QThread::}{sleep()} are meant to be called from the newly created - thread. - \o Additional members defined in the QThread subclass are - accessible by both threads. The developer is responsible for - coordinating access. A typical strategy is to set the members before - \l{QThread::}{start()} is called. Once the worker thread is running, - the main thread should not touch the additional members anymore. After - the worker has terminated, the main thread can access the additional - members again. This is a convenient strategy for passing parameters to a - thread before it is started as well as for collecting the result once it - has terminated. - \endlist - - A QObject's parent must always be in the same thread. This has a surprising - consequence for objects generated within the \l{QThread::}{run()} method: - - \code - void HelloThread::run() - { - QObject *object1 = new QObject(this); //error, parent must be in the same thread - QObject object2; // OK - QSharedPointer object3(new QObject); // OK - } - \endcode - - \section2 Using a Mutex to Protect the Integrity of Data - - A mutex is an object that has \l{QMutex::}{lock()} and \l{QMutex::}{unlock()} - methods and remembers if it is already locked. A mutex is designed to be - called from multiple threads. \l{QMutex::}{lock()} returns immediately if - the mutex is not locked. The next call from another thread will find the - mutex in a locked state and then \l{QMutex::}{lock()} will block the thread - until the other thread calls \l{QMutex::}{unlock()}. This functionality can - make sure that a code section will be executed by only one thread at a time. - - The following line sketches how a mutex can be used to make a method - thread-safe: - - \code - void Worker::work() - { - this->mutex.lock(); // first thread can pass, other threads will be blocked here - doWork(); - this->mutex.unlock(); - } - \endcode - - What happens if one thread does not unlock a mutex? The result can be a - frozen application. In the example above, an exception might be thrown and - \c{mutex.unlock()} will never be reached. To prevent problems like this, - QMutexLocker should be used. - - \code - void Worker::work() - { - QMutexLocker locker(&mutex); // Locks the mutex and unlocks when locker exits the scope - doWork(); - } - \endcode - - This looks easy, but mutexes introduce a new class of problems: deadlocks. - A deadlock happens when a thread waits for a mutex to become unlocked, but - the mutex remains locked because the owning thread is waiting for the first - thread to unlock it. The result is a frozen application. Mutexes can be - used to make a method thread safe. Most Qt methods aren't thread safe - because there is always a performance penalty when using mutexes. - - It isn't always possible to lock and unlock a mutex in a method. Sometimes - the need to lock spans several calls. For example, modifying a container - with an iterator requires a sequence of several calls which should not be - interrupted by other threads. In such a scenario, locking can be achieved - with a mutex that is kept outside of the object to be manipulated. With an - external mutex, the duration of locking can be adjusted to the needs of the - operation. One disadvantage is that external mutexes aid locking, but do - not enforce it because users of the object may forget to use it. - - \section2 Using the Event Loop to Prevent Data Corruption - - The event loops of Qt are a very valuable tool for inter-thread - communication. Every thread may have its own event loop. A safe way of - calling a slot in another thread is by placing that call in another - thread's event loop. This ensures that the target object finishes the - method that is currently running before another method is started. - - So how is it possible to put a method invocation in an event loop? Qt has - two ways of doing this. One way is via queued signal-slot connections; the - other way is to post an event with QCoreApplication::postEvent(). A queued - signal-slot connection is a signal slot connection that is executed - asynchronously. The internal implementation is based on posted events. The - arguments of the signal are put into the event loop and the signal method - returns immediately. - - The connected slot will be executed at a time which depends on what else is - in the event loop. - - Communication via the event loop eliminates the deadlock problem we face - when using mutexes. This is why we recommend using the event loop rather - than locking an object using a mutex. - - \section2 Dealing with Asynchronous Execution - - One way to obtain a worker thread's result is by waiting for the thread - to terminate. In many cases, however, a blocking wait isn't acceptable. The - alternative to a blocking wait are asynchronous result deliveries with - either posted events or queued signals and slots. This generates a certain - overhead because an operation's result does not appear on the next source - line, but in a slot located somewhere else in the source file. Qt - developers are used to working with this kind of asynchronous behavior - because it is much similar to the kind of event-driven programming used in - GUI applications. - - \section1 Examples - - This tutorial comes with examples for Qt's three basic ways of working with - threads. Two more examples show how to communicate with a running thread - and how a QObject can be placed in another thread, providing service to the - main thread. - - \list - \o Using QThread as shown \l{Qt thread basics}{above} - \o \l{Example 1: Using the Thread Pool}{Using the global QThreadPool} - \o \l{Example 2: Using QtConcurrent}{Using QtConcurrent} - \o \l{Example 3: Clock}{Communication with the GUI thread} - \o \l{Example 4: A Permanent Thread}{A permanent QObject in another thread - provides service to the main thread} - \endlist - - The following examples can all be compiled and run independently. The source can - be found in the examples directory: examples/tutorials/threads/ - - \section2 Example 1: Using the Thread Pool - - Creating and destroying threads frequently can be expensive. To avoid the - cost of thread creation, a thread pool can be used. A thread pool is a - place where threads can be parked and fetched. We can write the same - "hello thread" program as \l{Qt Thread Basics}{above} using the global - thread pool. We derive a class from QRunnable. The code we want to run in - another thread needs to be placed in the reimplemented QRunnable::run() - method. - - \snippet examples/tutorials/threads/hellothreadpool/hellothreadpool.cpp 1 - - We instantiate Work in main(), locate the global thread pool and use the - QThreadPool::start() method. Now the thread pool runs our worker in another - thread. Using the thread pool has a performance advantage because threads - are not destroyed after they have finished running. They are kept in a pool - and wait to be used again later. - - \section2 Example 2: Using QtConcurrent - - \snippet examples/tutorials/threads/helloconcurrent/helloconcurrent.cpp 1 - - We write a global function hello() to implement the work. QtConcurrent::run() - is used to run the function in another thread. The result is a QFuture. - QFuture provides a method called \l{QFuture::}{waitForFinished()}, which - blocks until the calculation is completed. The real power of QtConcurrent - becomes visible when data can be made available in a container. QtConcurrent - provides several functions that are able to process itemized data on all - available cores simultaneously. The use of QtConcurrent is very similar to - applying an STL algorithm to an STL container. - \l{examples-threadandconcurrent.html}{QtConcurrent Map} is a very short and - clear example about how a container of images can be scaled on all available - cores. The image scaling example uses the blocking variants of the functions - used. For every blocking function there is also a non-blocking, asynchronous - counterpart. Getting results asynchronously is implemented with QFuture and - QFutureWatcher. - - \section2 Example 3: Clock - - \image thread_clock.png "clock" - - We want to produce a clock application. The application has a GUI and a - worker thread. The worker thread checks every 10 milliseconds what time it - is. If the formatted time has changed, the result will be sent to the GUI - thread where it is displayed. - - Of course, this is an overly complicated way of designing a clock and, - actually, a separate thread is unnecessary. We would be better off placing - the timer in the main thread because the calculation made in the timer slot - is very short-lived. This example is purely for instructional use and shows - how to communicate from a worker thread to a GUI thread. Note that - communication in this direction is easy. We only need to add a signal - to QThread and make a queued signal/slot connection to the main thread. - Communication from the GUI to the worker thread is shown in the next - example. - - \snippet examples/tutorials/threads/clock/main.cpp 1 - - We've connected the \c clockThread with the label. The connection must be a - queued signal-slot connection because we want to put the call in the event - loop. - - \snippet examples/tutorials/threads/clock/clockthread.h 1 - - We have derived a class from QThread and declared the \c sendTime() signal. - - \snippet examples/tutorials/threads/clock/clockthread.cpp 1 - - The trickiest part of this example is that the timer is connected to its - slot via a direct connection. A default connection would produce a queued - signal-slot connection because the connected objects live in different - threads; remember that QThread does not live in the thread it creates. - - Still it is safe to access ClockThread::timerHit() from the worker thread - because ClockThread::timerHit() is private and only touches local variables - and a private member that isn't touched by public methods. - QDateTime::currentDateTime() isn't marked as thread-safe in Qt - documentation, however we can get away with using it in this small - example because we know that the QDateTime::currentDateTime() static - method isn't used in any other threads. - - \section2 Example 4: A Permanent Thread - - This example shows how it is possible to have a QObject in a worker thread - that accepts requests from the GUI thread, does polling using a timer and - continuously reports results back to the GUI thread. The actual work - including the polling must be implemented in a class derived from QObject. - We have called this class \c WorkerObject in the code shown below. The - thread-specific code is hidden in a class called \c Thread, derived from - QThread. - \c Thread has two additional public members. The \c launchWorker() member - takes the worker object and moves it to another thread with a started event - loop. - The call blocks for a very short moment until the thread creation operation - is completed, allowing the worker object to be used again on the next line. - The \c Thread class's code is short but somewhat involved, so we only show - how to use the class. - - \snippet examples/tutorials/threads/movedobject/main.cpp 1 - - QMetaObject::invokeMethod() calls a slot via the event loop. The worker - object's methods should not be called directly after the object has been - moved to another thread. We let the worker thread do some work and polling, - and use a timer to shut the application down after 3 seconds. Shutting the - worker down needs some care. We call \c{Thread::stop()} to exit the event - loop. We wait for the thread to terminate and, after this has occurred, we - delete the worker. - - \section1 Digging Deeper - - Threading is a very complicated subject. Qt offers more classes for - threading than we have presented in this tutorial. The following materials - can help you go into the subject in more depth: - - \list - \o Good video tutorials about threads with Qt can be found in the material - from the \l{Training Day at Qt Developer Days 2009}. - \o The \l{Thread Support in Qt} document is a good starting point into - the reference documentation. - \o Qt comes with several additional examples for - \l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}. - \o Several good books describe how to work with Qt threads. The most - extensive coverage can be found in \e{Advanced Qt Programming} by Mark - Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and - QtConcurrent. - \endlist -*/ diff --git a/doc/src/core/threads.qdoc b/doc/src/core/threads.qdoc deleted file mode 100644 index c38a7f3141..0000000000 --- a/doc/src/core/threads.qdoc +++ /dev/null @@ -1,705 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** GNU Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms -** and conditions contained in a signed written agreement between you -** and Nokia. -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \group thread - \title Threading Classes -*/ - -/*! - \page threads.html - \title Thread Support in Qt - \ingroup qt-basic-concepts - \brief A detailed discussion of thread handling in Qt. - - \ingroup frameworks-technologies - - \nextpage Starting Threads with QThread - - Qt provides thread support in the form of platform-independent - threading classes, a thread-safe way of posting events, and - signal-slot connections across threads. This makes it easy to - develop portable multithreaded Qt applications and take advantage - of multiprocessor machines. Multithreaded programming is also a - useful paradigm for performing time-consuming operations without - freezing the user interface of an application. - - Earlier versions of Qt offered an option to build the library - without thread support. Since Qt 4.0, threads are always enabled. - - \section1 Topics: - - \list - \o \l{Recommended Reading} - \o \l{The Threading Classes} - \o \l{Starting Threads with QThread} - \o \l{Synchronizing Threads} - \o \l{Reentrancy and Thread-Safety} - \o \l{Threads and QObjects} - \o \l{Concurrent Programming} - \o \l{Thread-Support in Qt Modules} - \endlist - - \section1 Recommended Reading - - This document is intended for an audience that has knowledge of, - and experience with, multithreaded applications. If you are new - to threading see our Recommended Reading list: - - \list - \o \l{Threads Primer: A Guide to Multithreaded Programming} - \o \l{Thread Time: The Multithreaded Programming Guide} - \o \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing} - \o \l{Win32 Multithreaded Programming} - \endlist - - \section1 The Threading Classes - - These classes are relevant to threaded applications. - - \annotatedlist thread - -\omit - \list - \o QThread provides the means to start a new thread. - \o QThreadStorage provides per-thread data storage. - \o QThreadPool manages a pool of threads that run QRunnable objects. - \o QRunnable is an abstract class representing a runnable object. - \o QMutex provides a mutual exclusion lock, or mutex. - \o QMutexLocker is a convenience class that automatically locks - and unlocks a QMutex. - \o QReadWriteLock provides a lock that allows simultaneous read access. - \o QReadLocker and QWriteLocker are convenience classes that automatically - lock and unlock a QReadWriteLock. - \o QSemaphore provides an integer semaphore (a generalization of a mutex). - \o QWaitCondition provides a way for threads to go to sleep until - woken up by another thread. - \o QAtomicInt provides atomic operations on integers. - \o QAtomicPointer provides atomic operations on pointers. - \endlist -\endomit - - \note Qt's threading classes are implemented with native threading APIs; - e.g., Win32 and pthreads. Therefore, they can be used with threads of the - same native API. -*/ - -/*! - \page threads-starting.html - \title Starting Threads with QThread - - \contentspage Thread Support in Qt - \nextpage Synchronizing Threads - - A QThread instance represents a thread and provides the means to - \l{QThread::start()}{start()} a thread, which will then execute the - reimplementation of QThread::run(). The \c run() implementation is for a - thread what the \c main() entry point is for the application. All code - executed in a call stack that starts in the \c run() function is executed - by the new thread, and the thread finishes when the function returns. - QThread emits signals to indicate that the thread started or finished - executing. - - \section1 Creating a Thread - - To create a thread, subclass QThread and reimplement its - \l{QThread::run()}{run()} function. For example: - - \snippet doc/src/snippets/threads/threads.h 0 - \codeline - \snippet doc/src/snippets/threads/threads.cpp 0 - \snippet doc/src/snippets/threads/threads.cpp 1 - \dots - \snippet doc/src/snippets/threads/threads.cpp 2 - - \section1 Starting a Thread - - Then, create an instance of the thread object and call - QThread::start(). Note that you must create the QApplication (or - QCoreApplication) object before you can create a QThread. - - The function will return immediately and the - main thread will continue. The code that appears in the - \l{QThread::run()}{run()} reimplementation will then be executed - in a separate thread. - - Creating threads is explained in more detail in the QThread - documentation. - - Note that QCoreApplication::exec() must always be called from the - main thread (the thread that executes \c{main()}), not from a - QThread. In GUI applications, the main thread is also called the - GUI thread because it's the only thread that is allowed to - perform GUI-related operations. -*/ - -/*! - \page threads-synchronizing.html - \title Synchronizing Threads - - \previouspage Starting Threads with QThread - \contentspage Thread Support in Qt - \nextpage Reentrancy and Thread-Safety - - The QMutex, QReadWriteLock, QSemaphore, and QWaitCondition - classes provide means to synchronize threads. While the main idea - with threads is that they should be as concurrent as possible, - there are points where threads must stop and wait for other - threads. For example, if two threads try to access the same - global variable simultaneously, the results are usually - undefined. - - QMutex provides a mutually exclusive lock, or mutex. At most one - thread can hold the mutex at any time. If a thread tries to - acquire the mutex while the mutex is already locked, the thread will - be put to sleep until the thread that currently holds the mutex - unlocks it. Mutexes are often used to protect accesses to shared - data (i.e., data that can be accessed from multiple threads - simultaneously). In the \l{Reentrancy and Thread-Safety} section - below, we will use it to make a class thread-safe. - - QReadWriteLock is similar to QMutex, except that it distinguishes - between "read" and "write" access to shared data and allows - multiple readers to access the data simultaneously. Using - QReadWriteLock instead of QMutex when it is possible can make - multithreaded programs more concurrent. - - QSemaphore is a generalization of QMutex that protects a certain - number of identical resources. In contrast, a mutex protects - exactly one resource. The \l{threads/semaphores}{Semaphores} - example shows a typical application of semaphores: synchronizing - access to a circular buffer between a producer and a consumer. - - QWaitCondition allows a thread to wake up other threads when some - condition has been met. One or many threads can block waiting for - a QWaitCondition to set a condition with - \l{QWaitCondition::wakeOne()}{wakeOne()} or - \l{QWaitCondition::wakeAll()}{wakeAll()}. Use - \l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly - selected event or \l{QWaitCondition::wakeAll()}{wakeAll()} to - wake them all. The \l{threads/waitconditions}{Wait Conditions} - example shows how to solve the producer-consumer problem using - QWaitCondition instead of QSemaphore. - - Note that Qt's synchronization classes rely on the use of properly - aligned pointers. For instance, you cannot use packed classes with - MSVC. -*/ - -/*! - \page threads-reentrancy.html - \title Reentrancy and Thread-Safety - - \keyword reentrant - \keyword thread-safe - - \previouspage Synchronizing Threads - \contentspage Thread Support in Qt - \nextpage Threads and QObjects - - Throughout the documentation, the terms \e{reentrant} and - \e{thread-safe} are used to mark classes and functions to indicate - how they can be used in multithread applications: - - \list - \o A \e thread-safe function can be called simultaneously from - multiple threads, even when the invocations use shared data, - because all references to the shared data are serialized. - \o A \e reentrant function can also be called simultaneously from - multiple threads, but only if each invocation uses its own data. - \endlist - - Hence, a \e{thread-safe} function is always \e{reentrant}, but a - \e{reentrant} function is not always \e{thread-safe}. - - By extension, a class is said to be \e{reentrant} if its member - functions can be called safely from multiple threads, as long as - each thread uses a \e{different} instance of the class. The class - is \e{thread-safe} if its member functions can be called safely - from multiple threads, even if all the threads use the \e{same} - instance of the class. - - \note Qt classes are only documented as \e{thread-safe} if they - are intended to be used by multiple threads. If a function is not - marked as thread-safe or reentrant, it should not be used from - different threads. If a class is not marked as thread-safe or - reentrant then a specific instance of that class should not be - accessed from different threads. - - \section1 Reentrancy - - C++ classes are often reentrant, simply because they only access - their own member data. Any thread can call a member function on an - instance of a reentrant class, as long as no other thread can call - a member function on the \e{same} instance of the class at the - same time. For example, the \c Counter class below is reentrant: - - \snippet doc/src/snippets/threads/threads.cpp 3 - \snippet doc/src/snippets/threads/threads.cpp 4 - - The class isn't thread-safe, because if multiple threads try to - modify the data member \c n, the result is undefined. This is - because the \c ++ and \c -- operators aren't always atomic. - Indeed, they usually expand to three machine instructions: - - \list 1 - \o Load the variable's value in a register. - \o Increment or decrement the register's value. - \o Store the register's value back into main memory. - \endlist - - If thread A and thread B load the variable's old value - simultaneously, increment their register, and store it back, they - end up overwriting each other, and the variable is incremented - only once! - - \section1 Thread-Safety - - Clearly, the access must be serialized: Thread A must perform - steps 1, 2, 3 without interruption (atomically) before thread B - can perform the same steps; or vice versa. An easy way to make - the class thread-safe is to protect all access to the data - members with a QMutex: - - \snippet doc/src/snippets/threads/threads.cpp 5 - \snippet doc/src/snippets/threads/threads.cpp 6 - - The QMutexLocker class automatically locks the mutex in its - constructor and unlocks it when the destructor is invoked, at the - end of the function. Locking the mutex ensures that access from - different threads will be serialized. The \c mutex data member is - declared with the \c mutable qualifier because we need to lock - and unlock the mutex in \c value(), which is a const function. - - \section1 Notes on Qt Classes - - Many Qt classes are \e{reentrant}, but they are not made - \e{thread-safe}, because making them thread-safe would incur the - extra overhead of repeatedly locking and unlocking a QMutex. For - example, QString is reentrant but not thread-safe. You can safely - access \e{different} instances of QString from multiple threads - simultaneously, but you can't safely access the \e{same} instance - of QString from multiple threads simultaneously (unless you - protect the accesses yourself with a QMutex). - - Some Qt classes and functions are thread-safe. These are mainly - the thread-related classes (e.g. QMutex) and fundamental functions - (e.g. QCoreApplication::postEvent()). - - \note Terminology in the multithreading domain isn't entirely - standardized. POSIX uses definitions of reentrant and thread-safe - that are somewhat different for its C APIs. When using other - object-oriented C++ class libraries with Qt, be sure the - definitions are understood. -*/ - -/*! - \page threads-qobject.html - \title Threads and QObjects - - \previouspage Reentrancy and Thread Safety - \contentspage Thread Support in Qt - \nextpage Concurrent Programming - - QThread inherits QObject. It emits signals to indicate that the - thread started or finished executing, and provides a few slots as - well. - - More interesting is that \l{QObject}s can be used in multiple - threads, emit signals that invoke slots in other threads, and - post events to objects that "live" in other threads. This is - possible because each thread is allowed to have its own event - loop. - - \section1 QObject Reentrancy - - QObject is reentrant. Most of its non-GUI subclasses, such as - QTimer, QTcpSocket, QUdpSocket and QProcess, are also - reentrant, making it possible to use these classes from multiple - threads simultaneously. Note that these classes are designed to be - created and used from within a single thread; creating an object - in one thread and calling its functions from another thread is not - guaranteed to work. There are three constraints to be aware of: - - \list - \o \e{The child of a QObject must always be created in the thread - where the parent was created.} This implies, among other - things, that you should never pass the QThread object (\c - this) as the parent of an object created in the thread (since - the QThread object itself was created in another thread). - - \o \e{Event driven objects may only be used in a single thread.} - Specifically, this applies to the \l{timers.html}{timer - mechanism} and the \l{QtNetwork}{network module}. For example, - you cannot start a timer or connect a socket in a thread that - is not the \l{QObject::thread()}{object's thread}. - - \o \e{You must ensure that all objects created in a thread are - deleted before you delete the QThread.} This can be done - easily by creating the objects on the stack in your - \l{QThread::run()}{run()} implementation. - \endlist - - Although QObject is reentrant, the GUI classes, notably QWidget - and all its subclasses, are not reentrant. They can only be used - from the main thread. As noted earlier, QCoreApplication::exec() - must also be called from that thread. - - In practice, the impossibility of using GUI classes in other - threads than the main thread can easily be worked around by - putting time-consuming operations in a separate worker thread and - displaying the results on screen in the main thread when the - worker thread is finished. This is the approach used for - implementing the \l{threads/mandelbrot}{Mandelbrot} and - the \l{network/blockingfortuneclient}{Blocking Fortune Client} - example. - - \section1 Per-Thread Event Loop - - Each thread can have its own event loop. The initial thread - starts its event loops using QCoreApplication::exec(); other - threads can start an event loop using QThread::exec(). Like - QCoreApplication, QThread provides an - \l{QThread::exit()}{exit(int)} function and a - \l{QThread::quit()}{quit()} slot. - - An event loop in a thread makes it possible for the thread to use - certain non-GUI Qt classes that require the presence of an event - loop (such as QTimer, QTcpSocket, and QProcess). It also makes it - possible to connect signals from any threads to slots of a - specific thread. This is explained in more detail in the - \l{Signals and Slots Across Threads} section below. - - \image threadsandobjects.png Threads, objects, and event loops - - A QObject instance is said to \e live in the thread in which it - is created. Events to that object are dispatched by that thread's - event loop. The thread in which a QObject lives is available using - QObject::thread(). - - Note that for QObjects that are created before QApplication, - QObject::thread() returns zero. This means that the main thread - will only handle posted events for these objects; other event - processing is not done at all for objects with no thread. Use the - QObject::moveToThread() function to change the thread affinity for - an object and its children (the object cannot be moved if it has a - parent). - - Calling \c delete on a QObject from a thread other than the one - that \e owns the object (or accessing the object in other ways) is - unsafe, unless you guarantee that the object isn't processing - events at that moment. Use QObject::deleteLater() instead, and a - \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted, - which the event loop of the object's thread will eventually pick - up. By default, the thread that \e owns a QObject is the thread - that \e creates the QObject, but not after QObject::moveToThread() - has been called. - - If no event loop is running, events won't be delivered to the - object. For example, if you create a QTimer object in a thread but - never call \l{QThread::exec()}{exec()}, the QTimer will never emit - its \l{QTimer::timeout()}{timeout()} signal. Calling - \l{QObject::deleteLater()}{deleteLater()} won't work - either. (These restrictions apply to the main thread as well.) - - You can manually post events to any object in any thread at any - time using the thread-safe function - QCoreApplication::postEvent(). The events will automatically be - dispatched by the event loop of the thread where the object was - created. - - Event filters are supported in all threads, with the restriction - that the monitoring object must live in the same thread as the - monitored object. Similarly, QCoreApplication::sendEvent() - (unlike \l{QCoreApplication::postEvent()}{postEvent()}) can only - be used to dispatch events to objects living in the thread from - which the function is called. - - \section1 Accessing QObject Subclasses from Other Threads - - QObject and all of its subclasses are not thread-safe. This - includes the entire event delivery system. It is important to keep - in mind that the event loop may be delivering events to your - QObject subclass while you are accessing the object from another - thread. - - If you are calling a function on an QObject subclass that doesn't - live in the current thread and the object might receive events, - you must protect all access to your QObject subclass's internal - data with a mutex; otherwise, you may experience crashes or other - undesired behavior. - - Like other objects, QThread objects live in the thread where the - object was created -- \e not in the thread that is created when - QThread::run() is called. It is generally unsafe to provide slots - in your QThread subclass, unless you protect the member variables - with a mutex. - - On the other hand, you can safely emit signals from your - QThread::run() implementation, because signal emission is - thread-safe. - - \section1 Signals and Slots Across Threads - - Qt supports these signal-slot connection types: - - \list - - \o \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is - emitted in the thread which the receiving object has affinity then - the behavior is the same as the Direct Connection. Otherwise, - the behavior is the same as the Queued Connection." - - \o \l{Qt::DirectConnection}{Direct Connection} The slot is invoked - immediately, when the signal is emitted. The slot is executed - in the emitter's thread, which is not necessarily the - receiver's thread. - - \o \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked - when control returns to the event loop of the receiver's - thread. The slot is executed in the receiver's thread. - - \o \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection} - The slot is invoked as for the Queued Connection, except the - current thread blocks until the slot returns. \note Using this - type to connect objects in the same thread will cause deadlock. - - \o \l{Qt::UniqueConnection}{Unique Connection} The behavior is the - same as the Auto Connection, but the connection is made only if - it does not duplicate an existing connection. i.e., if the same - signal is already connected to the same slot for the same pair - of objects, then the connection is not made and connect() - returns false. - - \endlist - - The connection type can be specified by passing an additional - argument to \l{QObject::connect()}{connect()}. Be aware that - using direct connections when the sender and receiver live in - different threads is unsafe if an event loop is running in the - receiver's thread, for the same reason that calling any function - on an object living in another thread is unsafe. - - QObject::connect() itself is thread-safe. - - The \l{threads/mandelbrot}{Mandelbrot} example uses a queued - connection to communicate between a worker thread and the main - thread. To avoid freezing the main thread's event loop (and, as a - consequence, the application's user interface), all the - Mandelbrot fractal computation is done in a separate worker - thread. The thread emits a signal when it is done rendering the - fractal. - - Similarly, the \l{network/blockingfortuneclient}{Blocking Fortune - Client} example uses a separate thread for communicating with - a TCP server asynchronously. -*/ - -/*! - \page threads-qtconcurrent.html - \title Concurrent Programming - - \previouspage Threads and QObjects - \contentspage Thread Support in Qt - \nextpage Thread-Support in Qt Modules - - \target qtconcurrent intro - - The QtConcurrent namespace provides high-level APIs that make it - possible to write multi-threaded programs without using low-level - threading primitives such as mutexes, read-write locks, wait - conditions, or semaphores. Programs written with QtConcurrent - automatically adjust the number of threads used according to the - number of processor cores available. This means that applications - written today will continue to scale when deployed on multi-core - systems in the future. - - QtConcurrent includes functional programming style APIs for - parallel list processing, including a MapReduce and FilterReduce - implementation for shared-memory (non-distributed) systems, and - classes for managing asynchronous computations in GUI - applications: - - \list - - \o QtConcurrent::map() applies a function to every item in a container, - modifying the items in-place. - - \o QtConcurrent::mapped() is like map(), except that it returns a new - container with the modifications. - - \o QtConcurrent::mappedReduced() is like mapped(), except that the - modified results are reduced or folded into a single result. - - \o QtConcurrent::filter() removes all items from a container based on the - result of a filter function. - - \o QtConcurrent::filtered() is like filter(), except that it returns a new - container with the filtered results. - - \o QtConcurrent::filteredReduced() is like filtered(), except that the - filtered results are reduced or folded into a single result. - - \o QtConcurrent::run() runs a function in another thread. - - \o QFuture represents the result of an asynchronous computation. - - \o QFutureIterator allows iterating through results available via QFuture. - - \o QFutureWatcher allows monitoring a QFuture using signals-and-slots. - - \o QFutureSynchronizer is a convenience class that automatically - synchronizes several QFutures. - - \endlist - - Qt Concurrent supports several STL-compatible container and iterator types, - but works best with Qt containers that have random-access iterators, such as - QList or QVector. The map and filter functions accept both containers and begin/end iterators. - - STL Iterator support overview: - - \table - \header - \o Iterator Type - \o Example classes - \o Support status - \row - \o Input Iterator - \o - \o Not Supported - \row - \o Output Iterator - \o - \o Not Supported - \row - \o Forward Iterator - \o std::slist - \o Supported - \row - \o Bidirectional Iterator - \o QLinkedList, std::list - \o Supported - \row - \o Random Access Iterator - \o QList, QVector, std::vector - \o Supported and Recommended - \endtable - - Random access iterators can be faster in cases where Qt Concurrent is iterating - over a large number of lightweight items, since they allow skipping to any point - in the container. In addition, using random access iterators allows Qt Concurrent - to provide progress information trough QFuture::progressValue() and QFutureWatcher:: - progressValueChanged(). - - The non in-place modifying functions such as mapped() and filtered() makes a - copy of the container when called. If you are using STL containers this copy operation - might take some time, in this case we recommend specifying the begin and end iterators - for the container instead. -*/ - -/*! - \page threads-modules.html - \title Thread-Support in Qt Modules - - \previouspage Concurrent Programming - \contentspage Thread Support in Qt - - \section1 Threads and the SQL Module - - A connection can only be used from within the thread that created it. - Moving connections between threads or creating queries from a different - thread is not supported. - - In addition, the third party libraries used by the QSqlDrivers can impose - further restrictions on using the SQL Module in a multithreaded program. - Consult the manual of your database client for more information - - \section1 Painting in Threads - - QPainter can be used in a thread to paint onto QImage, QPrinter, and - QPicture paint devices. Painting onto QPixmaps and QWidgets is \e not - supported. On Mac OS X the automatic progress dialog will not be - displayed if you are printing from outside the GUI thread. - - Any number of threads can paint at any given time, however only - one thread at a time can paint on a given paint device. In other - words, two threads can paint at the same time if each paints onto - separate QImages, but the two threads cannot paint onto the same - QImage at the same time. - - Note that on X11 systems without FontConfig support, Qt cannot - render text outside of the GUI thread. You can use the - QFontDatabase::supportsThreadedFontRendering() function to detect - whether or not font rendering can be used outside the GUI thread. - - \section1 Threads and Rich Text Processing - - The QTextDocument, QTextCursor, and \link richtext.html all - related classes\endlink are reentrant. - - Note that a QTextDocument instance created in the GUI thread may - contain QPixmap image resources. Use QTextDocument::clone() to - create a copy of the document, and pass the copy to another thread for - further processing (such as printing). - - \section1 Threads and the SVG module - - The QSvgGenerator and QSvgRenderer classes in the QtSvg module - are reentrant. - - \section1 Threads and Implicitly Shared Classes - - Qt uses an optimization called \l{implicit sharing} for many of - its value class, notably QImage and QString. Beginning with Qt 4, - implicit shared classes can safely be copied across threads, like - any other value classes. They are fully - \l{Reentrancy and Thread-Safety}{reentrant}. The implicit sharing - is really \e implicit. - - In many people's minds, implicit sharing and multithreading are - incompatible concepts, because of the way the reference counting - is typically done. Qt, however, uses atomic reference counting to - ensure the integrity of the shared data, avoiding potential - corruption of the reference counter. - - Note that atomic reference counting does not guarantee - \l{Reentrancy and Thread-Safety}{thread-safety}. Proper locking should be used - when sharing an instance of an implicitly shared class between - threads. This is the same requirement placed on all - \l{Reentrancy and Thread-Safety}{reentrant} classes, shared or not. Atomic reference - counting does, however, guarantee that a thread working on its - own, local instance of an implicitly shared class is safe. We - recommend using \l{Signals and Slots Across Threads}{signals and - slots} to pass data between threads, as this can be done without - the need for any explicit locking. - - To sum it up, implicitly shared classes in Qt 4 are really \e - implicitly shared. Even in multithreaded applications, you can - safely use them as if they were plain, non-shared, reentrant - value-based classes. -*/ diff --git a/doc/src/corelib/containers.qdoc b/doc/src/corelib/containers.qdoc new file mode 100644 index 0000000000..ca9bcc6b47 --- /dev/null +++ b/doc/src/corelib/containers.qdoc @@ -0,0 +1,803 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group tools + \title Non-GUI Classes + \ingroup groups + + \brief Collection classes such as list, queue, stack and string, along + with other classes that can be used without needing QApplication. + + The non-GUI classes are general-purpose collection and string classes + that may be used independently of the GUI classes. + + In particular, these classes do not depend on QApplication at all, + and so can be used in non-GUI programs. + +*/ + +/*! + \page containers.html + \title Container Classes + \ingroup technology-apis + \ingroup groups + \ingroup qt-basic-concepts + \keyword container class + \keyword container classes + + \brief Qt's template-based container classes. + + \tableofcontents + + \section1 Introduction + + The Qt library provides a set of general purpose template-based + container classes. These classes can be used to store items of a + specified type. For example, if you need a resizable array of + \l{QString}s, use QVector. + + These container classes are designed to be lighter, safer, and + easier to use than the STL containers. If you are unfamiliar with + the STL, or prefer to do things the "Qt way", you can use these + classes instead of the STL classes. + + The container classes are \l{implicitly shared}, they are + \l{reentrant}, and they are optimized for speed, low memory + consumption, and minimal inline code expansion, resulting in + smaller executables. In addition, they are \l{thread-safe} + in situations where they are used as read-only containers + by all threads used to access them. + + For traversing the items stored in a container, you can use one + of two types of iterators: \l{Java-style iterators} and + \l{STL-style iterators}. The Java-style iterators are easier to + use and provide high-level functionality, whereas the STL-style + iterators are slightly more efficient and can be used together + with Qt's and STL's \l{generic algorithms}. + + Qt also offers a \l{foreach} keyword that make it very + easy to iterate over all the items stored in a container. + + \section1 The Container Classes + + Qt provides the following sequential containers: QList, + QLinkedList, QVector, QStack, and QQueue. For most + applications, QList is the best type to use. Although it is + implemented as an array-list, it provides very fast prepends and + appends. If you really need a linked-list, use QLinkedList; if you + want your items to occupy consecutive memory locations, use QVector. + QStack and QQueue are convenience classes that provide LIFO and + FIFO semantics. + + Qt also provides these associative containers: QMap, + QMultiMap, QHash, QMultiHash, and QSet. The "Multi" containers + conveniently support multiple values associated with a single + key. The "Hash" containers provide faster lookup by using a hash + function instead of a binary search on a sorted set. + + As special cases, the QCache and QContiguousCache classes provide + efficient hash-lookup of objects in a limited cache storage. + + \table + \header \o Class \o Summary + + \row \o \l{QList} + \o This is by far the most commonly used container class. It + stores a list of values of a given type (T) that can be accessed + by index. Internally, the QList is implemented using an array, + ensuring that index-based access is very fast. + + Items can be added at either end of the list using + QList::append() and QList::prepend(), or they can be inserted in + the middle using QList::insert(). More than any other container + class, QList is highly optimized to expand to as little code as + possible in the executable. QStringList inherits from + QList. + + \row \o \l{QLinkedList} + \o This is similar to QList, except that it uses + iterators rather than integer indexes to access items. It also + provides better performance than QList when inserting in the + middle of a huge list, and it has nicer iterator semantics. + (Iterators pointing to an item in a QLinkedList remain valid as + long as the item exists, whereas iterators to a QList can become + invalid after any insertion or removal.) + + \row \o \l{QVector} + \o This stores an array of values of a given type at adjacent + positions in memory. Inserting at the front or in the middle of + a vector can be quite slow, because it can lead to large numbers + of items having to be moved by one position in memory. + + \row \o \l{QStack} + \o This is a convenience subclass of QVector that provides + "last in, first out" (LIFO) semantics. It adds the following + functions to those already present in QVector: + \l{QStack::push()}{push()}, \l{QStack::pop()}{pop()}, + and \l{QStack::top()}{top()}. + + \row \o \l{QQueue} + \o This is a convenience subclass of QList that provides + "first in, first out" (FIFO) semantics. It adds the following + functions to those already present in QList: + \l{QQueue::enqueue()}{enqueue()}, + \l{QQueue::dequeue()}{dequeue()}, and \l{QQueue::head()}{head()}. + + \row \o \l{QSet} + \o This provides a single-valued mathematical set with fast + lookups. + + \row \o \l{QMap} + \o This provides a dictionary (associative array) that maps keys + of type Key to values of type T. Normally each key is associated + with a single value. QMap stores its data in Key order; if order + doesn't matter QHash is a faster alternative. + + \row \o \l{QMultiMap} + \o This is a convenience subclass of QMap that provides a nice + interface for multi-valued maps, i.e. maps where one key can be + associated with multiple values. + + \row \o \l{QHash} + \o This has almost the same API as QMap, but provides + significantly faster lookups. QHash stores its data in an + arbitrary order. + + \row \o \l{QMultiHash} + \o This is a convenience subclass of QHash that + provides a nice interface for multi-valued hashes. + + \endtable + + Containers can be nested. For example, it is perfectly possible + to use a QMap >, where the key type is + QString and the value type QList. The only pitfall is that + you must insert a space between the closing angle brackets (>); + otherwise the C++ compiler will misinterpret the two >'s as a + right-shift operator (>>) and report a syntax error. + + The containers are defined in individual header files with the + same name as the container (e.g., \c ). For + convenience, the containers are forward declared in \c + . + + \keyword assignable data type + \keyword assignable data types + + The values stored in the various containers can be of any + \e{assignable data type}. To qualify, a type must provide a + default constructor, a copy constructor, and an assignment + operator. This covers most data types you are likely to want to + store in a container, including basic types such as \c int and \c + double, pointer types, and Qt data types such as QString, QDate, + and QTime, but it doesn't cover QObject or any QObject subclass + (QWidget, QDialog, QTimer, etc.). If you attempt to instantiate a + QList, the compiler will complain that QWidget's copy + constructor and assignment operators are disabled. If you want to + store these kinds of objects in a container, store them as + pointers, for example as QList. + + Here's an example custom data type that meets the requirement of + an assignable data type: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 0 + + If we don't provide a copy constructor or an assignment operator, + C++ provides a default implementation that performs a + member-by-member copy. In the example above, that would have been + sufficient. Also, if you don't provide any constructors, C++ + provides a default constructor that initializes its member using + default constructors. Although it doesn't provide any + explicit constructors or assignment operator, the following data + type can be stored in a container: + + \snippet doc/src/snippets/streaming/main.cpp 0 + + Some containers have additional requirements for the data types + they can store. For example, the Key type of a QMap must + provide \c operator<(). Such special requirements are documented + in a class's detailed description. In some cases, specific + functions have special requirements; these are described on a + per-function basis. The compiler will always emit an error if a + requirement isn't met. + + Qt's containers provide operator<<() and operator>>() so that they + can easily be read and written using a QDataStream. This means + that the data types stored in the container must also support + operator<<() and operator>>(). Providing such support is + straightforward; here's how we could do it for the Movie struct + above: + + \snippet doc/src/snippets/streaming/main.cpp 1 + \codeline + \snippet doc/src/snippets/streaming/main.cpp 2 + + \keyword default-constructed values + + The documentation of certain container class functions refer to + \e{default-constructed values}; for example, QVector + automatically initializes its items with default-constructed + values, and QMap::value() returns a default-constructed value if + the specified key isn't in the map. For most value types, this + simply means that a value is created using the default + constructor (e.g. an empty string for QString). But for primitive + types like \c{int} and \c{double}, as well as for pointer types, + the C++ language doesn't specify any initialization; in those + cases, Qt's containers automatically initialize the value to 0. + + \section1 The Iterator Classes + + Iterators provide a uniform means to access items in a container. + Qt's container classes provide two types of iterators: Java-style + iterators and STL-style iterators. Iterators of both types are + invalidated when the data in the container is modified or detached + from \l{Implicit Sharing}{implicitly shared copies} due to a call + to a non-const member function. + + \section2 Java-Style Iterators + + The Java-style iterators are new in Qt 4 and are the standard + ones used in Qt applications. They are more convenient to use than + the STL-style iterators, at the price of being slightly less + efficient. Their API is modelled on Java's iterator classes. + + For each container class, there are two Java-style iterator data + types: one that provides read-only access and one that provides + read-write access. + + \table + \header \o Containers \o Read-only iterator + \o Read-write iterator + \row \o QList, QQueue \o QListIterator + \o QMutableListIterator + \row \o QLinkedList \o QLinkedListIterator + \o QMutableLinkedListIterator + \row \o QVector, QStack \o QVectorIterator + \o QMutableVectorIterator + \row \o QSet \o QSetIterator + \o QMutableSetIterator + \row \o QMap, QMultiMap \o QMapIterator + \o QMutableMapIterator + \row \o QHash, QMultiHash \o QHashIterator + \o QMutableHashIterator + \endtable + + In this discussion, we will concentrate on QList and QMap. The + iterator types for QLinkedList, QVector, and QSet have exactly + the same interface as QList's iterators; similarly, the iterator + types for QHash have the same interface as QMap's iterators. + + Unlike STL-style iterators (covered \l{STL-style + iterators}{below}), Java-style iterators point \e between items + rather than directly \e at items. For this reason, they are + either pointing to the very beginning of the container (before + the first item), at the very end of the container (after the last + item), or between two items. The diagram below shows the valid + iterator positions as red arrows for a list containing four + items: + + \img javaiterators1.png + + Here's a typical loop for iterating through all the elements of a + QList in order and printing them to the console: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 1 + + It works as follows: The QList to iterate over is passed to the + QListIterator constructor. At that point, the iterator is located + just in front of the first item in the list (before item "A"). + Then we call \l{QListIterator::hasNext()}{hasNext()} to + check whether there is an item after the iterator. If there is, we + call \l{QListIterator::next()}{next()} to jump over that + item. The next() function returns the item that it jumps over. For + a QList, that item is of type QString. + + Here's how to iterate backward in a QList: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 2 + + The code is symmetric with iterating forward, except that we + start by calling \l{QListIterator::toBack()}{toBack()} + to move the iterator after the last item in the list. + + The diagram below illustrates the effect of calling + \l{QListIterator::next()}{next()} and + \l{QListIterator::previous()}{previous()} on an iterator: + + \img javaiterators2.png + + The following table summarizes the QListIterator API: + + \table + \header \o Function \o Behavior + \row \o \l{QListIterator::toFront()}{toFront()} + \o Moves the iterator to the front of the list (before the first item) + \row \o \l{QListIterator::toBack()}{toBack()} + \o Moves the iterator to the back of the list (after the last item) + \row \o \l{QListIterator::hasNext()}{hasNext()} + \o Returns true if the iterator isn't at the back of the list + \row \o \l{QListIterator::next()}{next()} + \o Returns the next item and advances the iterator by one position + \row \o \l{QListIterator::peekNext()}{peekNext()} + \o Returns the next item without moving the iterator + \row \o \l{QListIterator::hasPrevious()}{hasPrevious()} + \o Returns true if the iterator isn't at the front of the list + \row \o \l{QListIterator::previous()}{previous()} + \o Returns the previous item and moves the iterator back by one position + \row \o \l{QListIterator::peekPrevious()}{peekPrevious()} + \o Returns the previous item without moving the iterator + \endtable + + QListIterator provides no functions to insert or remove items + from the list as we iterate. To accomplish this, you must use + QMutableListIterator. Here's an example where we remove all + odd numbers from a QList using QMutableListIterator: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 3 + + The next() call in the loop is made every time. It jumps over the + next item in the list. The + \l{QMutableListIterator::remove()}{remove()} function removes the + last item that we jumped over from the list. The call to + \l{QMutableListIterator::remove()}{remove()} does not invalidate + the iterator, so it is safe to continue using it. This works just + as well when iterating backward: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 4 + + If we just want to modify the value of an existing item, we can + use \l{QMutableListIterator::setValue()}{setValue()}. In the code + below, we replace any value larger than 128 with 128: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 5 + + Just like \l{QMutableListIterator::remove()}{remove()}, + \l{QMutableListIterator::setValue()}{setValue()} operates on the + last item that we jumped over. If we iterate forward, this is the + item just before the iterator; if we iterate backward, this is + the item just after the iterator. + + The \l{QMutableListIterator::next()}{next()} function returns a + non-const reference to the item in the list. For simple + operations, we don't even need + \l{QMutableListIterator::setValue()}{setValue()}: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 6 + + As mentioned above, QLinkedList's, QVector's, and QSet's iterator + classes have exactly the same API as QList's. We will now turn to + QMapIterator, which is somewhat different because it iterates on + (key, value) pairs. + + Like QListIterator, QMapIterator provides + \l{QMapIterator::toFront()}{toFront()}, + \l{QMapIterator::toBack()}{toBack()}, + \l{QMapIterator::hasNext()}{hasNext()}, + \l{QMapIterator::next()}{next()}, + \l{QMapIterator::peekNext()}{peekNext()}, + \l{QMapIterator::hasPrevious()}{hasPrevious()}, + \l{QMapIterator::previous()}{previous()}, and + \l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and + value components are extracted by calling key() and value() on + the object returned by next(), peekNext(), previous(), or + peekPrevious(). + + The following example removes all (capital, country) pairs where + the capital's name ends with "City": + + \snippet doc/src/snippets/code/doc_src_containers.cpp 7 + + QMapIterator also provides a key() and a value() function that + operate directly on the iterator and that return the key and + value of the last item that the iterator jumped above. For + example, the following code copies the contents of a QMap into a + QHash: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 8 + + If we want to iterate through all the items with the same + value, we can use \l{QMapIterator::findNext()}{findNext()} + or \l{QMapIterator::findPrevious()}{findPrevious()}. + Here's an example where we remove all the items with a particular + value: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 9 + + \section2 STL-Style Iterators + + STL-style iterators have been available since the release of Qt + 2.0. They are compatible with Qt's and STL's \l{generic + algorithms} and are optimized for speed. + + For each container class, there are two STL-style iterator types: + one that provides read-only access and one that provides + read-write access. Read-only iterators should be used wherever + possible because they are faster than read-write iterators. + + \table + \header \o Containers \o Read-only iterator + \o Read-write iterator + \row \o QList, QQueue \o QList::const_iterator + \o QList::iterator + \row \o QLinkedList \o QLinkedList::const_iterator + \o QLinkedList::iterator + \row \o QVector, QStack \o QVector::const_iterator + \o QVector::iterator + \row \o QSet \o QSet::const_iterator + \o QSet::iterator + \row \o QMap, QMultiMap \o QMap::const_iterator + \o QMap::iterator + \row \o QHash, QMultiHash \o QHash::const_iterator + \o QHash::iterator + \endtable + + The API of the STL iterators is modelled on pointers in an array. + For example, the \c ++ operator advances the iterator to the next + item, and the \c * operator returns the item that the iterator + points to. In fact, for QVector and QStack, which store their + items at adjacent memory positions, the + \l{QVector::iterator}{iterator} type is just a typedef for \c{T *}, + and the \l{QVector::iterator}{const_iterator} type is + just a typedef for \c{const T *}. + + In this discussion, we will concentrate on QList and QMap. The + iterator types for QLinkedList, QVector, and QSet have exactly + the same interface as QList's iterators; similarly, the iterator + types for QHash have the same interface as QMap's iterators. + + Here's a typical loop for iterating through all the elements of a + QList in order and converting them to lowercase: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 10 + + Unlike \l{Java-style iterators}, STL-style iterators point + directly at items. The begin() function of a container returns an + iterator that points to the first item in the container. The + end() function of a container returns an iterator to the + imaginary item one position past the last item in the container. + end() marks an invalid position; it must never be dereferenced. + It is typically used in a loop's break condition. If the list is + empty, begin() equals end(), so we never execute the loop. + + The diagram below shows the valid iterator positions as red + arrows for a vector containing four items: + + \img stliterators1.png + + Iterating backward with an STL-style iterator requires us to + decrement the iterator \e before we access the item. This + requires a \c while loop: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 11 + + In the code snippets so far, we used the unary \c * operator to + retrieve the item (of type QString) stored at a certain iterator + position, and we then called QString::toLower() on it. Most C++ + compilers also allow us to write \c{i->toLower()}, but some + don't. + + For read-only access, you can use const_iterator, constBegin(), + and constEnd(). For example: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 12 + + The following table summarizes the STL-style iterators' API: + + \table + \header \o Expression \o Behavior + \row \o \c{*i} \o Returns the current item + \row \o \c{++i} \o Advances the iterator to the next item + \row \o \c{i += n} \o Advances the iterator by \c n items + \row \o \c{--i} \o Moves the iterator back by one item + \row \o \c{i -= n} \o Moves the iterator back by \c n items + \row \o \c{i - j} \o Returns the number of items between iterators \c i and \c j + \endtable + + The \c{++} and \c{--} operators are available both as prefix + (\c{++i}, \c{--i}) and postfix (\c{i++}, \c{i--}) operators. The + prefix versions modify the iterators and return a reference to + the modified iterator; the postfix versions take a copy of the + iterator before they modify it, and return that copy. In + expressions where the return value is ignored, we recommend that + you use the prefix operators (\c{++i}, \c{--i}), as these are + slightly faster. + + For non-const iterator types, the return value of the unary \c{*} + operator can be used on the left side of the assignment operator. + + For QMap and QHash, the \c{*} operator returns the value + component of an item. If you want to retrieve the key, call key() + on the iterator. For symmetry, the iterator types also provide a + value() function to retrieve the value. For example, here's how + we would print all items in a QMap to the console: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 13 + + Thanks to \l{implicit sharing}, it is very inexpensive for a + function to return a container per value. The Qt API contains + dozens of functions that return a QList or QStringList per value + (e.g., QSplitter::sizes()). If you want to iterate over these + using an STL iterator, you should always take a copy of the + container and iterate over the copy. For example: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 14 + + This problem doesn't occur with functions that return a const or + non-const reference to a container. + + \l{Implicit sharing} has another consequence on STL-style + iterators: You must not take a copy of a container while + non-const iterators are active on that container. Java-style + iterators don't suffer from that limitation. + + \keyword foreach + \section1 The foreach Keyword + + If you just want to iterate over all the items in a container + in order, you can use Qt's \c foreach keyword. The keyword is a + Qt-specific addition to the C++ language, and is implemented + using the preprocessor. + + Its syntax is: \c foreach (\e variable, \e container) \e + statement. For example, here's how to use \c foreach to iterate + over a QLinkedList: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 15 + + The \c foreach code is significantly shorter than the equivalent + code that uses iterators: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 16 + + Unless the data type contains a comma (e.g., \c{QPair}), the variable used for iteration can be defined within the + \c foreach statement: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 17 + + And like any other C++ loop construct, you can use braces around + the body of a \c foreach loop, and you can use \c break to leave + the loop: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 18 + + With QMap and QHash, \c foreach accesses the value component of + the (key, value) pairs. If you want to iterate over both the keys + and the values, you can use iterators (which are fastest), or you + can write code like this: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 19 + + For a multi-valued map: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 20 + + Qt automatically takes a copy of the container when it enters a + \c foreach loop. If you modify the container as you are + iterating, that won't affect the loop. (If you do not modify the + container, the copy still takes place, but thanks to \l{implicit + sharing} copying a container is very fast.) + + Since foreach creates a copy of the container, using a non-const + reference for the variable does not allow you to modify the original + container. It only affects the copy, which is probably not what you + want. + + In addition to \c foreach, Qt also provides a \c forever + pseudo-keyword for infinite loops: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 21 + + If you're worried about namespace pollution, you can disable + these macros by adding the following line to your \c .pro file: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 22 + + \section1 Other Container-Like Classes + + Qt includes three template classes that resemble containers in + some respects. These classes don't provide iterators and cannot + be used with the \c foreach keyword. + + \list + \o QVarLengthArray provides a low-level + variable-length array. It can be used instead of QVector in + places where speed is particularly important. + + \o QCache provides a cache to store objects of a certain + type T associated with keys of type Key. + + \o QContiguousCache provides an efficient way of caching data + that is typically accessed in a contiguous way. + + \o QPair stores a pair of elements. + \endlist + + Additional non-template types that compete with Qt's template + containers are QBitArray, QByteArray, QString, and QStringList. + + \section1 Algorithmic Complexity + + Algorithmic complexity is concerned about how fast (or slow) each + function is as the number of items in the container grow. For + example, inserting an item in the middle of a QLinkedList is an + extremely fast operation, irrespective of the number of items + stored in the QLinkedList. On the other hand, inserting an item + in the middle of a QVector is potentially very expensive if the + QVector contains many items, since half of the items must be + moved one position in memory. + + To describe algorithmic complexity, we use the following + terminology, based on the "big Oh" notation: + + \keyword constant time + \keyword logarithmic time + \keyword linear time + \keyword linear-logarithmic time + \keyword quadratic time + + \list + \o \bold{Constant time:} O(1). A function is said to run in constant + time if it requires the same amount of time no matter how many + items are present in the container. One example is + QLinkedList::insert(). + + \o \bold{Logarithmic time:} O(log \e n). A function that runs in + logarithmic time is a function whose running time is + proportional to the logarithm of the number of items in the + container. One example is qBinaryFind(). + + \o \bold{Linear time:} O(\e n). A function that runs in linear time + will execute in a time directly proportional to the number of + items stored in the container. One example is + QVector::insert(). + + \o \bold{Linear-logarithmic time:} O(\e{n} log \e n). A function + that runs in linear-logarithmic time is asymptotically slower + than a linear-time function, but faster than a quadratic-time + function. + + \o \bold{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function + executes in a time that is proportional to the square of the + number of items stored in the container. + \endlist + + The following table summarizes the algorithmic complexity of Qt's + sequential container classes: + + \table + \header \o \o Index lookup \o Insertion \o Prepending \o Appending + \row \o QLinkedList \o O(\e n) \o O(1) \o O(1) \o O(1) + \row \o QList \o O(1) \o O(n) \o Amort. O(1) \o Amort. O(1) + \row \o QVector \o O(1) \o O(n) \o O(n) \o Amort. O(1) + \endtable + + In the table, "Amort." stands for "amortized behavior". For + example, "Amort. O(1)" means that if you call the function + only once, you might get O(\e n) behavior, but if you call it + multiple times (e.g., \e n times), the average behavior will be + O(1). + + The following table summarizes the algorithmic complexity of Qt's + associative containers and sets: + + \table + \header \o{1,2} \o{2,1} Key lookup \o{2,1} Insertion + \header \o Average \o Worst case \o Average \o Worst case + \row \o QMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) + \row \o QMultiMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n) + \row \o QHash \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) + \row \o QSet \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n) + \endtable + + With QVector, QHash, and QSet, the performance of appending items + is amortized O(log \e n). It can be brought down to O(1) by + calling QVector::reserve(), QHash::reserve(), or QSet::reserve() + with the expected number of items before you insert the items. + The next section discusses this topic in more depth. + + \section1 Growth Strategies + + QVector, QString, and QByteArray store their items + contiguously in memory; QList maintains an array of pointers + to the items it stores to provide fast index-based access (unless + T is a pointer type or a basic type of the size of a pointer, in + which case the value itself is stored in the array); QHash keeps a hash table whose size is proportional to the number + of items in the hash. To avoid reallocating the data every single + time an item is added at the end of the container, these classes + typically allocate more memory than necessary. + + Consider the following code, which builds a QString from another + QString: + + \snippet doc/src/snippets/code/doc_src_containers.cpp 23 + + We build the string \c out dynamically by appending one character + to it at a time. Let's assume that we append 15000 characters to + the QString string. Then the following 18 reallocations (out of a + possible 15000) occur when QString runs out of space: 4, 8, 12, + 16, 20, 52, 116, 244, 500, 1012, 2036, 4084, 6132, 8180, 10228, + 12276, 14324, 16372. At the end, the QString has 16372 Unicode + characters allocated, 15000 of which are occupied. + + The values above may seem a bit strange, but here are the guiding + principles: + \list + \o QString allocates 4 characters at a time until it reaches size 20. + \o From 20 to 4084, it advances by doubling the size each time. + More precisely, it advances to the next power of two, minus + 12. (Some memory allocators perform worst when requested exact + powers of two, because they use a few bytes per block for + book-keeping.) + \o From 4084 on, it advances by blocks of 2048 characters (4096 + bytes). This makes sense because modern operating systems + don't copy the entire data when reallocating a buffer; the + physical memory pages are simply reordered, and only the data + on the first and last pages actually needs to be copied. + \endlist + + QByteArray and QList use more or less the same algorithm as + QString. + + QVector also uses that algorithm for data types that can be + moved around in memory using memcpy() (including the basic C++ + types, the pointer types, and Qt's \l{shared classes}) but uses a + different algorithm for data types that can only be moved by + calling the copy constructor and a destructor. Since the cost of + reallocating is higher in that case, QVector reduces the + number of reallocations by always doubling the memory when + running out of space. + + QHash is a totally different case. QHash's internal hash + table grows by powers of two, and each time it grows, the items + are relocated in a new bucket, computed as qHash(\e key) % + QHash::capacity() (the number of buckets). This remark applies to + QSet and QCache as well. + + For most applications, the default growing algorithm provided by + Qt does the trick. If you need more control, QVector, + QHash, QSet, QString, and QByteArray provide a trio of + functions that allow you to check and specify how much memory to + use to store the items: + + \list + \o \l{QString::capacity()}{capacity()} returns the + number of items for which memory is allocated (for QHash and + QSet, the number of buckets in the hash table). + \o \l{QString::reserve()}{reserve}(\e size) explicitly + preallocates memory for \e size items. + \o \l{QString::squeeze()}{squeeze()} frees any memory + not required to store the items. + \endlist + + If you know approximately how many items you will store in a + container, you can start by calling reserve(), and when you are + done populating the container, you can call squeeze() to release + the extra preallocated memory. +*/ diff --git a/doc/src/corelib/implicit-sharing.qdoc b/doc/src/corelib/implicit-sharing.qdoc new file mode 100644 index 0000000000..e745d127d5 --- /dev/null +++ b/doc/src/corelib/implicit-sharing.qdoc @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* TODO: Move some of the documentation from QSharedDataPointer into this + document. */ + +/*! + \group shared + \title Implicitly Shared Classes +*/ + +/*! + \page implicit-sharing.html + \title Implicit Sharing + \ingroup qt-basic-concepts + + \brief Reference counting for fast copying. + + \keyword implicit data sharing + \keyword implicit sharing + \keyword implicitly shared + \keyword reference counting + \keyword shared implicitly + \keyword shared classes + + Many C++ classes in Qt use implicit data sharing to maximize + resource usage and minimize copying. Implicitly shared classes are + both safe and efficient when passed as arguments, because only a + pointer to the data is passed around, and the data is copied only + if and when a function writes to it, i.e., \e {copy-on-write}. + + \tableofcontents + + \section1 Overview + + A shared class consists of a pointer to a shared data block that + contains a reference count and the data. + + When a shared object is created, it sets the reference count to 1. The + reference count is incremented whenever a new object references the + shared data, and decremented when the object dereferences the shared + data. The shared data is deleted when the reference count becomes + zero. + + \keyword deep copy + \keyword shallow copy + + When dealing with shared objects, there are two ways of copying an + object. We usually speak about \e deep and \e shallow copies. A deep + copy implies duplicating an object. A shallow copy is a reference + copy, i.e. just a pointer to a shared data block. Making a deep copy + can be expensive in terms of memory and CPU. Making a shallow copy is + very fast, because it only involves setting a pointer and incrementing + the reference count. + + Object assignment (with operator=()) for implicitly shared objects is + implemented using shallow copies. + + The benefit of sharing is that a program does not need to duplicate + data unnecessarily, which results in lower memory use and less copying + of data. Objects can easily be assigned, sent as function arguments, + and returned from functions. + + Implicit sharing takes place behind the scenes; the programmer + does not need to worry about it. Even in multithreaded + applications, implicit sharing takes place, as explained in + \l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes} + {Threads and Implicitly Shared Classes}. + + When implementing your own implicitly shared classes, use the + QSharedData and QSharedDataPointer classes. + + \section1 Implicit Sharing in Detail + + Implicit sharing automatically detaches the object from a shared + block if the object is about to change and the reference count is + greater than one. (This is often called \e {copy-on-write} or + \e {value semantics}.) + + An implicitly shared class has total control of its internal data. In + any member functions that modify its data, it automatically detaches + before modifying the data. + + The QPen class, which uses implicit sharing, detaches from the shared + data in all member functions that change the internal data. + + Code fragment: + \snippet doc/src/snippets/code/doc_src_groups.cpp 0 + + + \section1 List of Classes + + The classes listed below automatically detach from common data if + an object is about to be changed. The programmer will not even + notice that the objects are shared. Thus you should treat + separate instances of them as separate objects. They will always + behave as separate objects but with the added benefit of sharing + data whenever possible. For this reason, you can pass instances + of these classes as arguments to functions by value without + concern for the copying overhead. + + Example: + \snippet doc/src/snippets/code/doc_src_groups.cpp 1 + + In this example, \c p1 and \c p2 share data until QPainter::begin() + is called for \c p2, because painting a pixmap will modify it. + + \warning Do not copy an implicitly shared container (QMap, + QVector, etc.) while you are iterating over it using an non-const + \l{STL-style iterator}. + + \keyword implicitly shared classes + \annotatedlist shared +*/ diff --git a/doc/src/corelib/objectmodel/metaobjects.qdoc b/doc/src/corelib/objectmodel/metaobjects.qdoc new file mode 100644 index 0000000000..0a4756f899 --- /dev/null +++ b/doc/src/corelib/objectmodel/metaobjects.qdoc @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page metaobjects.html + \title The Meta-Object System + \brief An overview of Qt's meta-object system and introspection capabilities. + + \ingroup qt-basic-concepts + \keyword meta-object + \target Meta-Object System + + Qt's meta-object system provides the signals and slots mechanism for + inter-object communication, run-time type information, and the dynamic + property system. + + The meta-object system is based on three things: + + \list 1 + \o The \l QObject class provides a base class for objects that can + take advantage of the meta-object system. + \o The Q_OBJECT macro inside the private section of the class + declaration is used to enable meta-object features, such as + dynamic properties, signals, and slots. + \o The \l{moc}{Meta-Object Compiler} (\c moc) supplies each + QObject subclass with the necessary code to implement + meta-object features. + \endlist + + The \c moc tool reads a C++ source file. If it finds one or more + class declarations that contain the Q_OBJECT macro, it + produces another C++ source file which contains the meta-object + code for each of those classes. This generated source file is + either \c{#include}'d into the class's source file or, more + usually, compiled and linked with the class's implementation. + + In addition to providing the \l{signals and slots} mechanism for + communication between objects (the main reason for introducing + the system), the meta-object code provides the following + additional features: + + \list + \o QObject::metaObject() returns the associated + \l{QMetaObject}{meta-object} for the class. + \o QMetaObject::className() returns the class name as a + string at run-time, without requiring native run-time type information + (RTTI) support through the C++ compiler. + \o QObject::inherits() function returns whether an object is an + instance of a class that inherits a specified class within the + QObject inheritance tree. + \o QObject::tr() and QObject::trUtf8() translate strings for + \l{Internationalization with Qt}{internationalization}. + \o QObject::setProperty() and QObject::property() + dynamically set and get properties by name. + \o QMetaObject::newInstance() constructs a new instance of the class. + \endlist + + \target qobjectcast + It is also possible to perform dynamic casts using qobject_cast() + on QObject classes. The qobject_cast() function behaves similarly + to the standard C++ \c dynamic_cast(), with the advantages + that it doesn't require RTTI support and it works across dynamic + library boundaries. It attempts to cast its argument to the pointer + type specified in angle-brackets, returning a non-zero pointer if the + object is of the correct type (determined at run-time), or 0 + if the object's type is incompatible. + + For example, let's assume \c MyWidget inherits from QWidget and + is declared with the Q_OBJECT macro: + + \snippet doc/src/snippets/qtcast/qtcast.cpp 0 + + The \c obj variable, of type \c{QObject *}, actually refers to a + \c MyWidget object, so we can cast it appropriately: + + \snippet doc/src/snippets/qtcast/qtcast.cpp 1 + + The cast from QObject to QWidget is successful, because the + object is actually a \c MyWidget, which is a subclass of QWidget. + Since we know that \c obj is a \c MyWidget, we can also cast it to + \c{MyWidget *}: + + \snippet doc/src/snippets/qtcast/qtcast.cpp 2 + + The cast to \c MyWidget is successful because qobject_cast() + makes no distinction between built-in Qt types and custom types. + + \snippet doc/src/snippets/qtcast/qtcast.cpp 3 + \snippet doc/src/snippets/qtcast/qtcast.cpp 4 + + The cast to QLabel, on the other hand, fails. The pointer is then + set to 0. This makes it possible to handle objects of different + types differently at run-time, based on the type: + + \snippet doc/src/snippets/qtcast/qtcast.cpp 5 + \snippet doc/src/snippets/qtcast/qtcast.cpp 6 + + While it is possible to use QObject as a base class without the + Q_OBJECT macro and without meta-object code, neither signals + and slots nor the other features described here will be available + if the Q_OBJECT macro is not used. From the meta-object + system's point of view, a QObject subclass without meta code is + equivalent to its closest ancestor with meta-object code. This + means for example, that QMetaObject::className() will not return + the actual name of your class, but the class name of this + ancestor. + + Therefore, we strongly recommend that all subclasses of QObject + use the Q_OBJECT macro regardless of whether or not they + actually use signals, slots, and properties. + + \sa QMetaObject, {Qt's Property System}, {Signals and Slots} +*/ diff --git a/doc/src/corelib/objectmodel/object.qdoc b/doc/src/corelib/objectmodel/object.qdoc new file mode 100644 index 0000000000..535c4cc8f2 --- /dev/null +++ b/doc/src/corelib/objectmodel/object.qdoc @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page object.html + \title Object Model + \ingroup qt-basic-concepts + \brief A description of the powerful features made possible by Qt's dynamic object model. + + The standard C++ object model provides very efficient runtime + support for the object paradigm. But its static nature is + inflexibile in certain problem domains. Graphical user interface + programming is a domain that requires both runtime efficiency and + a high level of flexibility. Qt provides this, by combining the + speed of C++ with the flexibility of the Qt Object Model. + + Qt adds these features to C++: + + \list + \o a very powerful mechanism for seamless object + communication called \l{signals and slots} + \o queryable and designable \l{Qt's Property System}{object + properties} + \o powerful \l{The Event System}{events and event filters} + \o contextual \l{i18n}{string translation for internationalization} + \o sophisticated interval driven \l timers that make it possible + to elegantly integrate many tasks in an event-driven GUI + \o hierarchical and queryable \l{Object Trees & Ownership}{object + trees} that organize object ownership in a natural way + \o guarded pointers (QPointer) that are automatically + set to 0 when the referenced object is destroyed, unlike normal C++ + pointers which become dangling pointers when their objects are destroyed + \o a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across + library boundaries. + \endlist + + Many of these Qt features are implemented with standard C++ + techniques, based on inheritance from QObject. Others, like the + object communication mechanism and the dynamic property system, + require the \l{Meta-Object System} provided + by Qt's own \l{moc}{Meta-Object Compiler (moc)}. + + The meta-object system is a C++ extension that makes the language + better suited to true component GUI programming. Although + templates can be used to extend C++, the meta-object system + provides benefits using standard C++ that cannot be achieved with + templates; see \l{Why Doesn't Qt Use Templates for Signals and + Slots?} + + \section1 Important Classes + + These classes form the basis of the Qt Object Model. + + \annotatedlist objectmodel + + \target Identity vs Value + \section1 Qt Objects: Identity vs Value + + Some of the added features listed above for the Qt Object Model, + require that we think of Qt Objects as identities, not values. + Values are copied or assigned; identities are cloned. Cloning + means to create a new identity, not an exact copy of the old + one. For example, twins have different identities. They may look + identical, but they have different names, different locations, and + may have completely different social networks. + + Then cloning an identity is a more complex operation than copying + or assigning a value. We can see what this means in the Qt Object + Model. + + \bold{A Qt Object...} + + \list + + \o might have a unique \l{QObject::objectName()}. If we copy a Qt + Object, what name should we give the copy? + + \o has a location in an \l{Object Trees & Ownership} + {object hierarchy}. If we copy a Qt Object, where should the copy + be located? + + \o can be connected to other Qt Objects to emit signals to them or + to receive signals emitted by them. If we copy a Qt Object, how + should we transfer these connections to the copy? + + \o can have \l{Qt's Property System} {new properties} added to it + at runtime that are not declared in the C++ class. If we copy a Qt + Object, should the copy include the properties that were added to + the original? + + \endlist + + For these reasons, Qt Objects should be treated as identities, not + as values. Identities are cloned, not copied or assigned, and + cloning an identity is a more complex operation than copying or + assigning a value. Therefore, QObject and all subclasses of + QObject (direct or indirect) have their \l{No copy constructor} + {copy constructor and assignment operator} disabled. + + */ diff --git a/doc/src/corelib/objectmodel/objecttrees.qdoc b/doc/src/corelib/objectmodel/objecttrees.qdoc new file mode 100644 index 0000000000..d8f9501748 --- /dev/null +++ b/doc/src/corelib/objectmodel/objecttrees.qdoc @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page objecttrees.html + \title Object Trees & Ownership + \ingroup qt-basic-concepts + \brief Information about the parent-child pattern used to describe + object ownership in Qt. + + \section1 Overview + + \link QObject QObjects\endlink organize themselves in object trees. + When you create a QObject with another object as parent, it's added to + the parent's \link QObject::children() children() \endlink list, and + is deleted when the parent is. It turns out that this approach fits + the needs of GUI objects very well. For example, a \l QShortcut + (keyboard shortcut) is a child of the relevant window, so when the + user closes that window, the shorcut is deleted too. + + \l QWidget, the base class of everything that appears on the screen, + extends the parent-child relationship. A child normally also becomes a + child widget, i.e. it is displayed in its parent's coordinate system + and is graphically clipped by its parent's boundaries. For example, + when the application deletes a message box after it has been + closed, the message box's buttons and label are also deleted, just as + we'd want, because the buttons and label are children of the message + box. + + You can also delete child objects yourself, and they will remove + themselves from their parents. For example, when the user removes a + toolbar it may lead to the application deleting one of its \l QToolBar + objects, in which case the tool bar's \l QMainWindow parent would + detect the change and reconfigure its screen space accordingly. + + The debugging functions \l QObject::dumpObjectTree() and \l + QObject::dumpObjectInfo() are often useful when an application looks or + acts strangely. + + \target note on the order of construction/destruction of QObjects + \section1 Construction/Destruction Order of QObjects + + When \l {QObject} {QObjects} are created on the heap (i.e., created + with \e new), a tree can be constructed from them in any order, and + later, the objects in the tree can be destroyed in any order. When any + QObject in the tree is deleted, if the object has a parent, the + destructor automatically removes the object from its parent. If the + object has children, the destructor automatically deletes each + child. No QObject is deleted twice, regardless of the order of + destruction. + + When \l {QObject} {QObjects} are created on the stack, the same + behavior applies. Normally, the order of destruction still doesn't + present a problem. Consider the following snippet: + + \snippet doc/src/snippets/code/doc_src_objecttrees.cpp 0 + + The parent, \c window, and the child, \c quit, are both \l {QObject} + {QObjects} because QPushButton inherits QWidget, and QWidget inherits + QObject. This code is correct: the destructor of \c quit is \e not + called twice because the C++ language standard \e {(ISO/IEC 14882:2003)} + specifies that destructors of local objects are called in the reverse + order of their constructors. Therefore, the destructor of + the child, \c quit, is called first, and it removes itself from its + parent, \c window, before the destructor of \c window is called. + + But now consider what happens if we swap the order of construction, as + shown in this second snippet: + + \snippet doc/src/snippets/code/doc_src_objecttrees.cpp 1 + + In this case, the order of destruction causes a problem. The parent's + destructor is called first because it was created last. It then calls + the destructor of its child, \c quit, which is incorrect because \c + quit is a local variable. When \c quit subsequently goes out of scope, + its destructor is called again, this time correctly, but the damage has + already been done. +*/ diff --git a/doc/src/corelib/objectmodel/properties.qdoc b/doc/src/corelib/objectmodel/properties.qdoc new file mode 100644 index 0000000000..0350f19be4 --- /dev/null +++ b/doc/src/corelib/objectmodel/properties.qdoc @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page properties.html + \title The Property System + \brief An overview of Qt's property system. + + \ingroup qt-basic-concepts + \target Qt's Property System + + Qt provides a sophisticated property system similar to the ones + supplied by some compiler vendors. However, as a compiler- and + platform-independent library, Qt does not rely on non-standard + compiler features like \c __property or \c [property]. The Qt + solution works with \e any standard C++ compiler on every platform + Qt supports. It is based on the \l {Meta-Object System} that also + provides inter-object communication via \l{signals and slots}. + + \section1 Requirements for Declaring Properties + + To declare a property, use the \l {Q_PROPERTY()} {Q_PROPERTY()} + macro in a class that inherits QObject. + + \snippet doc/src/snippets/code/doc_src_properties.cpp 0 + + Here are some typical examples of property declarations taken from + class QWidget. + + \snippet doc/src/snippets/code/doc_src_properties.cpp 1 + + A property behaves like a class data member, but it has additional + features accessible through the \l {Meta-Object System}. + + \list + + \o A \c READ accessor function is required. It is for reading the + property value. Ideally, a const function is used for this purpose, + and it must return either the property's type or a pointer or + reference to that type. e.g., QWidget::focus is a read-only property + with \c READ function, QWidget::hasFocus(). + + \o A \c WRITE accessor function is optional. It is for setting the + property value. It must return void and must take exactly one + argument, either of the property's type or a pointer or reference + to that type. e.g., QWidget::enabled has the \c WRITE function + QWidget::setEnabled(). Read-only properties do not need \c WRITE + functions. e.g., QWidget::focus has no \c WRITE function. + + \o A \c RESET function is optional. It is for setting the property + back to its context specific default value. e.g., QWidget::cursor + has the typical \c READ and \c WRITE functions, QWidget::cursor() + and QWidget::setCursor(), and it also has a \c RESET function, + QWidget::unsetCursor(), since no call to QWidget::setCursor() can + mean \e {reset to the context specific cursor}. The \c RESET + function must return void and take no parameters. + + \o A \c NOTIFY signal is optional. If defined, it should specify one + existing signal in that class that is emitted whenever the value + of the property changes. + + \o A \c REVISION number is optional. If included, it defines the + the property and its notifier signal to be used in a particular + revision of the API that is exposed to QML. + + \o The \c DESIGNABLE attribute indicates whether the property + should be visible in the property editor of GUI design tool (e.g., + \l {Qt Designer}). Most properties are \c DESIGNABLE (default + true). Instead of true or false, you can specify a boolean + member function. + + \o The \c SCRIPTABLE attribute indicates whether this property + should be accessible by a scripting engine (default true). + Instead of true or false, you can specify a boolean member + function. + + \o The \c STORED attribute indicates whether the property should + be thought of as existing on its own or as depending on other + values. It also indicates whether the property value must be saved + when storing the object's state. Most properties are \c STORED + (default true), but e.g., QWidget::minimumWidth() has \c STORED + false, because its value is just taken from the width component + of property QWidget::minimumSize(), which is a QSize. + + \o The \c USER attribute indicates whether the property is + designated as the user-facing or user-editable property for the + class. Normally, there is only one \c USER property per class + (default false). e.g., QAbstractButton::checked is the user + editable property for (checkable) buttons. Note that QItemDelegate + gets and sets a widget's \c USER property. + + \o The presence of the \c CONSTANT attibute indicates that the property + value is constant. For a given object instance, the READ method of a + constant property must return the same value every time it is called. This + constant value may be different for different instances of the object. A + constant property cannot have a WRITE method or a NOTIFY signal. + + \o The presence of the \c FINAL attribute indicates that the property + will not be overridden by a derived class. This can be used for performance + optimizations in some cases, but is not enforced by moc. Care must be taken + never to override a \c FINAL property. + + \endlist + + The \c READ, \c WRITE, and \c RESET functions can be inherited. + They can also be virtual. When they are inherited in classes where + multiple inheritance is used, they must come from the first + inherited class. + + The property type can be any type supported by QVariant, or it can + be a user-defined type. In this example, class QDate is considered + to be a user-defined type. + + \snippet doc/src/snippets/code/doc_src_properties.cpp 2 + + Because QDate is user-defined, you must include the \c{} + header file with the property declaration. + + For QMap, QList, and QValueList properties, the property value is + a QVariant whose value is the entire list or map. Note that the + Q_PROPERTY string cannot contain commas, because commas separate + macro arguments. Therefore, you must use \c QMap as the property + type instead of \c QMap. For consistency, also + use \c QList and \c QValueList instead of \c QList and + \c QValueList. + + \section1 Reading and Writing Properties with the Meta-Object System + + A property can be read and written using the generic functions + QObject::property() and QObject::setProperty(), without knowing + anything about the owning class except the property's name. In + the code snippet below, the call to QAbstractButton::setDown() and + the call to QObject::setProperty() both set property "down". + + \snippet doc/src/snippets/code/doc_src_properties.cpp 3 + + Accessing a property through its \c WRITE accessor is the better + of the two, because it is faster and gives better diagnostics at + compile time, but setting the property this way requires that you + know about the class at compile time. Accessing properties by name + lets you access classes you don't know about at compile time. You + can \e discover a class's properties at run time by querying its + QObject, QMetaObject, and \l {QMetaProperty} {QMetaProperties}. + + \snippet doc/src/snippets/code/doc_src_properties.cpp 4 + + In the above snippet, QMetaObject::property() is used to get \l + {QMetaProperty} {metadata} about each property defined in some + unknown class. The property name is fetched from the metadata and + passed to QObject::property() to get the \l {QVariant} {value} of + the property in the current \l {QObject}{object}. + + \section1 A Simple Example + + Suppose we have a class MyClass, which is derived from QObject and + which uses the Q_OBJECT macro in its private section. We want to + declare a property in MyClass to keep track of a priorty + value. The name of the property will be \e priority, and its type + will be an enumeration type named \e Priority, which is defined in + MyClass. + + We declare the property with the Q_PROPERTY() macro in the private + section of the class. The required \c READ function is named \c + priority, and we include a \c WRITE function named \c setPriority. + The enumeration type must be registered with the \l {Meta-Object + System} using the Q_ENUMS() macro. Registering an enumeration type + makes the enumerator names available for use in calls to + QObject::setProperty(). We must also provide our own declarations + for the \c READ and \c WRITE functions. The declaration of MyClass + then might look like this: + + \snippet doc/src/snippets/code/doc_src_properties.cpp 5 + + The \c READ function is const and returns the property type. The + \c WRITE function returns void and has exactly one parameter of + the property type. The meta-object compiler enforces these + requirements. + + Given a pointer to an instance of MyClass or a pointer to a + QObject that is an instance of MyClass, we have two ways to set + its priority property: + + \snippet doc/src/snippets/code/doc_src_properties.cpp 6 + + In the example, the enumeration type that is the property type is + declared in MyClass and registered with the \l{Meta-Object System} + using the Q_ENUMS() macro. This makes the enumeration values + available as strings for use as in the call to setProperty(). Had + the enumeration type been declared in another class, its fully + qualified name (i.e., OtherClass::Priority) would be required, and + that other class would also have to inherit QObject and register + the enumeration type there using the Q_ENUMS() macro. + + A similar macro, Q_FLAGS(), is also available. Like Q_ENUMS(), it + registers an enumeration type, but it marks the type as being a + set of \e flags, i.e. values that can be OR'd together. An I/O + class might have enumeration values \c Read and \c Write and then + QObject::setProperty() could accept \c{Read | Write}. Q_FLAGS() + should be used to register this enumeration type. + + \section1 Dynamic Properties + + QObject::setProperty() can also be used to add \e new properties + to an instance of a class at runtime. When it is called with a + name and a value, if a property with the given name exists in the + QObject, and if the given value is compatible with the property's + type, the value is stored in the property, and true is returned. + If the value is \e not compatible with the property's type, the + property is \e not changed, and false is returned. But if the + property with the given name doesn't exist in the QObject (i.e., + if it wasn't declared with Q_PROPERTY(), a new property with the + given name and value is automatically added to the QObject, but + false is still returned. This means that a return of false can't + be used to determine whether a particular property was actually + set, unless you know in advance that the property already exists + in the QObject. + + Note that \e dynamic properties are added on a per instance basis, + i.e., they are added to QObject, not QMetaObject. A property can + be removed from an instance by passing the property name and an + invalid QVariant value to QObject::setProperty(). The default + constructor for QVariant constructs an invalid QVariant. + + Dynamic properties can be queried with QObject::property(), just + like properties declared at compile time with Q_PROPERTY(). + + \sa {Meta-Object System}, {Signals and Slots} + + \section1 Properties and Custom Types + + Custom types used by properties need to be registered using the + Q_DECLARE_METATYPE() macro so that their values can be stored in + QVariant objects. This makes them suitable for use with both + static properties declared using the Q_PROPERTY() macro in class + definitions and dynamic properties created at run-time. + + \sa Q_DECLARE_METATYPE(), QMetaType, QVariant + + \section1 Adding Additional Information to a Class + + Connected to the property system is an additional macro, + Q_CLASSINFO(), that can be used to attach additional + \e{name}--\e{value} pairs to a class's meta-object, for example: + + \snippet doc/src/snippets/code/doc_src_properties.cpp 7 + + Like other meta-data, class information is accessible at run-time + through the meta-object; see QMetaObject::classInfo() for details. +*/ diff --git a/doc/src/corelib/objectmodel/signalsandslots.qdoc b/doc/src/corelib/objectmodel/signalsandslots.qdoc new file mode 100644 index 0000000000..f976e74c7d --- /dev/null +++ b/doc/src/corelib/objectmodel/signalsandslots.qdoc @@ -0,0 +1,468 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page signalsandslots.html + \title Signals & Slots + \ingroup qt-basic-concepts + \brief An overview of Qt's signals and slots inter-object + communication mechanism. + + Signals and slots are used for communication between objects. The + signals and slots mechanism is a central feature of Qt and + probably the part that differs most from the features provided by + other frameworks. + + \tableofcontents + + \section1 Introduction + + In GUI programming, when we change one widget, we often want + another widget to be notified. More generally, we want objects of + any kind to be able to communicate with one another. For example, + if a user clicks a \gui{Close} button, we probably want the + window's \l{QWidget::close()}{close()} function to be called. + + Older toolkits achieve this kind of communication using + callbacks. A callback is a pointer to a function, so if you want + a processing function to notify you about some event you pass a + pointer to another function (the callback) to the processing + function. The processing function then calls the callback when + appropriate. Callbacks have two fundamental flaws: Firstly, they + are not type-safe. We can never be certain that the processing + function will call the callback with the correct arguments. + Secondly, the callback is strongly coupled to the processing + function since the processing function must know which callback + to call. + + \section1 Signals and Slots + + In Qt, we have an alternative to the callback technique: We use + signals and slots. A signal is emitted when a particular event + occurs. Qt's widgets have many predefined signals, but we can + always subclass widgets to add our own signals to them. A slot + is a function that is called in response to a particular signal. + Qt's widgets have many pre-defined slots, but it is common + practice to subclass widgets and add your own slots so that you + can handle the signals that you are interested in. + + \img abstract-connections.png + \omit + \caption An abstract view of some signals and slots connections + \endomit + + The signals and slots mechanism is type safe: The signature of a + signal must match the signature of the receiving slot. (In fact a + slot may have a shorter signature than the signal it receives + because it can ignore extra arguments.) Since the signatures are + compatible, the compiler can help us detect type mismatches. + Signals and slots are loosely coupled: A class which emits a + signal neither knows nor cares which slots receive the signal. + Qt's signals and slots mechanism ensures that if you connect a + signal to a slot, the slot will be called with the signal's + parameters at the right time. Signals and slots can take any + number of arguments of any type. They are completely type safe. + + All classes that inherit from QObject or one of its subclasses + (e.g., QWidget) can contain signals and slots. Signals are emitted by + objects when they change their state in a way that may be interesting + to other objects. This is all the object does to communicate. It + does not know or care whether anything is receiving the signals it + emits. This is true information encapsulation, and ensures that the + object can be used as a software component. + + Slots can be used for receiving signals, but they are also normal + member functions. Just as an object does not know if anything receives + its signals, a slot does not know if it has any signals connected to + it. This ensures that truly independent components can be created with + Qt. + + You can connect as many signals as you want to a single slot, and a + signal can be connected to as many slots as you need. It is even + possible to connect a signal directly to another signal. (This will + emit the second signal immediately whenever the first is emitted.) + + Together, signals and slots make up a powerful component programming + mechanism. + + \section1 A Small Example + + A minimal C++ class declaration might read: + + \snippet doc/src/snippets/signalsandslots/signalsandslots.h 0 + + A small QObject-based class might read: + + \snippet doc/src/snippets/signalsandslots/signalsandslots.h 1 + \codeline + \snippet doc/src/snippets/signalsandslots/signalsandslots.h 2 + \snippet doc/src/snippets/signalsandslots/signalsandslots.h 3 + + The QObject-based version has the same internal state, and provides + public methods to access the state, but in addition it has support + for component programming using signals and slots. This class can + tell the outside world that its state has changed by emitting a + signal, \c{valueChanged()}, and it has a slot which other objects + can send signals to. + + All classes that contain signals or slots must mention + Q_OBJECT at the top of their declaration. They must also derive + (directly or indirectly) from QObject. + + Slots are implemented by the application programmer. + Here is a possible implementation of the \c{Counter::setValue()} + slot: + + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 0 + + The \c{emit} line emits the signal \c valueChanged() from the + object, with the new value as argument. + + In the following code snippet, we create two \c Counter objects + and connect the first object's \c valueChanged() signal to the + second object's \c setValue() slot using QObject::connect(): + + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 1 + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 2 + \codeline + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 3 + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 4 + + Calling \c{a.setValue(12)} makes \c{a} emit a + \c{valueChanged(12)} signal, which \c{b} will receive in its + \c{setValue()} slot, i.e. \c{b.setValue(12)} is called. Then + \c{b} emits the same \c{valueChanged()} signal, but since no slot + has been connected to \c{b}'s \c{valueChanged()} signal, the + signal is ignored. + + Note that the \c{setValue()} function sets the value and emits + the signal only if \c{value != m_value}. This prevents infinite + looping in the case of cyclic connections (e.g., if + \c{b.valueChanged()} were connected to \c{a.setValue()}). + + By default, for every connection you make, a signal is emitted; + two signals are emitted for duplicate connections. You can break + all of these connections with a single disconnect() call. + If you pass the Qt::UniqueConnection \a type, the connection will only + be made if it is not a duplicate. If there is already a duplicate + (exact same signal to the exact same slot on the same objects), + the connection will fail and connect will return false + + This example illustrates that objects can work together without needing to + know any information about each other. To enable this, the objects only + need to be connected together, and this can be achieved with some simple + QObject::connect() function calls, or with \c{uic}'s + \l{Using a Designer UI File in Your Application#Automatic Connections} + {automatic connections} feature. + + \section1 Building the Example + + The C++ preprocessor changes or removes the \c{signals}, + \c{slots}, and \c{emit} keywords so that the compiler is + presented with standard C++. + + By running the \l moc on class definitions that contain signals + or slots, a C++ source file is produced which should be compiled + and linked with the other object files for the application. If + you use \l qmake, the makefile rules to automatically invoke \c + moc will be added to your project's makefile. + + \section1 Signals + + Signals are emitted by an object when its internal state has changed + in some way that might be interesting to the object's client or owner. + Signals are public access functions and can be emitted from anywhere, + but we recommend to only emit them from the class that defines the + signal and its subclasses. + + When a signal is emitted, the slots connected to it are usually + executed immediately, just like a normal function call. When this + happens, the signals and slots mechanism is totally independent of + any GUI event loop. Execution of the code following the \c emit + statement will occur once all slots have returned. The situation is + slightly different when using \l{Qt::ConnectionType}{queued + connections}; in such a case, the code following the \c emit keyword + will continue immediately, and the slots will be executed later. + + If several slots are connected to one signal, the slots will be + executed one after the other, in the order they have been connected, + when the signal is emitted. + + Signals are automatically generated by the \l moc and must not be + implemented in the \c .cpp file. They can never have return types + (i.e. use \c void). + + A note about arguments: Our experience shows that signals and slots + are more reusable if they do not use special types. If + QScrollBar::valueChanged() were to use a special type such as the + hypothetical QScrollBar::Range, it could only be connected to + slots designed specifically for QScrollBar. Connecting different + input widgets together would be impossible. + + \section1 Slots + + A slot is called when a signal connected to it is emitted. Slots are + normal C++ functions and can be called normally; their only special + feature is that signals can be connected to them. + + Since slots are normal member functions, they follow the normal C++ + rules when called directly. However, as slots, they can be invoked + by any component, regardless of its access level, via a signal-slot + connection. This means that a signal emitted from an instance of an + arbitrary class can cause a private slot to be invoked in an instance + of an unrelated class. + + You can also define slots to be virtual, which we have found quite + useful in practice. + + Compared to callbacks, signals and slots are slightly slower + because of the increased flexibility they provide, although the + difference for real applications is insignificant. In general, + emitting a signal that is connected to some slots, is + approximately ten times slower than calling the receivers + directly, with non-virtual function calls. This is the overhead + required to locate the connection object, to safely iterate over + all connections (i.e. checking that subsequent receivers have not + been destroyed during the emission), and to marshall any + parameters in a generic fashion. While ten non-virtual function + calls may sound like a lot, it's much less overhead than any \c + new or \c delete operation, for example. As soon as you perform a + string, vector or list operation that behind the scene requires + \c new or \c delete, the signals and slots overhead is only + responsible for a very small proportion of the complete function + call costs. The same is true whenever you do a system call in a slot; + or indirectly call more than ten functions. + The simplicity and flexibility of the signals and slots mechanism is + well worth the overhead, which your users won't even notice. + + Note that other libraries that define variables called \c signals + or \c slots may cause compiler warnings and errors when compiled + alongside a Qt-based application. To solve this problem, \c + #undef the offending preprocessor symbol. + + \section1 Meta-Object Information + + The meta-object compiler (\l moc) parses the class declaration in + a C++ file and generates C++ code that initializes the + meta-object. The meta-object contains the names of all the signal + and slot members, as well as pointers to these functions. + + The meta-object contains additional information such as the + object's \link QObject::className() class name\endlink. You can + also check if an object \link QObject::inherits() + inherits\endlink a specific class, for example: + + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 5 + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 6 + + The meta-object information is also used by qobject_cast(), which + is similar to QObject::inherits() but is less error-prone: + + \snippet doc/src/snippets/signalsandslots/signalsandslots.cpp 7 + + See \l{Meta-Object System} for more information. + + \section1 A Real Example + + Here is a simple commented example of a widget. + + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 0 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 1 + \codeline + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 2 + \codeline + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 3 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 4 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 5 + + \c LcdNumber inherits QObject, which has most of the signal-slot + knowledge, via QFrame and QWidget. It is somewhat similar to the + built-in QLCDNumber widget. + + The Q_OBJECT macro is expanded by the preprocessor to declare + several member functions that are implemented by the \c{moc}; if + you get compiler errors along the lines of "undefined reference + to vtable for \c{LcdNumber}", you have probably forgotten to + \l{moc}{run the moc} or to include the moc output in the link + command. + + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 6 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 7 + + It's not obviously relevant to the moc, but if you inherit + QWidget you almost certainly want to have the \c parent argument + in your constructor and pass it to the base class's constructor. + + Some destructors and member functions are omitted here; the \c + moc ignores member functions. + + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 8 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 9 + + \c LcdNumber emits a signal when it is asked to show an impossible + value. + + If you don't care about overflow, or you know that overflow + cannot occur, you can ignore the \c overflow() signal, i.e. don't + connect it to any slot. + + If on the other hand you want to call two different error + functions when the number overflows, simply connect the signal to + two different slots. Qt will call both (in the order they were connected). + + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 10 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 11 + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 12 + \codeline + \snippet doc/src/snippets/signalsandslots/lcdnumber.h 13 + + A slot is a receiving function used to get information about + state changes in other widgets. \c LcdNumber uses it, as the code + above indicates, to set the displayed number. Since \c{display()} + is part of the class's interface with the rest of the program, + the slot is public. + + Several of the example programs connect the + \l{QScrollBar::valueChanged()}{valueChanged()} signal of a + QScrollBar to the \c display() slot, so the LCD number + continuously shows the value of the scroll bar. + + Note that \c display() is overloaded; Qt will select the + appropriate version when you connect a signal to the slot. With + callbacks, you'd have to find five different names and keep track + of the types yourself. + + Some irrelevant member functions have been omitted from this + example. + + \section1 Signals And Slots With Default Arguments + + The signatures of signals and slots may contain arguments, and the + arguments can have default values. Consider QObject::destroyed(): + + \code + void destroyed(QObject* = 0); + \endcode + + When a QObject is deleted, it emits this QObject::destroyed() + signal. We want to catch this signal, wherever we might have a + dangling reference to the deleted QObject, so we can clean it up. + A suitable slot signature might be: + + \code + void objectDestroyed(QObject* obj = 0); + \endcode + + To connect the signal to the slot, we use QObject::connect(). + There are several ways to connect signal and slots. The first is to use + function pointers: + \code + connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed); + \endcode + + There are several advantages to using connect() with function pointers. + First, it allows the compiler to check that the signal's arguments are + compatible with the slot's arguments. Arguments can also be implicitly + converted by the compiler, if needed. + + You can also connect to functors or C++11 lamdas: + + \code + connect(sender, &QObject::destroyed, [=](){ this->m_objects.remove(sender); }); + \endcode + + Note that if your compiler does not support C++11 variadic templates, + this syntax only works if the signal and slot have 6 arguments or less. + + The other way to connect a signal to a slot is to use QObject::connect() + and the \c{SIGNAL} and \c{SLOT} macros. + The rule about whether to + include arguments or not in the \c{SIGNAL()} and \c{SLOT()} + macros, if the arguments have default values, is that the + signature passed to the \c{SIGNAL()} macro must \e not have fewer + arguments than the signature passed to the \c{SLOT()} macro. + + All of these would work: + \code + connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*))); + connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed())); + connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed())); + \endcode + But this one won't work: + \code + connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*))); + \endcode + + ...because the slot will be expecting a QObject that the signal + will not send. This connection will report a runtime error. + + Note that signal and slot arguments are not checked by the compiler when + using this QObject::connect() overload. + + \section1 Advanced Signals and Slots Usage + + For cases where you may require information on the sender of the + signal, Qt provides the QObject::sender() function, which returns + a pointer to the object that sent the signal. + + The QSignalMapper class is provided for situations where many + signals are connected to the same slot and the slot needs to + handle each signal differently. + + Suppose you have three push buttons that determine which file you + will open: "Tax File", "Accounts File", or "Report File". + + In order to open the correct file, you use QSignalMapper::setMapping() to + map all the clicked() signals to a QSignalMapper object. Then you connect + the file's QPushButton::clicked() signal to the QSignalMapper::map() slot. + + \snippet doc/src/snippets/signalmapper/filereader.cpp 0 + + Then, you connect the \l{QSignalMapper::}{mapped()} signal to + \c{readFile()} where a different file will be opened, depending on + which push button is pressed. + + \snippet doc/src/snippets/signalmapper/filereader.cpp 1 + + \sa {Meta-Object System}, {Qt's Property System} + + \target 3rd Party Signals and Slots + \section2 Using Qt with 3rd Party Signals and Slots + + It is possible to use Qt with a 3rd party signal/slot mechanism. + You can even use both mechanisms in the same project. Just add the + following line to your qmake project (.pro) file. + + \snippet doc/src/snippets/code/doc_src_containers.cpp 22 + + It tells Qt not to define the moc keywords \c{signals}, \c{slots}, + and \c{emit}, because these names will be used by a 3rd party + library, e.g. Boost. Then to continue using Qt signals and slots + with the \c{no_keywords} flag, simply replace all uses of the Qt + moc keywords in your sources with the corresponding Qt macros + Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT. +*/ diff --git a/doc/src/corelib/qtcore.qdoc b/doc/src/corelib/qtcore.qdoc new file mode 100644 index 0000000000..0d1654c9f0 --- /dev/null +++ b/doc/src/corelib/qtcore.qdoc @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtCore + \title QtCore Module + \ingroup modules + + \keyword QtCore + + \brief The QtCore module contains core non-GUI functionality. + + All other Qt modules rely on this module. To include the + definitions of the module's classes, use the following directive: + + \snippet doc/src/snippets/code/doc_src_qtcore.cpp 0 +*/ + diff --git a/doc/src/corelib/threads-basics.qdoc b/doc/src/corelib/threads-basics.qdoc new file mode 100644 index 0000000000..547c7fc50c --- /dev/null +++ b/doc/src/corelib/threads-basics.qdoc @@ -0,0 +1,572 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page thread-basics.html + \ingroup tutorials + \startpage {index.html}{Qt Reference Documentation} + + \title Threading Basics + \brief An introduction to threads + + \section1 What Are Threads? + + Threads are about doing things in parallel, just like processes. So how do + threads differ from processes? While you are making calculations on a + spreadsheet, there may also be a media player running on the same desktop + playing your favorite song. Here is an example of two processes working in + parallel: one running the spreadsheet program; one running a media player. + Multitasking is a well known term for this. A closer look at the media + player reveals that there are again things going on in parallel within one + single process. While the media player is sending music to the audio driver, + the user interface with all its bells and whistles is being constantly + updated. This is what threads are for \mdash concurrency within one single + process. + + So how is concurrency implemented? Parallel work on single core CPUs is an + illusion which is somewhat similar to the illusion of moving images in + cinema. + For processes, the illusion is produced by interrupting the processor's + work on one process after a very short time. Then the processor moves on to + the next process. In order to switch between processes, the current program + counter is saved and the next processor's program counter is loaded. This + is not sufficient because the same needs to be done with registers and + certain architecture and OS specific data. + + Just as one CPU can power two or more processes, it is also possible to let + the CPU run on two different code segments of one single process. When a + process starts, it always executes one code segment and therefore the + process is said to have one thread. However, the program may decide to + start a second thread. Then, two different code sequences are processed + simultaneously inside one process. Concurrency is achieved on single core + CPUs by repeatedly saving program counters and registers then loading the + next thread's program counters and registers. No cooperation from the + program is required to cycle between the active threads. A thread may be in + any state when the switch to the next thread occurs. + + The current trend in CPU design is to have several cores. A typical + single-threaded application can make use of only one core. However, a + program with multiple threads can be assigned to multiple cores, making + things happen in a truly concurrent way. As a result, distributing work + to more than one thread can make a program run much faster on multicore + CPUs because additional cores can be used. + + \section2 GUI Thread and Worker Thread + + As mentioned, each program has one thread when it is started. This thread + is called the "main thread" (also known as the "GUI thread" in Qt + applications). The Qt GUI must run in this thread. All widgets and several + related classes, for example QPixmap, don't work in secondary threads. + A secondary thread is commonly referred to as a "worker thread" because it + is used to offload processing work from the main thread. + + \section2 Simultaneous Access to Data + + Each thread has its own stack, which means each thread has its own call + history and local variables. Unlike processes, threads share the same + address space. The following diagram shows how the building blocks of + threads are located in memory. Program counter and registers of inactive + threads are typically kept in kernel space. There is a shared copy of the + code and a separate stack for each thread. + + \image threadvisual-example.png "Thread visualization" + + If two threads have a pointer to the same object, it is possible that both + threads will access that object at the same time and this can potentially + destroy the object's integrity. It's easy to imagine the many things that + can go wrong when two methods of the same object are executed + simultaneously. + + Sometimes it is necessary to access one object from different threads; + for example, when objects living in different threads need to communicate. + Since threads use the same address space, it is easier and faster for + threads to exchange data than it is for processes. Data does not have to be + serialized and copied. Passing pointers is possible, but there must be a + strict coordination of what thread touches which object. Simultaneous + execution of operations on one object must be prevented. There are several + ways of achieving this and some of them are described below. + + So what can be done safely? All objects created in a thread can be used + safely within that thread provided that other threads don't have references + to them and objects don't have implicit coupling with other threads. Such + implicit coupling may happen when data is shared between instances as with + static members, singletons or global data. Familiarize yourself with the + concept of \l{Reentrancy and Thread-Safety}{thread safe and reentrant} + classes and functions. + + \section1 Using Threads + + There are basically two use cases for threads: + + \list + \o Make processing faster by making use of multicore processors. + \o Keep the GUI thread or other time critical threads responsive by + offloading long lasting processing or blocking calls to other threads. + \endlist + + \section2 When to Use Alternatives to Threads + + Developers need to be very careful with threads. It is easy to start other + threads, but very hard to ensure that all shared data remains consistent. + Problems are often hard to find because they may only show up once in a + while or only on specific hardware configurations. Before creating threads + to solve certain problems, possible alternatives should be considered. + + \table + \header + \o Alternative + \o Comment + \row + \o QEventLoop::processEvents() + \o Calling QEventLoop::processEvents() repeatedly during a + time-consuming calculation prevents GUI blocking. However, this + solution doesn't scale well because the call to processEvents() may + occur too often, or not often enough, depending on hardware. + \row + \o QTimer + \o Background processing can sometimes be done conveniently using a + timer to schedule execution of a slot at some point in the future. + A timer with an interval of 0 will time out as soon as there are no + more events to process. + \row + \o QSocketNotifier QNetworkAccessManager QIODevice::readyRead() + \o This is an alternative to having one or multiple threads, each with + a blocking read on a slow network connection. As long as the + calculation in response to a chunk of network data can be executed + quickly, this reactive design is better than synchronous waiting in + threads. Reactive design is less error prone and energy efficient + than threading. In many cases there are also performance benefits. + \endtable + + In general, it is recommended to only use safe and tested paths and to + avoid introducing ad-hoc threading concepts. QtConcurrent provides an easy + interface for distributing work to all of the processor's cores. The + threading code is completely hidden in the QtConcurrent framework, so you + don't have to take care of the details. However, QtConcurrent can't be used + when communication with the running thread is needed, and it shouldn't be + used to handle blocking operations. + + \section2 Which Qt Thread Technology Should You Use? + + Sometimes you want to do more than just running a method in the context of + another thread. You may want to have an object which lives in another + thread that provides a service to the GUI thread. Maybe you want another + thread to stay alive forever to poll hardware ports and send a signal to + the GUI thread when something noteworthy has happened. Qt provides + different solutions for developing threaded applications. The right + solution depends on the purpose of the new thread as well as on the + thread's lifetime. + + \table + \header + \o Lifetime of thread + \o Development task + \o Solution + \row + \o One call + \o Run one method within another thread and quit the thread when the + method is finished. + \o Qt provides different solutions: + \list + \o Write a function and run it with QtConcurrent::run() + \o Derive a class from QRunnable and run it in the global thread + pool with QThreadPool::globalInstance()->start() + \o Derive a class from QThread, reimplement the QThread::run() + method and use QThread::start() to run it. + \endlist + + \row + \o One call + \o Operations are to be performed on all items of a container. + Processing should be performed using all available cores. A common + example is to produce thumbnails from a list of images. + \o QtConcurrent provides the \l{QtConcurrent::}{map()} function for + applying operations on every container element, + \l{QtConcurrent::}{filter()} for selecting container elements, and + the option of specifying a reduce function for combining the + remaining elements. + \row + \o One call + \o A long running operation has to be put in another thread. During the + course of processing, status information should be sent to the GUI + thread. + \o Use QThread, reimplement run and emit signals as needed. Connect the + signals to the GUI thread's slots using queued signal/slot + connections. + + \row + \o Permanent + \o Have an object living in another thread and let it perform different + tasks upon request. + This means communication to and from the worker thread is required. + \o Derive a class from QObject and implement the necessary slots and + signals, move the object to a thread with a running event loop and + communicate with the object over queued signal/slot connections. + \row + \o Permanent + \o Have an object living in another thread, let the object perform + repeated tasks such as polling a port and enable communication with + the GUI thread. + \o Same as above but also use a timer in the worker thread to implement + polling. However, the best solution for polling is to avoid it + completely. Sometimes using QSocketNotifier is an alternative. + \endtable + + + \section1 Qt Thread Basics + + QThread is a very convenient cross platform abstraction of native platform + threads. Starting a thread is very simple. Let us look at a short piece of + code that generates another thread which says hello in that thread and then + exits. + + \snippet examples/tutorials/threads/hellothread/hellothread.h 1 + + We derive a class from QThread and reimplement the \l{QThread::}{run()} + method. + + \snippet examples/tutorials/threads/hellothread/hellothread.cpp 1 + + The run method contains the code that will be run in a separate thread. In + this example, a message containing the thread ID will be printed. + QThread::start() will call the method in another thread. + + \snippet examples/tutorials/threads/hellothread/main.cpp 1 + + To start the thread, our thread object needs to be instantiated. The + \l{QThread::}{start()} method creates a new thread and calls the + reimplemented \l{QThread::}{run()} method in this new thread. Right after + \l{QThread::}{start()} is called, two program counters walk through the + program code. The main function starts with only the GUI thread running and + it should terminate with only the GUI thread running. Exiting the program + when another thread is still busy is a programming error, and therefore, + wait is called which blocks the calling thread until the + \l{QThread::}{run()} method has completed. + + This is the result of running the code: + + \badcode + hello from GUI thread 3079423696 + hello from worker thread 3076111216 + \endcode + + + \section2 QObject and Threads + + A QObject is said to have a \e{thread affinity} or, in other words, that it + lives in a certain thread. This means that, at creation time, QObject saves + a pointer to the current thread. This information becomes relevant when an + event is posted with \l{QCoreApplication::}{postEvent()}. The event will be + put in the corresponding thread's event loop. If the thread where the + QObject lives doesn't have an event loop, the event will never be delivered. + + To start an event loop, \l{QThread::}{exec()} must be called inside + \l{QThread::}{run()}. Thread affinity can be changed using + \l{QObject::}{moveToThread()}. + + As mentioned above, developers must always be careful when calling objects' + methods from other threads. Thread affinity does not change this situation. + Qt documentation marks several methods as thread-safe. + \l{QCoreApplication::}{postEvent()} is a noteworthy example. A thread-safe + method may be called from different threads simultaneously. + + In cases where there is usually no concurrent access to methods, calling + non-thread-safe methods of objects in other threads may work thousands + of times before a concurrent access occurs, causing unexpected behavior. + Writing test code does not entirely ensure thread correctness, but it is + still important. + On Linux, Valgrind and Helgrind can help detect threading errors. + + The anatomy of QThread is quite interesting: + + \list + \o QThread does not live in the new thread where \l{QThread::}{run()} is + executed. It lives in the old thread. + \o Most QThread methods are the thread's control interface and are meant to + be called from the old thread. Do not move this interface to the newly + created thread using \l{QObject::}{moveToThread()}; i.e., calling + \l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad + practice. + \o \l{QThread::}{exec()} and the static methods + \l{QThread::}{usleep()}, \l{QThread::}{msleep()}, + \l{QThread::}{sleep()} are meant to be called from the newly created + thread. + \o Additional members defined in the QThread subclass are + accessible by both threads. The developer is responsible for + coordinating access. A typical strategy is to set the members before + \l{QThread::}{start()} is called. Once the worker thread is running, + the main thread should not touch the additional members anymore. After + the worker has terminated, the main thread can access the additional + members again. This is a convenient strategy for passing parameters to a + thread before it is started as well as for collecting the result once it + has terminated. + \endlist + + A QObject's parent must always be in the same thread. This has a surprising + consequence for objects generated within the \l{QThread::}{run()} method: + + \code + void HelloThread::run() + { + QObject *object1 = new QObject(this); //error, parent must be in the same thread + QObject object2; // OK + QSharedPointer object3(new QObject); // OK + } + \endcode + + \section2 Using a Mutex to Protect the Integrity of Data + + A mutex is an object that has \l{QMutex::}{lock()} and \l{QMutex::}{unlock()} + methods and remembers if it is already locked. A mutex is designed to be + called from multiple threads. \l{QMutex::}{lock()} returns immediately if + the mutex is not locked. The next call from another thread will find the + mutex in a locked state and then \l{QMutex::}{lock()} will block the thread + until the other thread calls \l{QMutex::}{unlock()}. This functionality can + make sure that a code section will be executed by only one thread at a time. + + The following line sketches how a mutex can be used to make a method + thread-safe: + + \code + void Worker::work() + { + this->mutex.lock(); // first thread can pass, other threads will be blocked here + doWork(); + this->mutex.unlock(); + } + \endcode + + What happens if one thread does not unlock a mutex? The result can be a + frozen application. In the example above, an exception might be thrown and + \c{mutex.unlock()} will never be reached. To prevent problems like this, + QMutexLocker should be used. + + \code + void Worker::work() + { + QMutexLocker locker(&mutex); // Locks the mutex and unlocks when locker exits the scope + doWork(); + } + \endcode + + This looks easy, but mutexes introduce a new class of problems: deadlocks. + A deadlock happens when a thread waits for a mutex to become unlocked, but + the mutex remains locked because the owning thread is waiting for the first + thread to unlock it. The result is a frozen application. Mutexes can be + used to make a method thread safe. Most Qt methods aren't thread safe + because there is always a performance penalty when using mutexes. + + It isn't always possible to lock and unlock a mutex in a method. Sometimes + the need to lock spans several calls. For example, modifying a container + with an iterator requires a sequence of several calls which should not be + interrupted by other threads. In such a scenario, locking can be achieved + with a mutex that is kept outside of the object to be manipulated. With an + external mutex, the duration of locking can be adjusted to the needs of the + operation. One disadvantage is that external mutexes aid locking, but do + not enforce it because users of the object may forget to use it. + + \section2 Using the Event Loop to Prevent Data Corruption + + The event loops of Qt are a very valuable tool for inter-thread + communication. Every thread may have its own event loop. A safe way of + calling a slot in another thread is by placing that call in another + thread's event loop. This ensures that the target object finishes the + method that is currently running before another method is started. + + So how is it possible to put a method invocation in an event loop? Qt has + two ways of doing this. One way is via queued signal-slot connections; the + other way is to post an event with QCoreApplication::postEvent(). A queued + signal-slot connection is a signal slot connection that is executed + asynchronously. The internal implementation is based on posted events. The + arguments of the signal are put into the event loop and the signal method + returns immediately. + + The connected slot will be executed at a time which depends on what else is + in the event loop. + + Communication via the event loop eliminates the deadlock problem we face + when using mutexes. This is why we recommend using the event loop rather + than locking an object using a mutex. + + \section2 Dealing with Asynchronous Execution + + One way to obtain a worker thread's result is by waiting for the thread + to terminate. In many cases, however, a blocking wait isn't acceptable. The + alternative to a blocking wait are asynchronous result deliveries with + either posted events or queued signals and slots. This generates a certain + overhead because an operation's result does not appear on the next source + line, but in a slot located somewhere else in the source file. Qt + developers are used to working with this kind of asynchronous behavior + because it is much similar to the kind of event-driven programming used in + GUI applications. + + \section1 Examples + + This tutorial comes with examples for Qt's three basic ways of working with + threads. Two more examples show how to communicate with a running thread + and how a QObject can be placed in another thread, providing service to the + main thread. + + \list + \o Using QThread as shown \l{Qt thread basics}{above} + \o \l{Example 1: Using the Thread Pool}{Using the global QThreadPool} + \o \l{Example 2: Using QtConcurrent}{Using QtConcurrent} + \o \l{Example 3: Clock}{Communication with the GUI thread} + \o \l{Example 4: A Permanent Thread}{A permanent QObject in another thread + provides service to the main thread} + \endlist + + The following examples can all be compiled and run independently. The source can + be found in the examples directory: examples/tutorials/threads/ + + \section2 Example 1: Using the Thread Pool + + Creating and destroying threads frequently can be expensive. To avoid the + cost of thread creation, a thread pool can be used. A thread pool is a + place where threads can be parked and fetched. We can write the same + "hello thread" program as \l{Qt Thread Basics}{above} using the global + thread pool. We derive a class from QRunnable. The code we want to run in + another thread needs to be placed in the reimplemented QRunnable::run() + method. + + \snippet examples/tutorials/threads/hellothreadpool/hellothreadpool.cpp 1 + + We instantiate Work in main(), locate the global thread pool and use the + QThreadPool::start() method. Now the thread pool runs our worker in another + thread. Using the thread pool has a performance advantage because threads + are not destroyed after they have finished running. They are kept in a pool + and wait to be used again later. + + \section2 Example 2: Using QtConcurrent + + \snippet examples/tutorials/threads/helloconcurrent/helloconcurrent.cpp 1 + + We write a global function hello() to implement the work. QtConcurrent::run() + is used to run the function in another thread. The result is a QFuture. + QFuture provides a method called \l{QFuture::}{waitForFinished()}, which + blocks until the calculation is completed. The real power of QtConcurrent + becomes visible when data can be made available in a container. QtConcurrent + provides several functions that are able to process itemized data on all + available cores simultaneously. The use of QtConcurrent is very similar to + applying an STL algorithm to an STL container. + \l{examples-threadandconcurrent.html}{QtConcurrent Map} is a very short and + clear example about how a container of images can be scaled on all available + cores. The image scaling example uses the blocking variants of the functions + used. For every blocking function there is also a non-blocking, asynchronous + counterpart. Getting results asynchronously is implemented with QFuture and + QFutureWatcher. + + \section2 Example 3: Clock + + \image thread_clock.png "clock" + + We want to produce a clock application. The application has a GUI and a + worker thread. The worker thread checks every 10 milliseconds what time it + is. If the formatted time has changed, the result will be sent to the GUI + thread where it is displayed. + + Of course, this is an overly complicated way of designing a clock and, + actually, a separate thread is unnecessary. We would be better off placing + the timer in the main thread because the calculation made in the timer slot + is very short-lived. This example is purely for instructional use and shows + how to communicate from a worker thread to a GUI thread. Note that + communication in this direction is easy. We only need to add a signal + to QThread and make a queued signal/slot connection to the main thread. + Communication from the GUI to the worker thread is shown in the next + example. + + \snippet examples/tutorials/threads/clock/main.cpp 1 + + We've connected the \c clockThread with the label. The connection must be a + queued signal-slot connection because we want to put the call in the event + loop. + + \snippet examples/tutorials/threads/clock/clockthread.h 1 + + We have derived a class from QThread and declared the \c sendTime() signal. + + \snippet examples/tutorials/threads/clock/clockthread.cpp 1 + + The trickiest part of this example is that the timer is connected to its + slot via a direct connection. A default connection would produce a queued + signal-slot connection because the connected objects live in different + threads; remember that QThread does not live in the thread it creates. + + Still it is safe to access ClockThread::timerHit() from the worker thread + because ClockThread::timerHit() is private and only touches local variables + and a private member that isn't touched by public methods. + QDateTime::currentDateTime() isn't marked as thread-safe in Qt + documentation, however we can get away with using it in this small + example because we know that the QDateTime::currentDateTime() static + method isn't used in any other threads. + + \section2 Example 4: A Permanent Thread + + This example shows how it is possible to have a QObject in a worker thread + that accepts requests from the GUI thread, does polling using a timer and + continuously reports results back to the GUI thread. The actual work + including the polling must be implemented in a class derived from QObject. + We have called this class \c WorkerObject in the code shown below. The + thread-specific code is hidden in a class called \c Thread, derived from + QThread. + \c Thread has two additional public members. The \c launchWorker() member + takes the worker object and moves it to another thread with a started event + loop. + The call blocks for a very short moment until the thread creation operation + is completed, allowing the worker object to be used again on the next line. + The \c Thread class's code is short but somewhat involved, so we only show + how to use the class. + + \snippet examples/tutorials/threads/movedobject/main.cpp 1 + + QMetaObject::invokeMethod() calls a slot via the event loop. The worker + object's methods should not be called directly after the object has been + moved to another thread. We let the worker thread do some work and polling, + and use a timer to shut the application down after 3 seconds. Shutting the + worker down needs some care. We call \c{Thread::stop()} to exit the event + loop. We wait for the thread to terminate and, after this has occurred, we + delete the worker. + + \section1 Digging Deeper + + Threading is a very complicated subject. Qt offers more classes for + threading than we have presented in this tutorial. The following materials + can help you go into the subject in more depth: + + \list + \o Good video tutorials about threads with Qt can be found in the material + from the \l{Training Day at Qt Developer Days 2009}. + \o The \l{Thread Support in Qt} document is a good starting point into + the reference documentation. + \o Qt comes with several additional examples for + \l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}. + \o Several good books describe how to work with Qt threads. The most + extensive coverage can be found in \e{Advanced Qt Programming} by Mark + Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and + QtConcurrent. + \endlist +*/ diff --git a/doc/src/corelib/threads.qdoc b/doc/src/corelib/threads.qdoc new file mode 100644 index 0000000000..c38a7f3141 --- /dev/null +++ b/doc/src/corelib/threads.qdoc @@ -0,0 +1,705 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group thread + \title Threading Classes +*/ + +/*! + \page threads.html + \title Thread Support in Qt + \ingroup qt-basic-concepts + \brief A detailed discussion of thread handling in Qt. + + \ingroup frameworks-technologies + + \nextpage Starting Threads with QThread + + Qt provides thread support in the form of platform-independent + threading classes, a thread-safe way of posting events, and + signal-slot connections across threads. This makes it easy to + develop portable multithreaded Qt applications and take advantage + of multiprocessor machines. Multithreaded programming is also a + useful paradigm for performing time-consuming operations without + freezing the user interface of an application. + + Earlier versions of Qt offered an option to build the library + without thread support. Since Qt 4.0, threads are always enabled. + + \section1 Topics: + + \list + \o \l{Recommended Reading} + \o \l{The Threading Classes} + \o \l{Starting Threads with QThread} + \o \l{Synchronizing Threads} + \o \l{Reentrancy and Thread-Safety} + \o \l{Threads and QObjects} + \o \l{Concurrent Programming} + \o \l{Thread-Support in Qt Modules} + \endlist + + \section1 Recommended Reading + + This document is intended for an audience that has knowledge of, + and experience with, multithreaded applications. If you are new + to threading see our Recommended Reading list: + + \list + \o \l{Threads Primer: A Guide to Multithreaded Programming} + \o \l{Thread Time: The Multithreaded Programming Guide} + \o \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing} + \o \l{Win32 Multithreaded Programming} + \endlist + + \section1 The Threading Classes + + These classes are relevant to threaded applications. + + \annotatedlist thread + +\omit + \list + \o QThread provides the means to start a new thread. + \o QThreadStorage provides per-thread data storage. + \o QThreadPool manages a pool of threads that run QRunnable objects. + \o QRunnable is an abstract class representing a runnable object. + \o QMutex provides a mutual exclusion lock, or mutex. + \o QMutexLocker is a convenience class that automatically locks + and unlocks a QMutex. + \o QReadWriteLock provides a lock that allows simultaneous read access. + \o QReadLocker and QWriteLocker are convenience classes that automatically + lock and unlock a QReadWriteLock. + \o QSemaphore provides an integer semaphore (a generalization of a mutex). + \o QWaitCondition provides a way for threads to go to sleep until + woken up by another thread. + \o QAtomicInt provides atomic operations on integers. + \o QAtomicPointer provides atomic operations on pointers. + \endlist +\endomit + + \note Qt's threading classes are implemented with native threading APIs; + e.g., Win32 and pthreads. Therefore, they can be used with threads of the + same native API. +*/ + +/*! + \page threads-starting.html + \title Starting Threads with QThread + + \contentspage Thread Support in Qt + \nextpage Synchronizing Threads + + A QThread instance represents a thread and provides the means to + \l{QThread::start()}{start()} a thread, which will then execute the + reimplementation of QThread::run(). The \c run() implementation is for a + thread what the \c main() entry point is for the application. All code + executed in a call stack that starts in the \c run() function is executed + by the new thread, and the thread finishes when the function returns. + QThread emits signals to indicate that the thread started or finished + executing. + + \section1 Creating a Thread + + To create a thread, subclass QThread and reimplement its + \l{QThread::run()}{run()} function. For example: + + \snippet doc/src/snippets/threads/threads.h 0 + \codeline + \snippet doc/src/snippets/threads/threads.cpp 0 + \snippet doc/src/snippets/threads/threads.cpp 1 + \dots + \snippet doc/src/snippets/threads/threads.cpp 2 + + \section1 Starting a Thread + + Then, create an instance of the thread object and call + QThread::start(). Note that you must create the QApplication (or + QCoreApplication) object before you can create a QThread. + + The function will return immediately and the + main thread will continue. The code that appears in the + \l{QThread::run()}{run()} reimplementation will then be executed + in a separate thread. + + Creating threads is explained in more detail in the QThread + documentation. + + Note that QCoreApplication::exec() must always be called from the + main thread (the thread that executes \c{main()}), not from a + QThread. In GUI applications, the main thread is also called the + GUI thread because it's the only thread that is allowed to + perform GUI-related operations. +*/ + +/*! + \page threads-synchronizing.html + \title Synchronizing Threads + + \previouspage Starting Threads with QThread + \contentspage Thread Support in Qt + \nextpage Reentrancy and Thread-Safety + + The QMutex, QReadWriteLock, QSemaphore, and QWaitCondition + classes provide means to synchronize threads. While the main idea + with threads is that they should be as concurrent as possible, + there are points where threads must stop and wait for other + threads. For example, if two threads try to access the same + global variable simultaneously, the results are usually + undefined. + + QMutex provides a mutually exclusive lock, or mutex. At most one + thread can hold the mutex at any time. If a thread tries to + acquire the mutex while the mutex is already locked, the thread will + be put to sleep until the thread that currently holds the mutex + unlocks it. Mutexes are often used to protect accesses to shared + data (i.e., data that can be accessed from multiple threads + simultaneously). In the \l{Reentrancy and Thread-Safety} section + below, we will use it to make a class thread-safe. + + QReadWriteLock is similar to QMutex, except that it distinguishes + between "read" and "write" access to shared data and allows + multiple readers to access the data simultaneously. Using + QReadWriteLock instead of QMutex when it is possible can make + multithreaded programs more concurrent. + + QSemaphore is a generalization of QMutex that protects a certain + number of identical resources. In contrast, a mutex protects + exactly one resource. The \l{threads/semaphores}{Semaphores} + example shows a typical application of semaphores: synchronizing + access to a circular buffer between a producer and a consumer. + + QWaitCondition allows a thread to wake up other threads when some + condition has been met. One or many threads can block waiting for + a QWaitCondition to set a condition with + \l{QWaitCondition::wakeOne()}{wakeOne()} or + \l{QWaitCondition::wakeAll()}{wakeAll()}. Use + \l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly + selected event or \l{QWaitCondition::wakeAll()}{wakeAll()} to + wake them all. The \l{threads/waitconditions}{Wait Conditions} + example shows how to solve the producer-consumer problem using + QWaitCondition instead of QSemaphore. + + Note that Qt's synchronization classes rely on the use of properly + aligned pointers. For instance, you cannot use packed classes with + MSVC. +*/ + +/*! + \page threads-reentrancy.html + \title Reentrancy and Thread-Safety + + \keyword reentrant + \keyword thread-safe + + \previouspage Synchronizing Threads + \contentspage Thread Support in Qt + \nextpage Threads and QObjects + + Throughout the documentation, the terms \e{reentrant} and + \e{thread-safe} are used to mark classes and functions to indicate + how they can be used in multithread applications: + + \list + \o A \e thread-safe function can be called simultaneously from + multiple threads, even when the invocations use shared data, + because all references to the shared data are serialized. + \o A \e reentrant function can also be called simultaneously from + multiple threads, but only if each invocation uses its own data. + \endlist + + Hence, a \e{thread-safe} function is always \e{reentrant}, but a + \e{reentrant} function is not always \e{thread-safe}. + + By extension, a class is said to be \e{reentrant} if its member + functions can be called safely from multiple threads, as long as + each thread uses a \e{different} instance of the class. The class + is \e{thread-safe} if its member functions can be called safely + from multiple threads, even if all the threads use the \e{same} + instance of the class. + + \note Qt classes are only documented as \e{thread-safe} if they + are intended to be used by multiple threads. If a function is not + marked as thread-safe or reentrant, it should not be used from + different threads. If a class is not marked as thread-safe or + reentrant then a specific instance of that class should not be + accessed from different threads. + + \section1 Reentrancy + + C++ classes are often reentrant, simply because they only access + their own member data. Any thread can call a member function on an + instance of a reentrant class, as long as no other thread can call + a member function on the \e{same} instance of the class at the + same time. For example, the \c Counter class below is reentrant: + + \snippet doc/src/snippets/threads/threads.cpp 3 + \snippet doc/src/snippets/threads/threads.cpp 4 + + The class isn't thread-safe, because if multiple threads try to + modify the data member \c n, the result is undefined. This is + because the \c ++ and \c -- operators aren't always atomic. + Indeed, they usually expand to three machine instructions: + + \list 1 + \o Load the variable's value in a register. + \o Increment or decrement the register's value. + \o Store the register's value back into main memory. + \endlist + + If thread A and thread B load the variable's old value + simultaneously, increment their register, and store it back, they + end up overwriting each other, and the variable is incremented + only once! + + \section1 Thread-Safety + + Clearly, the access must be serialized: Thread A must perform + steps 1, 2, 3 without interruption (atomically) before thread B + can perform the same steps; or vice versa. An easy way to make + the class thread-safe is to protect all access to the data + members with a QMutex: + + \snippet doc/src/snippets/threads/threads.cpp 5 + \snippet doc/src/snippets/threads/threads.cpp 6 + + The QMutexLocker class automatically locks the mutex in its + constructor and unlocks it when the destructor is invoked, at the + end of the function. Locking the mutex ensures that access from + different threads will be serialized. The \c mutex data member is + declared with the \c mutable qualifier because we need to lock + and unlock the mutex in \c value(), which is a const function. + + \section1 Notes on Qt Classes + + Many Qt classes are \e{reentrant}, but they are not made + \e{thread-safe}, because making them thread-safe would incur the + extra overhead of repeatedly locking and unlocking a QMutex. For + example, QString is reentrant but not thread-safe. You can safely + access \e{different} instances of QString from multiple threads + simultaneously, but you can't safely access the \e{same} instance + of QString from multiple threads simultaneously (unless you + protect the accesses yourself with a QMutex). + + Some Qt classes and functions are thread-safe. These are mainly + the thread-related classes (e.g. QMutex) and fundamental functions + (e.g. QCoreApplication::postEvent()). + + \note Terminology in the multithreading domain isn't entirely + standardized. POSIX uses definitions of reentrant and thread-safe + that are somewhat different for its C APIs. When using other + object-oriented C++ class libraries with Qt, be sure the + definitions are understood. +*/ + +/*! + \page threads-qobject.html + \title Threads and QObjects + + \previouspage Reentrancy and Thread Safety + \contentspage Thread Support in Qt + \nextpage Concurrent Programming + + QThread inherits QObject. It emits signals to indicate that the + thread started or finished executing, and provides a few slots as + well. + + More interesting is that \l{QObject}s can be used in multiple + threads, emit signals that invoke slots in other threads, and + post events to objects that "live" in other threads. This is + possible because each thread is allowed to have its own event + loop. + + \section1 QObject Reentrancy + + QObject is reentrant. Most of its non-GUI subclasses, such as + QTimer, QTcpSocket, QUdpSocket and QProcess, are also + reentrant, making it possible to use these classes from multiple + threads simultaneously. Note that these classes are designed to be + created and used from within a single thread; creating an object + in one thread and calling its functions from another thread is not + guaranteed to work. There are three constraints to be aware of: + + \list + \o \e{The child of a QObject must always be created in the thread + where the parent was created.} This implies, among other + things, that you should never pass the QThread object (\c + this) as the parent of an object created in the thread (since + the QThread object itself was created in another thread). + + \o \e{Event driven objects may only be used in a single thread.} + Specifically, this applies to the \l{timers.html}{timer + mechanism} and the \l{QtNetwork}{network module}. For example, + you cannot start a timer or connect a socket in a thread that + is not the \l{QObject::thread()}{object's thread}. + + \o \e{You must ensure that all objects created in a thread are + deleted before you delete the QThread.} This can be done + easily by creating the objects on the stack in your + \l{QThread::run()}{run()} implementation. + \endlist + + Although QObject is reentrant, the GUI classes, notably QWidget + and all its subclasses, are not reentrant. They can only be used + from the main thread. As noted earlier, QCoreApplication::exec() + must also be called from that thread. + + In practice, the impossibility of using GUI classes in other + threads than the main thread can easily be worked around by + putting time-consuming operations in a separate worker thread and + displaying the results on screen in the main thread when the + worker thread is finished. This is the approach used for + implementing the \l{threads/mandelbrot}{Mandelbrot} and + the \l{network/blockingfortuneclient}{Blocking Fortune Client} + example. + + \section1 Per-Thread Event Loop + + Each thread can have its own event loop. The initial thread + starts its event loops using QCoreApplication::exec(); other + threads can start an event loop using QThread::exec(). Like + QCoreApplication, QThread provides an + \l{QThread::exit()}{exit(int)} function and a + \l{QThread::quit()}{quit()} slot. + + An event loop in a thread makes it possible for the thread to use + certain non-GUI Qt classes that require the presence of an event + loop (such as QTimer, QTcpSocket, and QProcess). It also makes it + possible to connect signals from any threads to slots of a + specific thread. This is explained in more detail in the + \l{Signals and Slots Across Threads} section below. + + \image threadsandobjects.png Threads, objects, and event loops + + A QObject instance is said to \e live in the thread in which it + is created. Events to that object are dispatched by that thread's + event loop. The thread in which a QObject lives is available using + QObject::thread(). + + Note that for QObjects that are created before QApplication, + QObject::thread() returns zero. This means that the main thread + will only handle posted events for these objects; other event + processing is not done at all for objects with no thread. Use the + QObject::moveToThread() function to change the thread affinity for + an object and its children (the object cannot be moved if it has a + parent). + + Calling \c delete on a QObject from a thread other than the one + that \e owns the object (or accessing the object in other ways) is + unsafe, unless you guarantee that the object isn't processing + events at that moment. Use QObject::deleteLater() instead, and a + \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted, + which the event loop of the object's thread will eventually pick + up. By default, the thread that \e owns a QObject is the thread + that \e creates the QObject, but not after QObject::moveToThread() + has been called. + + If no event loop is running, events won't be delivered to the + object. For example, if you create a QTimer object in a thread but + never call \l{QThread::exec()}{exec()}, the QTimer will never emit + its \l{QTimer::timeout()}{timeout()} signal. Calling + \l{QObject::deleteLater()}{deleteLater()} won't work + either. (These restrictions apply to the main thread as well.) + + You can manually post events to any object in any thread at any + time using the thread-safe function + QCoreApplication::postEvent(). The events will automatically be + dispatched by the event loop of the thread where the object was + created. + + Event filters are supported in all threads, with the restriction + that the monitoring object must live in the same thread as the + monitored object. Similarly, QCoreApplication::sendEvent() + (unlike \l{QCoreApplication::postEvent()}{postEvent()}) can only + be used to dispatch events to objects living in the thread from + which the function is called. + + \section1 Accessing QObject Subclasses from Other Threads + + QObject and all of its subclasses are not thread-safe. This + includes the entire event delivery system. It is important to keep + in mind that the event loop may be delivering events to your + QObject subclass while you are accessing the object from another + thread. + + If you are calling a function on an QObject subclass that doesn't + live in the current thread and the object might receive events, + you must protect all access to your QObject subclass's internal + data with a mutex; otherwise, you may experience crashes or other + undesired behavior. + + Like other objects, QThread objects live in the thread where the + object was created -- \e not in the thread that is created when + QThread::run() is called. It is generally unsafe to provide slots + in your QThread subclass, unless you protect the member variables + with a mutex. + + On the other hand, you can safely emit signals from your + QThread::run() implementation, because signal emission is + thread-safe. + + \section1 Signals and Slots Across Threads + + Qt supports these signal-slot connection types: + + \list + + \o \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is + emitted in the thread which the receiving object has affinity then + the behavior is the same as the Direct Connection. Otherwise, + the behavior is the same as the Queued Connection." + + \o \l{Qt::DirectConnection}{Direct Connection} The slot is invoked + immediately, when the signal is emitted. The slot is executed + in the emitter's thread, which is not necessarily the + receiver's thread. + + \o \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked + when control returns to the event loop of the receiver's + thread. The slot is executed in the receiver's thread. + + \o \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection} + The slot is invoked as for the Queued Connection, except the + current thread blocks until the slot returns. \note Using this + type to connect objects in the same thread will cause deadlock. + + \o \l{Qt::UniqueConnection}{Unique Connection} The behavior is the + same as the Auto Connection, but the connection is made only if + it does not duplicate an existing connection. i.e., if the same + signal is already connected to the same slot for the same pair + of objects, then the connection is not made and connect() + returns false. + + \endlist + + The connection type can be specified by passing an additional + argument to \l{QObject::connect()}{connect()}. Be aware that + using direct connections when the sender and receiver live in + different threads is unsafe if an event loop is running in the + receiver's thread, for the same reason that calling any function + on an object living in another thread is unsafe. + + QObject::connect() itself is thread-safe. + + The \l{threads/mandelbrot}{Mandelbrot} example uses a queued + connection to communicate between a worker thread and the main + thread. To avoid freezing the main thread's event loop (and, as a + consequence, the application's user interface), all the + Mandelbrot fractal computation is done in a separate worker + thread. The thread emits a signal when it is done rendering the + fractal. + + Similarly, the \l{network/blockingfortuneclient}{Blocking Fortune + Client} example uses a separate thread for communicating with + a TCP server asynchronously. +*/ + +/*! + \page threads-qtconcurrent.html + \title Concurrent Programming + + \previouspage Threads and QObjects + \contentspage Thread Support in Qt + \nextpage Thread-Support in Qt Modules + + \target qtconcurrent intro + + The QtConcurrent namespace provides high-level APIs that make it + possible to write multi-threaded programs without using low-level + threading primitives such as mutexes, read-write locks, wait + conditions, or semaphores. Programs written with QtConcurrent + automatically adjust the number of threads used according to the + number of processor cores available. This means that applications + written today will continue to scale when deployed on multi-core + systems in the future. + + QtConcurrent includes functional programming style APIs for + parallel list processing, including a MapReduce and FilterReduce + implementation for shared-memory (non-distributed) systems, and + classes for managing asynchronous computations in GUI + applications: + + \list + + \o QtConcurrent::map() applies a function to every item in a container, + modifying the items in-place. + + \o QtConcurrent::mapped() is like map(), except that it returns a new + container with the modifications. + + \o QtConcurrent::mappedReduced() is like mapped(), except that the + modified results are reduced or folded into a single result. + + \o QtConcurrent::filter() removes all items from a container based on the + result of a filter function. + + \o QtConcurrent::filtered() is like filter(), except that it returns a new + container with the filtered results. + + \o QtConcurrent::filteredReduced() is like filtered(), except that the + filtered results are reduced or folded into a single result. + + \o QtConcurrent::run() runs a function in another thread. + + \o QFuture represents the result of an asynchronous computation. + + \o QFutureIterator allows iterating through results available via QFuture. + + \o QFutureWatcher allows monitoring a QFuture using signals-and-slots. + + \o QFutureSynchronizer is a convenience class that automatically + synchronizes several QFutures. + + \endlist + + Qt Concurrent supports several STL-compatible container and iterator types, + but works best with Qt containers that have random-access iterators, such as + QList or QVector. The map and filter functions accept both containers and begin/end iterators. + + STL Iterator support overview: + + \table + \header + \o Iterator Type + \o Example classes + \o Support status + \row + \o Input Iterator + \o + \o Not Supported + \row + \o Output Iterator + \o + \o Not Supported + \row + \o Forward Iterator + \o std::slist + \o Supported + \row + \o Bidirectional Iterator + \o QLinkedList, std::list + \o Supported + \row + \o Random Access Iterator + \o QList, QVector, std::vector + \o Supported and Recommended + \endtable + + Random access iterators can be faster in cases where Qt Concurrent is iterating + over a large number of lightweight items, since they allow skipping to any point + in the container. In addition, using random access iterators allows Qt Concurrent + to provide progress information trough QFuture::progressValue() and QFutureWatcher:: + progressValueChanged(). + + The non in-place modifying functions such as mapped() and filtered() makes a + copy of the container when called. If you are using STL containers this copy operation + might take some time, in this case we recommend specifying the begin and end iterators + for the container instead. +*/ + +/*! + \page threads-modules.html + \title Thread-Support in Qt Modules + + \previouspage Concurrent Programming + \contentspage Thread Support in Qt + + \section1 Threads and the SQL Module + + A connection can only be used from within the thread that created it. + Moving connections between threads or creating queries from a different + thread is not supported. + + In addition, the third party libraries used by the QSqlDrivers can impose + further restrictions on using the SQL Module in a multithreaded program. + Consult the manual of your database client for more information + + \section1 Painting in Threads + + QPainter can be used in a thread to paint onto QImage, QPrinter, and + QPicture paint devices. Painting onto QPixmaps and QWidgets is \e not + supported. On Mac OS X the automatic progress dialog will not be + displayed if you are printing from outside the GUI thread. + + Any number of threads can paint at any given time, however only + one thread at a time can paint on a given paint device. In other + words, two threads can paint at the same time if each paints onto + separate QImages, but the two threads cannot paint onto the same + QImage at the same time. + + Note that on X11 systems without FontConfig support, Qt cannot + render text outside of the GUI thread. You can use the + QFontDatabase::supportsThreadedFontRendering() function to detect + whether or not font rendering can be used outside the GUI thread. + + \section1 Threads and Rich Text Processing + + The QTextDocument, QTextCursor, and \link richtext.html all + related classes\endlink are reentrant. + + Note that a QTextDocument instance created in the GUI thread may + contain QPixmap image resources. Use QTextDocument::clone() to + create a copy of the document, and pass the copy to another thread for + further processing (such as printing). + + \section1 Threads and the SVG module + + The QSvgGenerator and QSvgRenderer classes in the QtSvg module + are reentrant. + + \section1 Threads and Implicitly Shared Classes + + Qt uses an optimization called \l{implicit sharing} for many of + its value class, notably QImage and QString. Beginning with Qt 4, + implicit shared classes can safely be copied across threads, like + any other value classes. They are fully + \l{Reentrancy and Thread-Safety}{reentrant}. The implicit sharing + is really \e implicit. + + In many people's minds, implicit sharing and multithreading are + incompatible concepts, because of the way the reference counting + is typically done. Qt, however, uses atomic reference counting to + ensure the integrity of the shared data, avoiding potential + corruption of the reference counter. + + Note that atomic reference counting does not guarantee + \l{Reentrancy and Thread-Safety}{thread-safety}. Proper locking should be used + when sharing an instance of an implicitly shared class between + threads. This is the same requirement placed on all + \l{Reentrancy and Thread-Safety}{reentrant} classes, shared or not. Atomic reference + counting does, however, guarantee that a thread working on its + own, local instance of an implicitly shared class is safe. We + recommend using \l{Signals and Slots Across Threads}{signals and + slots} to pass data between threads, as this can be done without + the need for any explicit locking. + + To sum it up, implicitly shared classes in Qt 4 are really \e + implicitly shared. Even in multithreaded applications, you can + safely use them as if they were plain, non-shared, reentrant + value-based classes. +*/ -- cgit v1.2.3