Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# Porting to Qt 4

This document describes porting applications from Qt 3 to Qt 4.

If you haven't yet made the decision about porting, or are unsure about whether it is worth it, take a look at the key features offered by Qt 4.

The Qt 4 series is not binary compatible with the 3 series. This means programs compiled for Qt 3 must be recompiled to work with Qt 4. Qt 4 is also not completely source compatible with 3, however nearly all points of incompatibility cause compiler errors or run-time messages (rather than mysterious results). Qt 4 includes many additional features and discards obsolete functionality. Porting from Qt 3 to Qt 4 is straightforward, and once completed makes the considerable additional power and flexibility of Qt 4 available for use in your applications.

To port code from Qt 3 to Qt 4:

1. Briefly read the porting notes below to get an idea of what to expect.
2. Be sure that your code compiles and runs well on all your target platforms with Qt 3, with QT_NO_COMPAT defined.
3. Recompile with Qt 4. For each error, search below for related identifiers (e.g. function names, class names). This document mentions all relevant identifiers to help you get the information you need at the cost of being a little verbose.
4. If you get stuck, ask on the qt-interest mailing list, or Trolltech Technical Support if you're a registered licensee.

Table of contents:

- Explicit Sharing
- QAccel
- QApplication
- QAquaStyle
- QAsciiCache<T>
- QAsciiDict<T>
- QBackInsertIterator
- QBitArray
- QButton
- QButtonGroup
- QByteArray
- QCache<T>
- QCanvas
- QColorGroup
- QCString
- QDataBrowser
- QDataTable
- QDataView
- QDeepCopy<T>
- QDict<T>
- QDir
- QDns
- QDropSite
- QEditorFactory
- QFileDialog

- QFrame
- QFtp
- QGrid
- QGroupBox
- QGuardedPtr<T>
- QHBox
- QHttp
- QIconFactory
- QIconView
- QImage
- QIntCache<T>
- QIntDict<T>
- QIODevice
- QListBox
- QListView
- QLocalFs
- QMemArray<T>
- QMimeSourceFactory
- QMultiLineEdit
- QNetworkProtocol
- QObject
- QObjectDictionary
- QObjectList
- QPaintDevice
- QPicture

- QPixmap
- QPointArray
- QPrinter
- QPtrCollection<T>
- QPtrDict<T>
- QPtrList<T>
- QPtrQueue<T>
- QPtrStack<T>
- QPtrVector<T>
- QRangeControl
- QRegion
- QScrollView
- QShared
- QSignal
- QSlider
- QSortedList
- QSplitter
- QSqlCursor
- QSqlDatabase
- QSqlEditorFactory
- QSqlError
- QSqlFieldInfo
- QSqlForm
- QSqlPropertyMap
- QSqlQuery

- QSqlRecord
- QSqlRecordInfo
- QSqlSelectCursor
- QStr(I)List
- QStr(I)Vec
- QString
- QStringList
- QTabDialog
- QTable
- QTextOStreamIterator
- QUrl
- QUrlOperator
- QValueList<T>
- QValueVector<T>
- QVariant
- QVBox
- QWidget
- QWidgetIntDict
- QWidgetList
- QWidgetStack
- QWizard

## Explicit Sharing

Qt 4 is the first version of Qt that contains no explicitly shared classes. All classes that were explicitly shared in Qt 3 are implicitly shared in Qt 4:

- QImage
- QMovie
- QBitArray
- QByteArray
- QPointArray

