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. See also Getting Ready for Qt 4 for tips on how to write Qt 3 code that is easy to port to 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:

Briefly read the porting notes below to get an idea of what to expect.

Be sure that your code compiles and runs well on all your target platforms with Qt 3.

Add the line QT += qt3support to your .pro file if you use qmake; otherwise, edit your makefile or project file to link against the Qt3Support library and add -DQT3_SUPPORT to your compiler flags. (You might also need to specify other libraries. See What's New in Qt 4 for details.)

Run the qt3to4 porting tool. The tool will go through your source code and adapt it to Qt 4.

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.

The qt3to4 porting tool replaces occurrences of Qt 3 classes that don't exist anymore in Qt 4 with the corresponding Qt 3 support class; for example, QListBox is turned into Q3ListBox.

At some point, you might want to stop linking against the Qt 3 support library (Qt3Support) and take advantage of Qt 4's new features. The instructions below explain how to do that for each compatibility class.

In addition to the Qt3Support classes (such as Q3Action, Q3ListBox, and Q3ValueList), Qt 4 provides compatibility functions when it's possible for an old API to cohabit with the new one. For example, QString provides a QString::simplifyWhiteSpace() compatibility function that's implemented inline and that simply calls QString::simplified(). The compatibility functions are not documented here; instead, they are documented for each class.

If you have the line QT += qt3support in your .pro file, qmake will automatically define the QT3_SUPPORT symbol, turning on compatibility function support. You can also define the symbol manually (e.g., if you don't want to link against the Qt3Support library), or you can define QT3_SUPPORT_WARNINGS instead, telling the compiler to emit a warning when a compatibility function is called. (This works only with GCC 3.2+ and MSVC 7.)

If you get stuck, ask on the qt4-preview-feedback mailing list. If you are a licensed customer, you can also contact Trolltech support.

Properties

Some properties have been renamed in Qt 4, to make Qt's API more consistent and more intuitive. For example, QWidget's caption property has been renamed windowTitle to make it clear that it refers to the title shown in the window's title bar.

The table below lists the Qt properties that have been renamed in Qt 4. Occurrences of these in Qt Designer.ui files are automatically converted to the new name by uic.

A handful of properties in Qt 3 are no longer properties in Qt 4, but the access functions still exist as part of the Qt 4 API. These are not used by Qt Designer; the only case where you need to worry about them is in highly dynamic applications that use Qt's meta-object system to access properties. Here's the list of these properties with the read and write functions that you can use instead:

Some properties have been removed from Qt 4, but the associated access functions are provided if QT3_SUPPORT is defined to help porting to Qt 4. When converting Qt 3 .ui files to Qt 4, uic generates calls to the Qt 3 compatibility functions.

The table below lists these properties with the read and write functions that you can use instead. The documentation for the individual functions explains how to replace them with non-compatibility Qt 4 functions.

Explicit Sharing

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.

QAccessibleTitleBar

The QAccessibleTitleBar has been renamed Q3AccessibleTitleBar and moved to the Qt3Support library.

QAction

The QAction class has been redesigned in Qt 4 to integrate better with the rest of the menu system. It unifies the old QMenuItem class and the old QAction class into one class, avoiding unnecessary data duplication and the need to learn two different APIs.

The old QAction and QActionGroup classes have been renamed Q3Action and Q3ActionGroup and moved to Qt3Support. In addition, the new QAction class has compatibility functions to ease transition to Qt 4.

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.

QAsyncIO

The QAsyncIO class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0. If you use this mechanism in your application, please submit a report to the Task Tracker on the Trolltech website and we will try to find a satisfactory substitute.

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.

In Qt 3, QButton had a "toggle type", which could be QButton::SingleShot, QButton::Toggle, or QButton::Tristate. The new QAbstractButton class doesn't support "tristate" directly; this feature is implemented in QCheckBox instead. The two other "toggle types" (QButton::SingleShot and QButton::Toggle) are replaced by a QAbstractButton::checkable property.

In Qt 3, QButton had a "toggle state", which could be QButton::Off, QButton::NoChange, or QButton::On. In Qt 4, this mechanism has been moved to QCheckBox.

See Virtual Functions for a list of QButton virtual member functions in Qt 3 that aren't virtual in Qt 4.

See Properties for a list of QButton properties in Qt 3 that have changed in Qt 4.

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 Qt3Support. Likewise, the QHButtonGroup and QVButtonGroup convenience subclasses have been renamed Q3HButtonGroup and Q3VButtonGroup and moved to the Qt3Support library.

The old QButtonGroup, as well as Q3ButtonGroup, can be used in two ways:

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.

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.

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:

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');

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';

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.

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.

QMemArray::bsearch() and QMemArray::sort() have no equivalent in the new QByteArray class. Use qBinaryFind() and qSort() if you need that functionality.

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.

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.

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);

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,

Qt 4.1 is expected to provide a replacement module for these classes, based on Qt 4's powerful new 2D paint system.

QColor

In Qt 4, QColor is a value type like QPoint or QRect. Graphics system-specific code has been implemented in QColorMap.

The numBitPlanes() function has been replaced by QColorMap::depth().

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 QT3_SUPPORT is defined.

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(QPalette::Background));