This means that if you took a copy of an instance of the class (using operator=() or the class's copy constructor), any modification to the copy would affect the original and vice versa. Needless to say, this behavior is rarely desirable.

Fortunately, nearly all Qt 3 applications don't rely on explicit sharing. When porting, you typically only need to remove calls to detach() and/or copy(), which aren't necessary anymore.

If you deliberately rely on explicit sharing in your application, you can use pointers or references to achieve the same result in Qt 4.

For example, if you have code like

        void asciify(QByteArray array)
        {
            for (int i = 0; i < (int)array.size(); ++i) {
                if ((uchar)array[i] >= 128)
                    array[i] = '?';
            }
        }

you can rewrite it as

        void asciify(QByteArray &array)
        {
            for (int i = 0; i < (int)array.size(); ++i) {
                if ((uchar)array[i] >= 128)
                    array[i] = '?';
            }
        }

(Notice the `&` in the parameter declaration.)

## QAccel

The QAccel class has been moved to the Qt 3 compatibility library. In new applications, you have three options:

1. You can use QAction and set a key sequence using QAction::setShortcut().
2. You can use QShortcut, a class that provides similar functionality to QAccel.
3. You can use QWidget::grabShortcut() and process "shortcut" events by reimplementing QWidget::event().

The QAccel class also supported multiple accelerators using the same object, by calling QAccel::insertItem() multiple times. In Qt 4, the solution is to create multiple QShortcut objects.

## QApplication

The QApplication class has been split into two classes: QCoreApplication and QApplication. The new QApplication class inherits QCoreApplication and adds GUI-related functionality. In practice, this has no consequences for existing Qt applications.

In addition, the following API change was made:

1. QApplication::allWidgets() and QApplication::topLevelWidgets() used to return a pointer to a QWidgetList. Now they return a QWidgetList.

   Also, QWidgetList has changed from being a typedef for QPtrList<QWidget> to being a typedef for QList<QWidget *>. See the section on QWidgetList below for details.

   For example, if you have code like

               QWidgetList *list = QApplication::topLevelWidgets();
               QWidgetListIt it(*list);
               QWidget *widget;
               while ((widget = it.current())) {
                   if (widget->inherits("MainWindow"))
                       ((MainWindow *)widget)->updateRecentFileItems();
                   ++it;
               }
               delete list;

   you can rewrite it as

               QWidgetList list = QApplication::topLevelWidgets();
               for (int i = 0; i < list.size(); ++i) {
                   if (MainWindow *mainWin = qt_cast<MainWindow>(list.at(i)))
                       mainWin->updateRecentFileItems();
               }

## QAquaStyle

The QAquaStyle class first appeared in Qt 3.0, when the Qt/Mac port was first released. It emulated Apple's "Aqua" theme. In Qt 3.1, QAquaStyle was obsoleted by QMacStyle, which uses Appearance Manager to perform its drawing.

The QAquaStyle class is no longer provided in Qt 4. Use QMacStyle instead.

## QAsciiCache<T>

QAsciiCache<T> has been moved to the Qt 3 compatibility library. It has been replaced by QCache<QByteArray, T>.

For details, read the section on QCache<T>, mentally substituting QByteArray for QString.

## QAsciiDict<T>

QAsciiDict<T> and QAsciiDictIterator<T> have been moved to the Qt 3 compatibility library. They have been replaced by the more modern QHash<Key, T> and QMultiHash<Key, T> classes and their associated iterator classes.

When porting old code that uses QAsciiDict<T> to Qt 4, there are four classes that you can use:

- QMultiHash<QByteArray, T *>
- QMultiHash<QByteArray, T *>
- QHash<QByteArray, T>
- QHash<QByteArray, T>

For details, read the section on QDict<T>, mentally substituting QByteArray for QString.

## QBackInsertIterator

The undocumented QBackInsertIterator class has been removed from the Qt library. If you need it in your application, feel free to copy the source code from the Qt 3 `<qtl.h>` header file.

## QBitArray

In Qt 3, QBitArray inherited from QByteArray. In Qt 4, QBitArray is a totally independent class. This makes very little difference to the user, except that the new QBitArray doesn't provide any of QByteArray's byte-based API anymore. These calls will result in a compile-time error, except calls to QBitArray::truncate(), whose parameter was a number of bytes in Qt 3 and a number of bits in Qt 4.

QBitArray was an explicitly shared class in Qt 3. See Explicit Sharing for more information.

The QBitVal class has been renamed QBitRef.

## QButton

The QButton class has been replaced by QAbstractButton in Qt 4. Classes like QPushButton and QRadioButton inherit from QAbstractButton. As a help when porting older Qt applications, the Qt 3 compatibility library contains a QButton class implemented in terms of the new QAbstractButton.

If you used the QButton class as a base class for your own button type and want to port your code to the newer QAbstractButton, you need to be aware that QAbstractButton has no equivalent for the QButton::drawButton(QPainter *) virtual function. The solution is to reimplement QWidget::paintEvent() in your QAbstractButton subclass as follows:

        void MyButton::paintEvent(QPaintEvent *)
        {
            QPainter painter(this);
            drawButton(&painter);
        }

## QButtonGroup

The QButtonGroup class has been completely redesigned in Qt 4. For compatibility, the old QButtonGroup class has been renamed Q3ButtonGroup and has been moved to the Qt 3 compatibility library, together with the QHButtonGroup and QVButtonGroup convenience subclasses.

Q3ButtonGroup could be used in two ways:

1. The button group is the parent widget of a number of buttons, i.e. the button group is the parent argument in the button constructor. The buttons are assigned identifiers 0, 1, 2, etc., in the order they are created. A Q3ButtonGroup can display a frame and a title because it inherits Q3GroupBox.
2. The button group is an invisible widget and the contained buttons have some other parent widget. In this usage, each button must be manually inserted, using Q3ButtonGroup::insert(), into the button group and given an ID number.

Unlike Q3ButtonGroup, the new QButtonGroup doesn't inherit QWidget. It is very similar to a "hidden Q3ButtonGroup".

If you use a Q3ButtonGroup, QHButtonGroup, or QVButtonGroup as a widget and want to port to Qt 4, you can replace it with QGroupBox. In Qt 4, radio buttons with the same parent are automatically part of an exclusive group, so you normally don't need to do anything else. See also the section on QGroupBox below.

## QByteArray

In Qt 3, QByteArray was simply a typedef for QMemArray<char>. In Qt 4, QByteArray is a class in its own right, with a higher-level API in the style of QString.

Here are the main issues to be aware of when porting to Qt 4:

1. The QMemArray(int size) constructor has been replaced with QByteArray(int size, char ch). The second argument specifies which character should be used for initializing the array; pass '\0' if you have no specific needs.

   For example, if you have code like

           QByteArray ba(64);

   you can rewrite it as

           QByteArray ba(64, '\0');

2. QMemArray::at() returned a non-const reference, whereas the new QByteArray::at() returns a const value. Code like

           ba.at(0) = 'X';

   will no longer compile. Instead, use QByteArray::operator[]:

           ba[0] = 'X';

3. The QMemArray::contains(char) function has been renamed QByteArray::count(char). In addition, there now exists a QByteArray::contains(char) function that returns a boolean value. Replace old calls to contains() with either count() or contains(), depending on whether you care about the specific number of occurrences of a character in the byte array or only care about whether the array contains that character or not.
4. The new QByteArray has no assign() function. Calls to QMemArray::assign(const QMemArray &) can be replaced by calls to QByteArray::operator=(). Calls to QMemArray::assign(const T *, uint) have no equivalent in Qt 4; if you use it, the solution is either to use QByteArray::fromRawData() and to call free() yourself to avoid a memory leak, or to use the QByteArray(const char *, int) constructor, which will take a deep copy of the data.
5. QMemArray::bsearch() and QMemArray::sort() have no equivalent in the new QByteArray class. Use qBinaryFind() and qHeapSort() if you need that functionality.

QByteArray was an explicitly shared class in Qt 3. See Explicit Sharing for more information.

## QCache<T>

QCache<T> has been renamed Q3Cache<T> and moved to the Qt 3 compatibility library. The new QCache class has a different API, and takes different template parameters: QCache<Key, T>.

When porting to Qt 4, QCache<QString, T> is the obvious substitute for Q3Cache<T>. The following table summarizes the API differences.

Q3Cache<T> function | QCache<QString, T> equivalent
--- | ---
Q3Cache::Q3Cache(int maxCost, int size, bool caseSensitive) | See remark below
Q3Cache::autoDelete() | N/A
Q3Cache::count() | QCache::count() or QCache::size() (equivalent)
Q3Cache::setAutoDelete() | See remark below
Q3Cache::size() | N/A
Q3Cache::statistics() | N/A
Q3Cache::operator=() | See remark below

Remarks:

1. Q3Cache requires the user to allocate a specific number of buckets by passing a prime number (17 by default) to the constructor. In contrast, the new QCache's hash table automatically grows and shrinks as needed, and the constructor doesn't take a prime number.
2. Q3Cache supportes case-insensitive lookups by passing false as second argument to the constructor. This feature has no equivalent in QMultiHash. Instead, call QString::toLower() before you insert or lookup a key in the hash.
3. The Q3Cache::insert() function returns a `bool` value that indicates whether or not the item actually was inserted in the cache. If the item wasn't inserted, it was the caller's responsibility to delete the item. The new QCache::insert() function returns `void` and either adds it to the cache or deletes it right away. Old code like

           if (!cache.insert(key, object))
               delete object;

   becomes

           cache.insert(key, object);

4. The new QCache class always takes ownership of the items it stores (i.e. auto-delete is always on). If you use Q3Cache with auto-delete turned off (the rarely useful default), you cannot use QCache as a direct substitute. One unelegant trick that works well in practice is to use QCache<QString, T *> instead of QCache<QString, T>. In that case, QCache owns the pointers, not the objects that the pointers refer to. For example,

               Q3Cache<QWidget> cache;
               cache.insert(widget->name(), widget);
               ...
               QWidget *foo = cache.take("foo");
               if (foo)
                   foo->show();

   becomes

               typedef QWidget *QWidgetPtr;
               QCache<QString, QWidgetPtr> cache;
               cache.insert(widget->name(), new QWidgetPtr(widget));
               ...
               QWidgetPtr *ptr = cache.take("foo");
               if (ptr) {
                   QWidget *foo = *ptr;
                   delete ptr;
                   foo->show();
               }

   An alternative is to stick to using Q3Cache.

QCacheIterator<T> has been renamed Q3CacheIterator<T> and moved to the Qt 3 compatibility library. The new QCache class doesn't offer any iterator types.

## QCanvas

The canvas module classes (QCanvas, QCanvasView, QCanvasItem,, QCanvasEllipse, QCanvasItemList, QCanvasLine, QCanvasPixmap, QCanvasPixmapArray, QCanvasPolygon, QCanvasPolygonalItem, QCanvasRectangle, QCanvasSpline, QCanvasSprite, and QCanvasText) have been moved to the Qt 3 compatibility library.

Qt 4 will provide a replacement module for these classes.

## QColorGroup

In Qt 3, a QPalette consisted of three QColorGroup objects. In Qt 4, the (rarely used) QColorGroup abstraction has been eliminated. For source compatibility, a QColorGroup class is available when `QT_COMPAT` is defined.

The new QPalette still works in terms of color groups, specified through enum values (QPalette::Active, QPalette::Disabled, and QPalette::Inactive). It also has the concept of a current color group, which you can set using QPalette::setCurrentColorGroup().

The QPalette object returned by QWidget::palette() returns a QPalette initialized with the correct current color group for the widget. This means that if you had code like

        painter.setBrush(colorGroup().brush(QColorGroup::Background));

you can simply replace colorGroup() with palette():

        painter.setBrush(palette().brush(QColorGroup::Background));

## QCString

In Qt 3, QCString inherited from QByteArray. The main drawback of this approach is that the user had the responsibility of ensuring that the string is '\0'-terminated. Another important issue was that conversions between QCString and QByteArray often gave confusing results. (See the Achtung! Binary and Character Data article in Qt Quarterly for an overview of the pitfalls.)

Qt 4 solves that problem by merging the QByteArray and QCString classes into one class called QByteArray. Most functions that were in QCString previously have been moved to QByteArray. The '\0' issue is handled by having QByteArray allocate one extra byte that it always sets to '\0'. For example:

        QByteArray ba("Hello");
        ba.size();             // returns 5 (the '\0' is not counted)
        ba.length();           // returns 5
        ba.data()[5];          // returns '\0'

The Qt 4 compatibility library contains a class called QCString that inherits from the new QByteArray class and that extends it to provide an API that is as close to the old QCString class as possible. Note that the following functions aren't provided by the compatibility QCString class:

- QCString::find(const QRegExp &, int)
- QCString::findRev(const QRegExp &, int)
- QCString::contains(const QRegExp &)
- QCString::replace(const QRegExp &, const char *)

The following functions have lost their last parameter, which specified whether the search was case sensitive or not:

- QByteArray::find(char, int)
- QByteArray::find(const char *, int)
- QByteArray::findRev(char, int)
- QByteArray::findRev(const char *, int)
- QByteArray::contains(char)
- QByteArray::contains(const char *)

In both cases, the solution is to convert the QCString to a QString and use the corresponding QString functions instead.

Also be aware that QCString::size() (inherited from QByteArray) used to return the size of the character data including the '\0'-terminator, whereas the new QByteArray::size() is just a synonym for QByteArray::length(). This brings QByteArray semantics in line with QString's.

When porting to Qt 4, occurrences of QCString should be replaced with QByteArray or QString. The following table summarizes the API differences between the QCString compatibility class and the Qt 4 QByteArray and QString classes:

QCString function | Qt 4 equivalent
--- | ---
QCString::QCString(const char *, uint) | See remark below
QCString::QCString(int) | QByteArray::QByteArray(int, char)
QCString::leftJustify() | QString::leftJustified()
QCString::length() | QByteArray::length() or QByteArray::size() (equivalent)
QCString::lower() | QByteArray::toLower()
QCString::rightJustify() | QString::rightJustified()
QCString::setExpand() | See remark below
QCString::simplifyWhiteSpace() | QByteArray::simplified()
QCString::sprintf() | QString::sprintf()
QCString::stripWhiteSpace() | QByteArray::trimmed()
QCString::toDouble() | QString::toDouble()
QCString::toFloat() | QString::toFloat()
QCString::toInt() | QString::toInt()
QCString::toLong() | QString::toLong()
QCString::toShort() | QString::toShort()
QCString::toUInt() | QString::toUInt()
QCString::toULong() | QString::toULong()
QCString::toUShort() | QString::toUShort()
QCString::upper() | QByteArray::toUpper()

Remarks:

1. QCString(const char *str, uint max) constructs a string of length strlen(str) or max - 1, whichever is shorter. QByteArray(const char *data, int size) constructs a byte array containing exactly size bytes.

   For example, if you have code like

               QCString str1("Hello", 4);           // "Hel"
               QCString str2("Hello world!", n);

   you can rewrite it as

               QByteArray str1("Hello", 3);
               QByteArray str2("Hello world!");
               str2.truncate(n - 1);

2. QCString::setExpand(uint index, char ch) has no equivalent in Qt 4.

   For example, if you have code like

               QCString str("Hello world");
               str.setExpand(16, '\n');            // "Hello world     \n"

   you can rewrite it as

               QCString str("Hello world");
               while (str.size() < 16)
                   str += ' ';
               str += '\n';

Since the old QCString class inherited from QByteArray, everything that is said in the QByteArray section applies for QCString as well.

## QDataBrowser

The QDataBrowser class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QDataTable

The QDataTable class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QDataView

The QDataView class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QDeepCopy<T>

The QDeepCopy<T> class in Qt 3 provided a means of ensuring that implicitly shared and explicitly shared classes referenced unique data. This was necessary because the reference counting in Qt's container classes was done in a thread-unsafe manner.

With Qt 4, QDeepCopy<T> has been moved to the Qt 4 compatibility library. Removing it from existing code is straightforward.

For example, if you have code like

        QString str1 = "I am a string";
        QDeepCopy<QString> str2 = str1;
        QString str3 = QDeepCopy<QString>(str2);

you can rewrite it as

        QString str1 = "I am a string";
        QString str2 = str1;
        QString str3 = str2;

## QDict<T>

QDict<T> has been moved to the Qt 3 compatibility library. It has been replaced by the more modern QHash<Key, T> and QMultiHash<Key, T> classes.

When porting old code that uses QDict<T> to Qt 4, there are four classes that you can use:

Qt 4 class | When to use it
--- | ---
QMultiHash<QString, T *> | Since QDict<T> is pointer-based and allows duplicate keys, this is usually the most straightforward conversion.
QMultiHash<QString, T> | If type `T` is an assignable data type, you can use `T` as the value type rather than `T *`. This often leads to nicer code.
QHash<QString, T *> | If you don't use duplicate keys, you can use QHash instead of QMultiHash. QMultiHash inherits from QHash.
QHash<QString, T>

The APIs of QDict<T> and QMultiHash<QString, T *> are quite similar. The main issue is that QDict supports auto-delete whereas QMultiHash doesn't. (See What's Wrong with Auto-Delete for an explanation of why the Qt 4 containers don't offer that feature.)

The following table summarizes the API differences between the two classes:

QDict function | QMultiHash equivalent
--- | ---
QDict::QDict(int size, bool caseSensitive) | See remarks below
QDict::autoDelete() | N/A
QDict::count() | QMultiHash::count() or QMultiHash::size() (equivalent)
QDict::find(const QString &) | QMultiHash::value(const QString &)
QDict::remove(const QString &) | QMultiHash::take(const QString &)
QDict::resize(uint) | QMultiHash::reserve(int)
QDict::setAutoDelete() | See discussion below
QDict::size() | QMultiHash::capacity()
QDict::statistics() | N/A
QDict::operator[](const QString &) | See remark below

Remarks:

1. QDict requires the user to allocate a specific number of buckets by passing a prime number (17 by default) to the constructor and/or calling QDict::resize() later on. In contrast, QMultiHash's hash table automatically grows and shrinks as needed, and the constructor doesn't take a prime number.
2. QDict supportes case-insensitive lookups by passing false as second argument to the constructor. This feature has no equivalent in QMultiHash. Instead, call QString::toLower() before you insert or lookup a key in the hash.
3. QDict::size() and QMultiHash::size() have different semantics. The former returns the number of buckets in the container, whereas the latter returns the number of items in the container.
4. If there are multiple items with the same key, QDict::remove() removes only the most recently inserted item, whereas QMultiHash::remove() removes all items that share a particular key. To remove only the most recently inserted item, call QMultiHash::take().
5. QDict has only one [] operator (QDict::operator[]()), providing const access to an item's value. QMultiHash also has a non-const overload that can be used on the left side of the assignment operator. If you use the [] operator on a non-const QHash with an unexisting item, QHash will created an element and initialize it to be a null pointer. For that reason, QDict::operator[] should be converted to QMultiHash::value(), not QMultiHash::operator[].

If you use QDict's auto-delete feature (by calling QDict::setAutoDelete(true)), you need to do some more work. You have two options: Either you call `delete` yourself whenever you remove an item from the container, or you use QMultiHash<QString, T> instead of QMultiHash<QString, T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call `delete`.

The following table summarizes the idioms that you need to watch out for if you want to call `delete` yourself.

QDict idiom | QMultiHash idiom
--- | ---

        dict.replace(key, value);

        delete hash.take(key);
        hash.insert(key, value);

        dict.remove(key, value);

        delete hash.take(key);

        dict.clear();

(also called from QDict's destructor)

        while (!hash.isEmpty()) {
            T *value = *hash.begin();
            dict.erase(hash.begin());
            delete value;
        }

In 99% of cases, the following idiom also works:

        qDeleteAll(hash);
        hash.clear();

However, it may lead to crashes if `hash` is referenced from the value type's destructor, because `hash` contains dangling pointers until clear() is called.

Be aware that QDict's destructor automatically calls clear(). If you have a QDict data member in a custom class and use the auto-delete feature, you will need to call `delete` on all the items in the container from your class destructor to avoid a memory leak.

Finally, QDictIterator<T> must also be ported. There are no fewer than four iterator classes that can be used as a replacement: QHash::const_iterator, QHash::iterator, QHashIterator, and QHashMutableIterator. The most straightforward class to use when porting is QHashIterator<QString, T *>. The following table summarizes the API differences:

QDictIterator functions | Qt 4 equivalent
--- | ---
QDictIterator::count() | QHash::count() or QHash::size()
QDictIterator::current() | QHashIterator::value()
QDictIterator::currentKey() | QHashIterator::key()
QDictIterator::isEmpty() | QHash::isEmpty()
QDictIterator::toFirst() | QHashIterator::toFront()
QDictIterator::operator()() | QHashIterator::value()
QDictIterator::operator*() | QHashIterator::value()
QDictIterator::operator++() | See remark below

Be aware that QHashIterator has a different way of iterating than QDictIterator. A typical loop with QDictIterator looks like this:

        QDictIterator<QWidget> i(dict);
        while (i.current() != 0) {
            do_something(i.currentKey(), i.current());
            ++i;
        }

Here's the equivalent QHashIterator loop:

        QHashIterator<QString, QWidget *> i(hash);
        while (i.hasNext()) {
            i.next();                   // must come first
            do_something(i.key(), i.value());
        }

See Java-style iterators for details.

## QDir

QDir::encodedEntryList has been removed.

fileInfoList() and drives() now return a QList<QFileInfo> and not a QPtrList<QFileInfo> *. Code using these methods will have to be adapted.

## QDns

Qt 3 used its own implementation of the DNS protocol and provided a low-level QDns class. Qt 4 uses the system's gethostbyname() function from a thread instead.

The old QDns class has been renamed Q3Dns and moved to the Qt 3 compatibility library. The new QDns class has a radically different API: It consists of two static functions, both called QDns::getHostByName(), one of which is blocking, the other non-blocking. See the QDns class documentation for details.

## QDropSite

The QDropSite class has been obsolete ever since Qt 2.0. The only thing it does is call QWidget::setAcceptDrops(true).

For example, if you have code like

        class MyWidget : public QWidget, public QDropSite
        {
        public:
            MyWidget(const QWidget *parent)
                : QWidget(parent), QDropSite(this)
            {
            }
            ...
        }

you can rewrite it as

        class MyWidget : public QWidget
        {
        public:
            MyWidget(const QWidget *parent)
                : QWidget(parent)
            {
                setAcceptDrops(true);
            }
            ...
        }

## QEditorFactory

The QEditorFactory class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QFileDialog

The QFileDialog class in Qt 4 has been totally rewritten. It provides most of the functionality of the old QFileDialog class, but with a different API. Some functionality, such as the ability to preview files, is expected to be added in a later Qt 4 release.

The old QFileDialog, QFileIconProvider, and QFilePreview classes has been renamed Q3FileDialog, Q3FileIconProvider, and Q3FilePreview and have been moved to the Qt 3 compatibility library. You can use them if you need some functionality not provided yet by the new QFileDialog class.

The following table lists which functions have been renamed or removed in Qt 4.

Old function | Qt 4 equivalent
--- | ---
Q3FileDialog::addFilter(const QString &) | See remark below
Q3FileDialog::addLeftWidget(QWidget *) | N/A
Q3FileDialog::addRightWidget(QWidget *) | N/A
Q3FileDialog::addToolButton(QAbstractButton *, bool separator) | N/A
Q3FileDialog::addWidgets(QLabel *, QWidget *, QPushButton *) | N/A
Q3FileDialog::dir() | QFileDialog::directory()
Q3FileDialog::dirPath() | QFileDialog::directory().path()
Q3FileDialog::iconProvider() | N/A
Q3FileDialog::isContentsPreviewEnabled() | N/A
Q3FileDialog::isInfoPreviewEnabled() | N/A
Q3FileDialog::previewMode() | N/A
Q3FileDialog::rereadDir() | N/A
Q3FileDialog::resortDir() | N/A
Q3FileDialog::selectAll(bool) | N/A
Q3FileDialog::setContentsPreview(QWidget *, Q3FilePreview *) | N/A
Q3FileDialog::setContentsPreviewEnabled(bool) | N/A
Q3FileDialog::setDir(const QString &) | QFileDialog::setDirectory(const QString &)
Q3FileDialog::setFilters(const char **) | Q3FileDialog::setFilters(const QStringList &)
Q3FileDialog::setIconProvider(Q3FileIconProvider *) | N/A
Q3FileDialog::setInfoPreview(QWidget *, Q3FilePreview *) | N/A
Q3FileDialog::setInfoPreviewEnabled(bool) | N/A
Q3FileDialog::setPreviewMode(PreviewMode) | N/A
Q3FileDialog::setSelectedFilter(const QString &) | QFileDialog::selectFilter(const QString &)
Q3FileDialog::setSelectedFilter(int) | See remark below
Q3FileDialog::setSelection(const QString &) | QFileDialog::selectFile(const QString &)
Q3FileDialog::setShowHiddenFiles(bool) | showHidden()
Q3FileDialog::setUrl(const QUrlOperator &) | N/A
Q3FileDialog::showHiddenFiles() | N/A
Q3FileDialog::url() | QUrl::fromLocalFile(QFileDialog::directory())
Old signals | Qt 4 equivalent
Q3FileDialog::fileHighlighted(const QString &) | N/A
Q3FileDialog::fileSelected(const QString &) | QFileDialog::filesSelected(const QStringList &)
Q3FileDialog::dirEntered(const QString &) | N/A
Q3FileDialog::filterSelected(const QString &) | N/A

Remarks:

1. The Q3FileDialog::addFilter(const QString &) function has no direct equivalent in the new QFileDialog. Use QFileDialog::setFilters() instead.

   For example, if you have code like

               fileDialog->addFilter(tr("JPEG files (*.jpg *.jpeg)"));

   you can rewrite it as

               QStringList filters = fileDialog->filters();
               filters << tr("JPEG files (*.jpg *.jpeg)");
               fileDialog->setFilters(filters);

2. The Q3FileDialog::setSelectedFilter(int) overload has no direct equivalent in the new QFileDialog. Use QFileDialog::selectFilter(const QString &) instead.

   For example, if you have code like

               fileDialog->setSelectedFilter(3);

   you can rewrite it as

               fileDialog->selectFilter(fileDialog->filters().at(3));

## QFrame

The QFrame class has been made more lightweight in Qt 4, by reducing the number of properties and virtual functions. The reduction in the number of virtual functions is significant because QFrame is the base class of many Qt classes.

Here's an overview of the changes:

- QFrame no longer has a `margin` property (which wasn't honored by Qt's layout managers anyway).
- QFrame used to have drawFrame(QPainter *), drawContents(QPainter *), and frameChanged() virtual functions. These are now gone. If you want to change the way QFrame paints itself, reimplement QFrame:paintEvent().

As an help to porting, the Qt 3 compatibility library contains a Q3Frame class that inherits QFrame and provides a similar API to the old QFrame class. If you derived from QFrame in your application, you might want to use Q3Frame as a base class as a first step in the porting process, and later move on to the new QFrame class.

## QFtp

This class no longer inherits from QNetworkProtocol. See the section on QNetworkProtocol for details.

## QGrid

The QGrid class has been renamed QGridWidget.

## QGroupBox

The QGroupBox class has been redesigned in Qt 4. The old QUrl class has been renamed Q3GroupBox and moved to the Qt 3 compatibility library.

The new QGroupBox is more lightweight. It doesn't attempt to duplicate functionality already provided by QGridLayout. For that reason, the following members have been removed:

- Q3GroupBox::setColumns(), Q3GroupBox::columns()
- Q3GroupBox::setOrientation(), Q3GroupBox::orientation()
- Q3GroupBox::setInsideMargin(), Q3GroupBox::insideMargin()
- Q3GroupBox::addSpace()

Naturally, the `columns` and `orientation` properties have also been removed.

If you rely on some of the missing functionality in your application, you can use Q3GroupBox instead of QGroupBox as a help to porting.

## QGuardedPtr<T>

The QGuardedPtr<T> class has been renamed QPointer<T> in Qt 4. The Qt 3 compatibility library contains a trivial implementation of QGuardedPtr<T> in terms of QPointer<T>.

## QHBox

The QHBox class has been renamed QHBoxWidget.

## QHttp

This class no longer inherits from QNetworkProtocol. See the See the section on QNetworkProtocol for details.

## QIconFactory

The QIconFactory is no longer part of Qt. It has been replaced by a lighter mechanism based on function pointers.

To port old code that uses QIconFactory to Qt 4, you generally need to turn your QIconFactory::createPixmap() reimplementation into a regular function and call QIconSet::setPixmapGeneratorFn() or QIconSet::setDefaultPixmapGeneratorFn() on it.

## QIconView

The QIconView, QIconViewItem, QIconDrag, QIconDragItem classes has been moved to the Qt 3 compatibility library. New Qt applications should use QListWidget or its base class QListView instead, and call QListView::setViewMode(QListView::IconMode) to obtain an "icon view" look.

See Model-View Programming for an overview of the new item view classes.

## QImage

QImage::fromMimeSource(const QString &) -> qImageFromMimeSource(const QString &)

## QIntCache<T>

QIntCache<T> has been moved to the Qt 3 compatibility library. It has been replaced by QCache<int, T>.

For details, read the section on QCache<T>, mentally substituting `int` for QString.

## QIntDict<T>

QIntDict<T> and QIntDictIterator<T> have been moved to the Qt 3 compatibility library. They have been replaced by the more modern QHash<Key, T> and QMultiHash<Key, T> classes and their associated iterator classes.

When porting old code that uses QIntDict<T> to Qt 4, there are four classes that you can use:

- QMultiHash<int, T *>
- QMultiHash<int, T *>
- QHash<int, T>
- QHash<int, T>

For details, read the section on QDict<T>, mentally substituting `int` for QString.

## QIODevice

Virtuals readBlock and writeBlock now accept a Q_LONG length argument (rather than a Q_ULONG). All subclass will need to change as this is a pure virtual function build errors will occur.

## QListBox

The QListBox, QListBoxItem, QListBoxText, and QListBoxPixmap classes have been moved to the Qt 3 compatibility library. New Qt applications should use QListWidget or its base class QListView instead.

See Model-View Programming for an overview of the new item view classes.

## QListView

The QListView, QListViewItem, QCheckListItem, and QListViewItemIterator classes have been renamed Q3ListView, Q3ListViewItem, Q3CheckListItem, and Q3ListViewItemIterator, and have been moved to the Qt 3 compatibility library. New Qt applications should use one of the following four classes instead: QTreeView or QTreeWidget for tree-like structures; QListWidget or the new QListView class for one-dimensional lists.

See Model-View Programming for an overview of the new item view classes.

## QLocalFs

The QLocalFs class is no longer part of the public Qt API. It has been moved to the Qt 3 compatibility library. Use QDir, QFileInfo, or QFile instead.

## QMemArray<T>

QMemArray<T> has been moved to the Qt 3 compatibility library. It has been replaced by the QVector<T> class.

The following table summarizes the API differences between the two classes.

QMemArray::assign(const QMemArray<T> &) | QVector::operator=()
QMemArray::assign(const T *, uint) | See remark below
QMemArray::duplicate(const QMemArray &) | QVector::operator=()
QMemArray::duplicate(const T *, uint) | See remark below
QMemArray::setRawData(const T *, uint) | N/A
QMemArray::resetRawData(const T *, uint) | N/A
QMemArray::find(const T &, uint) | QVector::indexOf(const T &, int)
QMemArray::contains(const T &) | QVector::count(const T &)
QMemArray::sort() | qHeapSort()
QMemArray::bsearch(const T &d) | qBinaryFind()
QMemArray::at(uint) | QVector::operator[]()
QMemArray::operator const T *() | QVector::constData()

Remarks:

1. QMemArray::assign(const T *, uint) and QMemArray::duplicate(const T *, uint) can be replaced by QVector::resize() and qCopy().

   For example, if you have code like

               QMemArray<QSize> array;
               ...
               array.assign(data, size);

   you can rewrite it as

               QVector<QSize> vector;
               ...
               vector.resize(size);
               qCopy(data, data + size, vector.begin());

2. QMemArray is an explicitly shared class, whereas QVector is implicitly shared. See Explicit Sharing for more information.

## QMimeSourceFactory

The QMimeSourceFactory has been moved to the Qt 3 compatibility library. New Qt applications should use Qt 4's Resource System instead.

## QMultiLineEdit

The QMultiLineEdit class in Qt 3 was a convenience QTextEdit subclass that provided an interface compatible with Qt 2's QMultiLineEdit class. In Qt 4, it inherits Q3TextEdit and is part of the Qt 3 compatibility library. Use QTextEdit in new code.

## QNetworkProtocol

The QNetworkProtocol, QNetworkProtocolFactoryBase, QNetworkProtocolFactory<T>, and QNetworkOperation classes are no longer part of the public Qt API. They have been moved to the Qt 3 compatibility library.

In Qt 4 applications, you can use classes like QFtp and QHttp directly to perform file-related actions on a remote host.

## QObject

children() and QueryList now return a QObjectList instead of a pointer to a QObjectList. See also the comments on QObjectList.

killTimers() has been removed.

## QObjectDictionary

The QObjectDictionary class is a synonym for QAsciiDict<QMetaObject>. See the section on QAsciiDict<T>.

## QObjectList

In Qt 3, the QObjectList class was a typedef for QPtrList<QObject>. In Qt 4, it is a typedef for QList<QObject *>. See the section on QPtrList<T>.

## QPaintDevice

To reimplement painter backends one previously needed to reimplement the virtual function QPaintDevice::cmd(). This function is taken out and should is replaced with the function QPaintDevice::paintEngine() and the abstract class QPaintEngine. QPaintEngine provides virtual functions for all drawing operations that can be performed on a painter backend.

bitBlt and copyBlt are now only compatibility functions. Use QPainter and drawPixmap instead.

## QPicture

Probably something needs to be said about new stuff from painting? Don't know, I didn't do that part.

QPicture::copy() is deprecated and QPicture::detach() is now a public internal function. In general, one should have never needed to call these functions.

## QPixmap

QPixmap::fromMimeSource(const QString &) -> qPixmapFromMimeSource(const QString &)

## QPointArray

In Qt 3, QPointArray inherited from QMemArray<QPoint>. In Qt 4, it inherits from QVector<QPoint>. Everything mentioned in the section on QMemArray<T> apply for QPointArray as well.

The QPointArray::setPoints() and QPointArray::putPoints() functions returned a bool in Qt 3, indicating whether the array was successfully resized or not. In Qt 4, they return void.

## QPrinter

page setup / print setup -> Use QPrintDialog, QPageSetupDialog Compat functions: margins Killed -> setMargins

## QPtrCollection<T>

The QPtrCollection<T> abstract base class has been moved to the Qt 3 compatibility library. There is no direct equivalent in Qt 4.

## QPtrDict<T>

QPtrDict<T> and QPtrDictIterator<T> have been moved to the Qt 3 compatibility library. They have been replaced by the more modern QHash<Key, T> and QMultiHash<Key, T> classes and their associated iterator classes.

When porting old code that uses QPtrDict<T> to Qt 4, there are four classes that you can use:

- QMultiHash<void *, T *>
- QMultiHash<void *, T *>
- QHash<void *, T>
- QHash<void *, T>

(You can naturally use other types than `void *` for the key type, e.g. `QWidget *`.)

To port QPtrDict<T> to Qt 4, read the section on QDict<T>, mentally substituting `void *` for QString.

## QPtrList<T>

QPtrList<T>, QPtrListIterator<T>, and QPtrListStdIterator<T> have been moved to the Qt 3 compatibility library. They have been replaced by the more modern QList and QLinkedList classes and their associated iterator classes.

When porting to Qt 4, you have the choice of using QList<T> or QLinkedList<T> as alternatives to QValueList<T>. QList<T> has an index-based API and provides very fast random access (QList::operator[]), whereas QLinkedList<T> has an iterator-based API.

The following table summarizes the API differences between QPtrList<T> and QList<T *>:

QPtrList function | QList equivalent
--- | ---
QPtrList::contains(const T *) | QList::count(T *)
QPtrList::containsRef(const T *) | QList::count(T *)
QPtrList::find(const T *) | See remark below
QPtrList::findRef(const T *) | See remark below
QPtrList::getFirst() | QList::first()
QPtrList::getLast() | QList::last()
QPtrList::inSort(const T *) | N/A
QPtrList::remove(const T *) | QList::removeAll(T *)
QPtrList::remove(uint) | QList::removeAt(int)
QPtrList::removeNode(QLNode *) | N/A
QPtrList::removeRef(const T *) | QList::removeAll(T *)
QPtrList::sort() | See remark below
QPtrList::takeNode(QLNode *) | N/A
QPtrList::toVector(QGVector *) | See remark below

Remarks:

1. QPtrList::toVector(QGVector *) can be replaced by QVector::resize() and qCopy().

   For example, if you have code like

               QPtrList<QWidget> list;
               ...
               QPtrVector<QWidget> vector;
               list.toVector(&vector);

   you can rewrite it as

               QList<QWidget *> list;
               ...
               QVector<QWidget *> vector;
               vector.resize(list.size());
               qCopy(list.begin(), list.end(), vector.begin());

2. QPtrList::sort() relied on the virtual comparedItems() to sort items. In Qt 4, you can use qHeapSort() instead and pass your "compare item" function as an argument.
3. QPtrList::find(const T *) returns an iterator, whereas QList::indexOf(T *) returns an index. To convert an index into an iterator, add the index to QList::begin().
4. QPtrList::removeFirst() and QPtrList::removeLast() return a `bool` that indicates whether the element was removed or not. The corresponding QList functions return `void`. You can achieve the same result by calling QList::isEmpty() before attempting to remove an item.

If you use QPtrList's auto-delete feature (by calling QPtrList::setAutoDelete(true)), you need to do some more work. You have two options: Either you call `delete` yourself whenever you remove an item from the container, or you can use QList<T> instead of QList<T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call `delete`. (See What's Wrong with Auto-Delete for an explanation of why the Qt 4 containers don't offer that feature.)

The following table summarizes the idioms that you need to watch out for if you want to call `delete` yourself.

QPtrList idiom | QList idiom
--- | ---

            list.replace(index, value);

            delete list[index];
            list[index] = value;

            list.removeFirst();

            delete list.takeFirst();

            list.removeLast();

            delete list.takeLast();

            list.remove(index);

            delete list.take(index);

            list.remove(value);

            int i = list.indexOf(value);
            if (i != -1)
                delete list.takeAt(i);

            list.remove();

(removes the current item)

            QListMutableIterator<T *> i;
            ...
            delete i.value();
            i.remove();

            list.clear();

(also called from QPtrList's destructor)

            while (!list.isEmpty())
                delete list.takeFirst();

In 99% of cases, the following idiom also works:

            qDeleteAll(list);
            list.clear();

However, it may lead to crashes if `list` is referenced from the value type's destructor, because `list` contains dangling pointers until clear() is called.

Be aware that QPtrList's destructor automatically calls clear(). If you have a QPtrList data member in a custom class and use the auto-delete feature, you will need to call `delete` on all the items in the container from your class destructor to avoid a memory leak.

QPtrList had the concept of a "current item", which could be used for traversing the list without using an iterator. When porting to Qt 4, you can use the Java-style QListIterator<T *> (or QListMutableIterator<T *>) class instead. The following table summarizes the API differences:

QPtrList function | QListIterator equivalent
--- | ---
QPtrList::at() | N/A
QPtrList::current() | QListIterator::value()
QPtrList::currentNode() | N/A
QPtrList::findNext(const T *) | QListIterator::findNext(const T *)
QPtrList::findNextRef(const T *) | QListIterator::findNext(const T *)
QPtrList::first() | QPtrList::toFront()
QPtrList::last() | QPtrList::toBack()
QPtrList::next() | QPtrList::next()
QPtrList::prev() | QPtrList::previous()
QPtrList::remove() | QListMutableIterator::remove()
QPtrList::take() | QListMutableIterator::remove()

Be aware that QListIterator has a different way of iterating than QPtrList. A typical loop with QPtrList looks like this:

            QPtrList<QWidget> list;
            ...
            while (list.current() != 0) {
                do_something(list.current());
                list.next();
            }

Here's the equivalent QListIterator loop:

            QList<QWidget *> list;
            ...
            QListIterator<QWidget *> i(list);
            while (i.hasNext())
                do_something(i.next());

Finally, QPtrListIterator<T> must also be ported. There are no fewer than four iterator classes that can be used as a replacement: QList::const_iterator, QList::iterator, QListIterator, and QListMutableIterator. The most straightforward class to use when porting is QListMutableIterator<T *> (if you modify the list through the iterator) or QListIterator<T *> (if you don't). The following table summarizes the API differences:

QPtrListIterator function | Qt 4 equivalent
--- | ---
QPtrListIterator::atFirst() | !QListIterator::hasPrevious() (notice the `!`)
QPtrListIterator::atLast() | !QListIterator::hasNext() (notice the `!`)
QPtrListIterator::count() | QList::count() or QList::size()
QPtrListIterator::current() | QListIterator::value()
QPtrListIterator::isEmpty() | QList::isEmpty()
QPtrListIterator::toFirst() | QListIterator::toFront()
QPtrListIterator::toLast() | QListIterator::toBack()
QPtrListIterator::operator() | QListIterator::value()
QPtrListIterator::operator*() | QListIterator::value()

Again, be aware that QListIterator has a different way of iterating than QPtrList. A typical loop with QPtrList looks like this:

            QPtrList<QWidget> list;
            ...
            QPtrListIterator<QWidget> i;
            while (i.current() != 0) {
                do_something(i.current());
                i.next();
            }

Here's the equivalent QListIterator loop:

            QList<QWidget *> list;
            ...
            QListIterator<QWidget *> i(list);
            while (i.hasNext())
                do_something(i.next());

Finally, QPtrListStdIterator<T> must also be ported. This is easy, because QList also provides STL-style iterators (QList::iterator and QList::const_iterator).

## QPtrQueue<T>

QPtrQueue has been moved to the Qt 3 compatibility library. It has been replaced by the more modern QQueue class.

The following table summarizes the differences between QPtrQueue<T> and QQueue<T *>:

QPtrQueue function | QQueue equivalent
--- | ---
QPtrQueue::autoDelete() | See discussion below
QPtrQueue::count() | QQueue::count() or QQueue::size() (equivalent)
QPtrQueue::current() | QQueue::head()
QPtrQueue::remove() | QQueue::dequeue()
QPtrQueue::setAutoDelete() | See discussion below

If you use QPtrQueue's auto-delete feature (by calling QPtrQueue::setAutoDelete(true)), you need to do some more work. You have two options: Either you call `delete` yourself whenever you remove an item from the container, or you can use QQueue<T> instead of QQueue<T *> (i.e. store values directly instead of pointers to values). Here, we will show when to call `delete`. (See What's Wrong with Auto-Delete for an explanation of why the Qt 4 containers don't offer that feature.)

QPtrQueue idiom | QQueue idiom
--- | ---

            queue.dequeue();

            delete queue.dequeue();

            queue.remove();

            delete queue.dequeue();

            queue.clear();

(also called from QPtrQueue's destructor)

            while (!queue.isEmpty())
                delete queue.dequeue();

In 99% of cases, the following idiom also works:

            qDeleteAll(queue);
            queue.clear();

However, it may lead to crashes if `queue` is referenced from the value type's destructor, because `queue` contains dangling pointers until clear() is called.

## QPtrStack<T>

QPtrStack has been moved to the Qt 3 compatibility library. It has been replaced by the more modern QStack class.

The following table summarizes the differences between QPtrStack<T> and QStack<T *>:

QPtrStack function | QStack equivalent
--- | ---
QPtrStack::autoDelete() | See discussion below
QPtrStack::count() | QStack::count() or QStack::size() (equivalent)
QPtrStack::current() | QStack::top()
QPtrStack::remove() | QStack::pop()
QPtrStack::setAutoDelete() | See discussion below

If you use QPtrStack's auto-delete feature (by calling QPtrStack::setAutoDelete(true)), you need to do some more work. You have two options: Either you call `delete` yourself whenever you remove an item from the container, or you can use QStack<T> instead of QStack<T *> (i.e. store values directly instead of pointers to values). Here, we will show when to call `delete`. (See What's Wrong with Auto-Delete for an explanation of why the Qt 4 containers don't offer that feature.)

QPtrStack idiom | QStack idiom
--- | ---

            stack.pop();

            delete stack.pop();

            stack.remove();

            delete stack.pop();

            stack.clear();

(also called from QPtrStack's destructor)

            while (!stack.isEmpty())
                delete stack.pop();

In 99% of cases, the following idiom also works:

            qDeleteAll(stack);
            stack.clear();

However, it may lead to crashes if `stack` is referenced from the value type's destructor, because `stack` contains dangling pointers until clear() is called.

## QPtrVector<T>

QPtrVector<T> has been moved to the Qt 3 compatibility library. It has been replaced by the more modern QVector class.

When porting to Qt 4, you can use QVector<T *> as an alternative to QPtrVector<T>. The APIs of QPtrVector<T> and QVector<T *> are somewhat similar. The main issue is that QPtrVector supports auto-delete whereas QVector doesn't. (See What's Wrong with Auto-Delete for an explanation of why the Qt 4 containers don't offer that feature.)

The following table summarizes the API differences between the two classes:

QPtrVector function | QVector equivalent
--- | ---
QPtrVector::autoDelete() | See discussion below
QPtrVector::bsearch(const T *) | qBinaryFind()
QPtrVector::contains(const T *) | QVector::count(T *)
QPtrVector::containsRef(const T *) | QVector::count(T *)
QPtrVector::count() | See remark below
QPtrVector::insert(uint, T *) | See remark below
QPtrVector::isNull() | N/A
QPtrVector::remove(uint) | See remark below
QPtrVector::setAutoDelete() | See discussion below
QPtrVector::sort() | qHeapSort()
QPtrVector::take(uint) | See remark below
QPtrVector::toList(QGList *) | QList::QList(const QVector &)

Remarks:

1. QPtrVector::insert(uint, T *) sets an item to store a certain pointer value. This is not the same as QVector::insert(int, T *), which creates space for the item by moving following items by one position. Use `vect[i] = ptr` to set a QVector item to a particular value.
2. QPtrVector::remove(uint) sets an item to be 0. This is not the same as QVector::removeAt(int), which entirely erases the item, reducing the size of the vector. Use `vect[i] = 0` to set a QVector item to 0.
3. Likewise, QPtrVector::take(uint) sets an item to be 0 and returns the previous value of the item. Again, this is easy to achieve using QVector::operator[]().
4. QPtrVector::count() returns the number of non-null items in the vector, whereas QVector::count() (like QVector::size()) returns the number of items (null or non-null) in the vector. Fortunately, it's not too hard to simulate QPtrVector::count().

   For example, if you have code like

               int numValidItems = vect.count();

   you can rewrite it as

               int numValidItems = vect.size() - vect.count(0);

If you use QVector's auto-delete feature (by calling QVector::setAutoDelete(true)), you need to do some more work. You have two options: Either you call `delete` yourself whenever you remove an item from the container, or you use QVector<T> instead of QVector<T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call `delete`.

The following table summarizes the idioms that you need to watch out for if you want to call `delete` yourself.

QPtrVector idiom | QVector idiom
--- | ---

            vect.insert(i, ptr);

            delete vect[i];
            vect[i] = ptr;

            vect.remove(i);

            delete vect[i];
            vect[i] = 0;

            T *ptr = vect.take(i);

            T *ptr = vect[i];
            vect[i] = 0;

            vect.resize(n)

            while (n > vect.size())
                vect.append(0);
            while (n < vect.size() {
                T *ptr = vect.last();
                vect.remove(vect.size() - 1);
                delete ptr;
            }

            vect.clear();

(also called from QPtrVector's destructor)

            for (int i = 0; i < vect.size(); ++i)
                T *ptr = vect[i];
                vect[i] = 0;
                delete ptr;
            }

In 99% of cases, the following idiom also works:

            qDeleteAll(vect);
            vect.clear();

However, it may lead to crashes if `vect` is referenced from the value type's destructor, because `vect` contains dangling pointers until clear() is called.

Be aware that QPtrVector's destructor automatically calls clear(). If you have a QPtrVector data member in a custom class and use the auto-delete feature, you will need to call `delete` on all the items in the container from your class destructor to avoid a memory leak.

## QRangeControl

In Qt 3, various "range control" widgets (QDial, QScrollBar, QSlider, and QSpinBox) inherited from both QWidget and QRangeControl.

In Qt 4, QRangeControl has been replaced with the new QAbstractSlider class, which inherits from QWidget and provides similar functionality. Apart from eliminating unnecessary multiple inheritance, the new design allows QAbstractSlider to contain signals, slots, and properties.

The old QRangeControl class has been moved to the Qt 3 compatibility library, together with the (undocumented) QSpinWidget class.

If you use QRangeControl as a base class in your application, you can switch to use QAbstractSlider instead.

For example, if you have code like

            class VolumeControl : public QWidget, public QRangeControl
            {
                ...
            protected:
                void valueChange() {
                    update();
                    emit valueChanged(value());
                }
                void rangeChange() {
                    update();
                }
                void stepChange() {
                    update();
                }
            };

you can rewrite it as

            class VolumeControl : public QAbstractSlider
            {
                ...
            protected:
                void sliderChange(SliderChange change) {
                    update();
                    if (change == SliderValueChange)
                        emit valueChanged(value());
                }
            };

## QRegion

The following changes have been made to QRegion in Qt 4:

- There is no longer any difference between a null region and an empty region. Use isEmpty() in most places where you would have used a null QRegion.
- QRegion::rects() used to return a QMemArray<QRect>. It now returns a QVector<QRect>.

## QScrollView

The QScrollView class has been moved to the Qt 3 compatibility library. It has been replaced by the QViewport and QWidgetView classes.

QScrollView was designed to work around the 16-bit limitation on widget coordinates found on most window systems. In Qt 4, this is done transparently for all widgets, so there is no longer a need for such functionality in QScrollView. For that reason, the new QViewport and QWidgetView classes are much more lightweight, and concentrate on handling scroll bars.

If you used QScrollView as a base class

## QShared

The QShared class has been obsoleted by the more powerful QSharedData and QSharedDataPointer as a means of creating custom implicitly shared classes. It has been moved to the Qt 3 compatibility library.

An easy way of porting to Qt 4 is to include this class into your project and to use it instead of QShared:

            struct Shared
            {
                Shared() : count(1) {}
                void ref() { ++count; }
                bool deref() { return !--count; }
                uint count;
            };

If possible, we recommend that you use QSharedData and QSharedDataPointer instead. They provide thread-safe reference counting and handle all the reference counting behind the scenes, eliminating the risks of forgetting to increment or decrement the reference count.

## QSignal

The QSignal class has been completely redesigned in Qt 4. For compatibility, the old QSignal class has been renamed Q3Signal and has been moved to the Qt 3 compatibility library.

The new QSignal class is a template class, where the template type gives the parameter type of the signal. For example, if you used Q3Signal class's @C{intSignal(int)} signal, you can now use QSignal<int>'s @C{signal(int)} signal instead.

The Q3Signal::setParameter(), Q3Signal::parameter(), Q3Signal::setValue(), and Q3Signal::value() functions have no direct equivalent in Qt 4. Instead, pass the value to QSignal::activate().

For example, if you have code like

            QSignal signal;
            signal.connect(target, SLOT(display(int)));
            ...
            signal.setParameter(5);
            signal.activate();

you can rewrite it as

            QSignal<int> signal;
            signal.connect(target, SLOT(display(int)));
            ...
            signal.activate(5);

## QSlider

The QSlider::sliderStart() and QSlider::sliderRect() functons have been removed. You can retrieve this information using QAbstractSlider::sliderPosition() and QStyle::querySubControlMetrics(), respectively.

## QSortedList

The QSortedList<T> class has been deprecated since Qt 3.0. In Qt 4, it has been moved to the Qt 3 compatibility library.

In new code, we recommend that you use QList<T> instead and use qHeapSort() to sort the items.

## QSplitter

The function setResizeMode() has been moved into compat. Set the stretch factor in the widget's size policy to get equivalent functionality.

The obsolete function drawSplitter() has been removed. Use QStyle::drawPrimitive() to acheive similar functionality.

## QSqlCursor

The QSqlCursor class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QSqlDatabase

QSqlDatabase is now a smart pointer that is passed around by value. Simply replace all QSqlDatabase pointer by QSqlDatabase objects.

## QSqlEditorFactory

The QSqlEditorFactory class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QSqlError

The enum `Type` was renamed to `ErrorType`, The values were renamed as well:

- None - use NoError instead
- Connection - use ConnectionError instead
- Statement - use StatementError instead
- Transaction - use TransactionError instead
- Unknown - use UnknownError instead

## QSqlFieldInfo

The QSqlFieldInfo class has been moved to the Qt 3 compatibility library. Its functionality is now provided by the QSqlField class.

See SQL Module for an overview of the new item SQL classes.

## QSqlForm

The QSqlForm class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QSqlPropertyMap

The QSqlPropertyMap class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QSqlQuery

QSqlQuery::prev() was renamed to QSqlQuery::previous(). There is a function call for compatibility, but if you subclassed QSqlQuery, you have to reimplement previous() instead of prev().

## QSqlRecord

QSqlRecord behaves like a vector now, QSqlRecord::insert() will actually insert a new field instead of replacing the existing one.

## QSqlRecordInfo

The QSqlRecordInfo class has been moved to the Qt 3 compatibility library. Its functionality is now provided by the QSqlRecord class.

See SQL Module for an overview of the new item SQL classes.

## QSqlSelectCursor

The QSqlSelectCursor class has been moved to the Qt 3 compatibility library.

See SQL Module for an overview of the new item SQL classes.

## QStr(I)List

The QStrList and QStrIList convenience classes have been deprecated since Qt 2.0. In Qt 4, they have been moved to the Qt 3 compatibility library. If you used any of these, we recommend that you use QStringList or QList<QByteArray> instead.

## QStr(I)Vec

The QStrVec and QStrIVec convenience classes have been deprecated since Qt 2.0. In Qt 4, they have been moved to the Qt 3 compatibility library. If you used any of these, we recommend that you use QStringList or QList<QByteArray> instead.

## QString

Here are the main issues to be aware of when porting QString to Qt 4:

1. The QString::QString(QChar) constructor performed implicit conversion in Qt 3. Now, you will need a cast to convert a QChar to a QString.
2. The QString::QString(const QByteArray &) constructor used to stop at the first '\0' it encountered, for compatibility with Qt 1. This quirk has now been fixed; in Qt 4, the resulting QString always has the same length as the QByteArray that was passed to the constructor.
3. The QString::null static constant has been deprecated in Qt 4. For compatibility, Qt 4 provides a QString::null symbol that behaves more or less the same as the old constant. The new idiom is to write QString() instead of QString::null, or to call clear().

   For example, if you have code like

                   str1 = QString::null;
                   if (str2 == QString::null)
                       do_something(QString::null);

   you can rewrite it as

                   str1.clear();
                   if (str2.isNull())
                       do_something(QString());

4. QString::at() returned a non-const reference, whereas the new QString::at() returns a const value. Code like

               str.at(0) = 'X';

   will no longer compile. Instead, use QString::operator[]:

               str[0] = 'X';

5. The QString::contains(x) function (where x is a character or a string) has been renamed QString::count(x). In addition, there now exists a set of QString::contains() functions that returns a boolean value. Replace old calls to contains() with either count() or contains(), depending on whether you care about the specific number of occurrences of a character in the string or only care about whether the string contains that character or not.
6. Many functions in QString had a `bool` parameter that specified case sensitivity. In Qt 4, in the interest of code readability and maintainability, the `bool` parameters have been replaced by the Qt::CaseSensitivity enum, which can take the values Qt::CaseSensitive and Qt::CaseInsensitive.

   For example, if you have code like

                   if (url.startsWith("http:", false))
                       ...

   you can rewrite it as

                   if (url.startsWith("http:", Qt::CaseInsensitive))
                       ...

7. The QString::setExpand(uint, QChar) function, which already was obsolete in Qt 3, is no longer available. Use QString::operator[] instead.

   For example, if you have code like

                   str.setExpand(32, '$');

   you can rewrite it as

                   str[32] = '$';

8. The `QT_NO_ASCII_CAST` and `QT_NO_CAST_ASCII` macros have been renamed `QT_NO_CAST_TO_ASCII` and `QT_NO_CAST_FROM_ASCII`, respectively.
9. QString::ascii() and QString::latin1() now return "" (the empty string) rather than 0 (the null pointer). The new behavior prevents crashes when interfacing with the standard C++ library.
10. QString::utf8() and QString::local8Bit() used to return a QByteArray. They now return a `const char *`, to be consistent with QString::ascii() and QString::latin1(). Call QString::toUtf8() or QString::toLocal8Bit() if you want a QByteArray.
11. The QString::data() used to return the same as QString::ascii(). It now returns a pointer to the Unicode data stored in the QString object. Call QString::ascii() if you want the old behavior.
12. QString::simpleText() has been renamed QString::isSimpleText().

## QStringList

QStringList now inherits from QList<QString> and can no longer be converted to a QValueList<QString>. Since QValueList inherits QList a cast will work as expected.

This change implies some API incompatibilities for QStringList. For example, at() returns the string, not an iterator. See the section on QValueList for details.

## QTabDialog

The QTabDialog class is no longer part of the public Qt API. It has been moved to the Qt 3 compatibility library. In Qt 4 applications, you can easily obtain the same result by combining a QTabWidget with a QDialog and provide QPushButtons yourself.

## QTable

The QTable, QTableItem, QComboTableItem, QCheckTableItem, and QTableSelection classes have been moved to the Qt 3 compatibility library. New Qt applications should use the new QTableWidget or QTableView class instead.

See Model-View Programming for an overview of the new item view classes.

## QTextOStreamIterator

The undocumented QTextOStreamIterator class has been removed from the Qt library. If you need it in your application, feel free to copy the source code from the Qt 3 `<qtl.h>` header file.

## QUrl

The QUrl class has been rewritten from scratch in Qt 4 to be more standard-compliant. The old QUrl class has been renamed Q3Url and moved to the Qt 3 compatibility library.

The new QUrl class provides an extensive list of compatibility functions to ease porting from Q3Url to QUrl. A few functions require you to change your code:

- Q3Url::Q3Url(const Q3Url &, const QString &, bool) can be simulated by combining the URLs manually (using QString::operator+(), for example).
- Q3Url::setEncodedPathAndQuery(const QString &) is replaced by QUrl::setPath() and QUrl::setEncodedQuery().
- Q3Url::encodedPathAndQuery() is replaced by QUrl::path() and QUrl::encodedQuery().
- Q3Url::isLocalFile() can be simulated by checking that QUrl::protocol() is "file".
- Q3Url::toString(bool, bool) is replaced by QUrl::toString(int), where the `int` parameter specifies a combination of formatting options.

## QUrlOperator

The QUrlOperator class is no longer part of the public Qt API. It has been moved to the Qt 3 compatibility library.

In Qt 4 applications, you can use classes like QFtp and QHttp directly to perform file-related actions on a remote host.

## QValueList<T>

The QValueList<T> class has been replaced by QList<T> and QLinkedList<T> in Qt 4. As a help when porting older Qt applications, the Qt 3 compatibility library contains a QValueList<T> class implemented in terms of the new QLinkedList<T>. Similarly, it contains QValueListIterator<T> and QValueListConstIterator<T> classes implemented in terms of QLinkedList<T>::iterator and QLinkedList<T>::const_iterator.

When porting to Qt 4, you have the choice of using QList<T> or QLinkedList<T> as alternatives to QValueList<T>. QList<T> has an index-based API and provides very fast random access (QList::operator[]), whereas QLinkedList<T> has an iterator-based API.

Here's a list of problem functions:

- QValueList(const std::list<T> &) doesn't exist in QList or QLinkedList. You can simulate it by calling append() in a loop.
- QValueList::insert(iterator, size_type, const T& x) doesn't exist in QList or QLinkedList. Call insert() repeatedly instead.
- QValueList::fromLast() doesn't exist in QList or QLinkedList. Use QValueList::end() instead.

  For example, if you have code like

              for (QValueList<T>::iterator i = list.fromLast(); i != list.end(); ++i)
                  do_something(*i);

  you can rewrite it as

              QLinkedList<T>::iterator i = list.end();
              while (i != list.begin()) {
                  --i; // decrement i before using it
                  do_something(*i);
              }

- QValueList::append() and QValueList::prepend() return an iterator to the inserted item. QList's and QLinkedList's corresponding functions don't, but it's not a problem because QValueList::prepend() always returns begin() and append() always returns QValueList::end() - 1.
- QValueList::at(i) return an iterator to the item at index i. This corresponds to QList::begin() + i.
- QValueList::contains(const T &) corresponds to QList::count(const T &) and QLinkedList::count(const T &).

## QValueVector<T>

The QValueVector<T> class has been replaced by QVector<T> in Qt 4. As a help when porting older Qt applications, the Qt 3 compatibility library contains a QValueVector<T> class implemented in terms of the new QVector<T>.

When porting from QValueVector<T> to QVector<T>, you might run into the following incompatibilities:

- QValueVector(const std::vector<T> &) doesn't exist in QVector. You can simulate it by calling QVector::append()} in a loop.
- QValueVector::resize(int, const T &) doesn't exist in QVector. If you want the new items to be initialized with a particular value, use QVector::insert() instead.
- QValueVector::at() on a non-const vector returns a non-const reference. This corresponds to QVector::operator[]().
- Both QValueVector::at() functions have an ok parameter of type `bool *` that is set to true if the index is within bounds. This functionality doesn't exist in QVector; instead, check the index against QVector::size() yourself.

See Generic Containers for an overview of the Qt 4 container classes.

## QVariant

The QVariant class has been split into two classes: QCoreVariant and QVariant. The new QVariant class inherits QCoreVariant and adds GUI-related types. In practice, this has no consequences for existing Qt applications.

In addition, some changes to the rest of the Qt library have implications on QVariant as well:

1. The `QCoreVariant::ColorGroup` enum value is defined only if `QT_COMPAT` is defined.
2. The `QCoreVariant::IconSet` enum value has been renamed `QCoreVariant::Icon`.
3. The `QCoreVariant::CString` enum value is now a synonym for `QCoreVariant::ByteArray`.

## QVBox

The QVBox class has been renamed QVBoxWidget.

## QWidget

Widget background painting has been greatly improved, supporting flickerfree updates and making it possible to have half transparent widgets. This renders the following background handling functions obsolete:

- QWidget::repaint(bool noErase) - the `noErase` boolean parameter is gone
- QWidget::setBackgroundMode(BackgroundMode m)
- QWidget::backgroundBrush() const
- QWidget::setBackgroundPixmap(const QPixmap &pm)
- QWidget::backgroundPixmap() const
- QWidget::setBackgroundColor(const QColor &c)
- QWidget::backgroundColor() const
- QWidget::foregroundColor() const
- QWidget::eraseColor() const
- QWidget::setEraseColor(const QColor &c)
- QWidget::erasePixmap() const
- QWidget::setErasePixmap(const QPixmap &p)
- QWidget::paletteForegroundColor()
- QWidget::setPaletteForegroundColor(const QColor &c)
- QWidget::paletteBackgroundColor()
- QWidget::setPaletteBackgroundColor(const QColor &c)
- QWidget::paletteBackgroundPixmap() const
- QWidget::setPaletteBackgroundPixmap(const QPixmap &p)
- QWidget::erase()
- QWidget::erase(const QRect &r)
- QWidget::setBackgroundOrigin( BackgroundOrigin )
- QWidget::BackgroundOrigin backgroundOrigin() const
- QWidget::backgroundOffset()

A widget now receives change events in its QWidget::changeEvent() handler. This makes the following virtual change handlers obsolete:

- QWidget::styleChange - use QEvent::StyleChange
- QWidget::enabledChange - use QEvent::EnabledChange
- QWidget::paletteChange - use QEvent::PaletteChange
- QWidget::fontChange - use QEvent::FontChange
- QWidget::windowActivationChange - use QEvent::ActivationChange
- QWidget::languageChange - use QEvent::LanguageChange

The following functions were slots, but are no more:

- QWidget::clearFocus()
- QWidget::setMouseTracking()
- QWidget::stackUnder(QWidget*)
- QWidget::move(int x, int y)
- QWidget::move(const QPoint &)
- QWidget::resize(int w, int h)
- QWidget::resize(const QSize &)
- QWidget::setGeometry(int x, int y, int w, int h)
- QWidget::setGeometry(const QRect &)
- QWidget::adjustSize()
- QWidget::update(int x, int y, int w, int h)
- QWidget::update(const QRect&)
- QWidget::repaint(bool erase)
- QWidget::repaint(int x, int y, int w, int h, bool erase)
- QWidget::repaint(const QRect &, bool erase)
- QWidget::repaint(const QRegion &, bool erase)
- QWidget::setCaption(const QString &)
- QWidget::setIcon(const QPixmap &)
- QWidget::setIconText(const QString &)

The following functions were incorrectly marked as virtual:

- QWidget::close(bool alsoDelete)
- QWidget::create(WId, bool, bool)
- QWidget::destroy(bool)
- QWidget::move(int x, int y)
- QWidget::reparent(QWidget *parent, WFlags, const QPoint &, bool)
- QWidget::resize(int w, int h)
- QWidget::setAcceptDrops(bool on)
- QWidget::setActiveWindow()
- QWidget::setAutoMask(bool)
- QWidget::setBackgroundColor(const QColor &)
- QWidget::setBackgroundMode(BackgroundMode)
- QWidget::setBackgroundOrigin(BackgroundOrigin)
- QWidget::setBackgroundPixmap(const QPixmap &)
- QWidget::setCaption(const QString &)
- QWidget::setCursor(const QCursor &)
- QWidget::setEnabled(bool)
- QWidget::setEraseColor(const QColor &)
- QWidget::setErasePixmap(const QPixmap &)
- QWidget::setFocus()
- QWidget::setFocusPolicy(FocusPolicy)
- QWidget::setFocusProxy(QWidget *)
- QWidget::setFont(const QFont &)
- QWidget::setGeometry(const QRect &)
- QWidget::setGeometry(int x, int y, int w, int h)
- QWidget::setIcon(const QPixmap &)
- QWidget::setIconText(const QString &)
- QWidget::setKeyCompression(bool)
- QWidget::setMask(const QBitmap &)
- QWidget::setMask(const QRegion &)
- QWidget::setMaximumSize(int maxw, int maxh)
- QWidget::setMicroFocusHint(int x, int y, int w, int h, bool, QFont *f)
- QWidget::setMinimumSize(int minw, int minh)
- QWidget::setMouseTracking(bool enable)
- QWidget::setPalette(const QPalette &)
- QWidget::setPaletteBackgroundColor(const QColor &)
- QWidget::setPaletteBackgroundPixmap(const QPixmap &)
- QWidget::setSizeIncrement(int w, int h)
- QWidget::setSizePolicy(QSizePolicy)
- QWidget::setUpdatesEnabled(bool enable)
- QWidget::setWFlags(WFlags)
- QWidget::setWState(uint)
- QWidget::showFullScreen()
- QWidget::showMaximized()
- QWidget::showMinimized()
- QWidget::showNormal()
- QWidget::unsetCursor()

## QWidgetIntDict

The QWidgetIntDict class was a synonym for QIntDict<QWidget>. It is no longer available in Qt 4. If you link against the Qt 3 compatibility library, you can use QIntDict<QWidget> instead; otherwise, see the section on QDict<T>.

## QWidgetList

In Qt 3, the QWidgetList class was a typedef for QPtrList<QWidget>. In Qt 4, it is a typedef for QList<QWidget *>. See the section on QPtrList<T>.

## QWidgetStack

The QWidgetStack class is no longer part of the Qt public API. It has been moved to the Qt 3 compatibility library.

In Qt 4 applications, you can use QStackedLayout instead to obtain the same results.

## QWizard

The QWizard class is no longer part of the Qt public API. It has been moved to the Qt 3 compatibility library. In Qt 4 applications, you can easily obtain the same result by combining a QStackedBox with a QDialog and provide QPushButtons yourself.

The dialogs/simplewizard and dialogs/complexwizard examples show how to create wizards without using QWizard.