QColorDrag

The QColorDrag class has been renamed Q3ColorDrag and moved to the Qt3Support library. In Qt 4, use QMimeData instead and call QMimeData::setColor() to set the color.

QComboBox

In Qt 3, the list box used to display the contents of a QComboBox widget could be accessed by using the listBox() function. In Qt 4, the standard list box is provided by a QListView widget, and can be accessed with the view() function.

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:

The Qt3Support library contains a class called Q3CString 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 Q3CString:

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

QDataBrowser

The QDataBrowser class has been renamed Q3DataBrowser and moved to the Qt3Support library. It is expected that Qt 4.1 will offer a replacement class. In the meantime, you can use Q3DataBrowser for creating data-aware forms or you can roll your own.

QDataPump

The QDataPump class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.

If you use this mechanism in your application, please submit a
report to the \l{Task Tracker} on the Trolltech
website and we will try to find a satisfactory substitute.

QDataSink

The QDataSink class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.

If you use this mechanism in your application, please submit a
report to the \l{Task Tracker} on the Trolltech
website and we will try to find a satisfactory substitute.

QDataSource

The QDataSource class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.

If you use this mechanism in your application, please submit a
report to the \l{Task Tracker} on the Trolltech
website and we will try to find a satisfactory substitute.

QDataTable

The QDataTable class has been renamed Q3DataTable and moved to the Qt3Support library. It is expected that Qt 4.1 will offer a replacement class. In the meantime, you can use Q3DataTable for creating data-aware forms or you can roll your own.

QDataView

The QDataView class has been renamed Q3DataView and moved to the Qt3Support library. It is expected that Qt 4.1 will offer a replacement class. In the meantime, you can use Q3DataTable for creating data-aware forms or you can roll your own.

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 renamed Q3DeepCopy<T> and moved to the Qt3Support library. Removing it from existing code is straightforward.

Q3Dict requires the user to allocate a specific number of buckets by passing a prime number (17 by default) to the constructor and/or calling Q3Dict::resize() later on. In contrast, QMultiHash's hash table automatically grows and shrinks as needed, and the constructor doesn't take a prime number.

Q3Dict 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.

Q3Dict::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.

If there are multiple items with the same key, Q3Dict::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().

Q3Dict has only one [] operator (Q3Dict::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, Q3Dict::operator[] should be converted to QMultiHash::value(), not QMultiHash::operator[].

If you use Q3Dict's auto-delete feature (by calling Q3Dict::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.

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 Q3Dict's destructor automatically calls clear(). If you have a Q3Dict 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.

fileInfoList(), entryInfoList(), and drives() now return a QList<QFileInfo> and not a QPtrList<QFileInfo> *. Code using these methods will not work with the Qt3Support library and must be adapted instead.

See Virtual Functions for a list of QDir virtual member functions in Qt 3 that are no longer virtual in Qt 4.

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.

QFocusData

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.

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().

To help with porting, the Qt3Support 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.

The IO_xxx flags have been revised. Most of them have been elimiated, because errors are best handled by the actual QIODevice subclasses than through the base classes. The file access flags, such as IO_ReadOnly and IO_WriteOnly, have been moved to the QIODevice class to avoid polluting the global namespace. The table below shows the correspondence between the Qt 3 IO_xxx flags and the Qt 4 API:

QIODeviceSource

The QIODeviceSource class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.

If you use this mechanism in your application, please submit a
report to the \l{Task Tracker} on the Trolltech
website and we will try to find a satisfactory substitute.

QLabel

QLabel doesn't enable word-wrap automatically anymore when rich text is used. You can enable it by calling QLabel::setWordWrap() or by setting the wordWrap property. The reason for this change is that the old behavior was confusing to many users.

QLocalFs

QMainWindow

The QMainWindow class has been redesigned in Qt 4 to provide a more modern look and feel and more flexibility. The API has changed to reflect that. The old QMainWindow class has been renamed Q3MainWindow and moved to Qt3Support. See the QMainWindow class documentation for details.

QMemArray<T>

QMemArray<T> has been moved to Qt3Support. It has been replaced by the QVector<T> class.

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

QNetworkProtocol

The QNetworkProtocol, QNetworkProtocolFactoryBase, QNetworkProtocolFactory<T>, and QNetworkOperation classes are no longer part of the public Qt API. They have been renamed Q3NetworkProtocol, Q3NetworkProtocolFactoryBase, Q3NetworkProtocolFactory<T>, and Q3NetworkOperation and have been moved to the Qt3Support library.

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

QObject

QObject::children() now returns a QObjectList instead of a pointer to a QObjectList. See also the comments on QObjectList below.

QObject::killTimers() has been removed because it was unsafe to use in subclass. (A subclass normally doesn't know whether the base class uses timers or not.)

QObjectList

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.

QPainter

The QPainter class has undergone some changes in Qt 4 because of the way rectangles are drawn. In Qt 4, the result of drawing a QRect with a pen width of 1 pixel is 1 pixel wider and 1 pixel taller than in Qt 3.

For compatibility, we provide a Q3Painter class in Qt3Support that provides the old semantics. See the Q3Painter documentation for details and for the reasons why we had to make this change.

The QPolygon::setPoints() and QPolygon::putPoints() functions return void in Qt 4. The corresponding Qt 3 functions returned a bool indicating whether the array was successfully resized or not. This can now be checked by checking QPolygon::size() after the call.

QPopupMenu

For most purposes, QPopupMenu has been replaced by QMenu in Qt 4. For compatibility with older applications, Q3PopupMenu provides the old API and features that are specific to popup menus.

QPtrDict<T>

QPtrDict<T> and QPtrDictIterator<T> have been renamed Q3PtrDict<T> and Q3PtrDictIterator<T> and have been moved to the Qt3Support 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 Q3PtrDict<T> to Qt 4, there are four classes that you can use:

QPtrList<T>

QPtrList<T>, QPtrListIterator<T>, and QPtrListStdIterator<T> have been moved to the Qt3Support 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::sort() relied on the virtual comparedItems() to sort items. In Qt 4, you can use qSort() instead and pass your "compare item" function as an argument.

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().

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.

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

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 QMutableListIterator<T *>) class instead. The following table summarizes the API differences:

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.

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.

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 Qt3Support. 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.

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

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.

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.

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[]().

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.

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 4, QRangeControl has been replaced with the new QAbstractSlider and QAbstractSpinBox classes, which inherit from QWidget and provides similar functionality. Apart from eliminating unnecessary multiple inheritance, the new design allows QAbstractSlider to provide signals, slots, and properties.

The old QRangeControl class has been renamed Q3RangeControl and moved to the Qt3Support library, together with the (undocumented) QSpinWidget class.

QScrollView

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 QAbstractScrollArea and QScrollArea classes are much more lightweight, and concentrate on handling scroll bars.

QSettings

The QSettings class has been rewritten to be more robust and to respect existing standards (e.g., the INI file format). The API has also been extensively revised. The old API is still provided when Qt 3 support is enabled.

Since the format and location of settings have changed between Qt 3 and Qt 4, the Qt 4 version of your application won't recognize settings written using Qt 3.

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.

QSimpleRichText

QSlider

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

If you use Q3SocketDevice for other uses, Qt 4 offers no alternative right now. However, there is a QSocketLayer internal class that offers a low-level socket API similar to Q3SocketDevice. Should the need for such functionality arise in Qt 4 applications, we will consider making this class public in a later release (e.g., Qt 4.1).

QSortedList

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

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

QSplitter

The function setResizeMode() has been moved into Qt3Support. 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.

QStoredDrag

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 Qt3Support 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 Qt3Support. If you used any of these, we recommend that you use QStringList or QList<QByteArray> instead.

QString

The QString::QString(QChar) constructor performed implicit conversion in Qt 3. Now, you will need a cast to convert a QChar to a QString.

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.

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().

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.

QStringList

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

QStyle

The QStyle API has been overhauled and improved. Most of the information on why this change was done is described in the QStyle overview.

Since QStyle is mostly used internally by Qt's widgets and styles and since it is not essential to the good functioning of an application, there is no compatibility path. This means that we have changed many enums and functions and the qt3to4 porting tool will not change much in your qstyle code. To ease the pain, we list some of the major changes here.

QStyleOption has taken on a more central role and is no longer an optional argument, please see the QStyleOption documentation for more information.

The QStyle::StyleFlags have been renamed QStyle::StateFlags and are now prefixed State_ instead of Style_, in addition the Style_ButtonDefault flag has moved to QStyleOptionButton.

The QStyle::PrimitiveElement enumeration has undergone extensive change. Some of the enums were moved to QStyle::ControlElement, some were removed and all were renamed. This renaming is not done by the qt3to4 porting tool, so you must do it yourself. The table below shows how things look now.

QTabBar

QTabDialog

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

See also the dialogs/tabdialog example, which shows how to implement tab dialogs in Qt 4.

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.

QTextStream

QTextStream has undergone a number of API and implementation enhancements, and some of the changes affect QTextStream's behavior:

QTextStream now uses buffered writing, which means that you need to call QTextStream::flush(), or use the streaming manipulators endl or flush if you need QTextStream to flush its write buffer. The stream is flushed automatically if QTextStream is deleted or when the device is closed.

QTextStream now uses buffered reading, so if you read a line from the stream, QTextStream will read as much as it can from the device to fill up its internal read buffer. This speeds up reading significantly, but Qt 3 code that mixed QTextStream access and direct device access may need to be updated.

While QTextStream in Qt 3 always translated end-of-line characters from Windows style ("\r\n") to Unix style ("\n") on Windows, QTextStream in Qt 4 only does this on devices opened with the QIODevice::Text mode (formerly IO_Translate).

QTimeEdit

See Virtual Functions for a list of QTimeEdit virtual member functions in Qt 3 that are no longer virtual in Qt 4.

QToolBar

The old QToolBar class, which worked with the old QMainWindow and QDockArea classes and inherited from QDockWindow, has been renamed Q3ToolBar and moved to Qt3Support. Use the new QToolBar class in new applications.

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 renamed Q3UrlOperator and moved to Qt3Support.

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 Qt3Support 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.

QValueVector<T>

The QValueVector<T> class has been replaced by QVector<T> in Qt 4. As a help when porting older Qt applications, the Qt3Support library contains a Q3ValueVector<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.

QWhatsThis

QWidget

Widget background painting has been greatly improved, supporting flicker-free updates and making it possible to have semitransparent widgets. This renders the following background handling functions obsolete:

QWizard

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