Moving from Qt 3 to Qt 4This document describes which parts of Qt should be used when writing an application with Qt 3, so that it can be upgraded to use Qt 4 later with a minimum of effort. However, the advice may also be useful to developers who are porting existing applications from Qt 3 to Qt 4. For a detailed overview of the porting process for existing Qt 3 applications, see the Porting to Qt 4 document. Since Qt 4 provides important new functionality at the cost of some compatibility with Qt 3, it is useful for developers of Qt 3-based applications to learn how to take advantage of Qt 3's API now while preparing for future changes that will be needed when upgrading to Qt 4. Certain advanced Qt 3 features were moved to the Qt 3 support library (Qt3Support) in Qt 4.0, and have been gradually replaced in subsequent releases of Qt 4. Making Qt 3 applications as portable to Qt 4 as possible enables a smooth transition between versions of Qt in the long term, and allows for a stable development process throughout. Qt 3 Features to AvoidAlthough we are proud of the level of stability we have achieved with Qt, it is important to realise that, for Qt 4 to be a substantial improvement over Qt 3, certain features have been revised to make the framework more maintainable for us and more usable for developers. It is therefore useful to know which features of Qt 3 should be avoided to help save time during a later porting effort to Qt 4. Note that it is still possible to use many of the following classes and features through the use of the Qt3Support module. Painting Outside Paint EventsIn Qt 3, under certain circumstances, it was possible to use QPainter to draw on a given custom widget outside its paintEvent() reimplementation. In Qt 4, in most situations, painting must occur within a widget's paint event handler. On X11, it is possible to set the Qt::WA_PaintOutsidePaintEvent attribute on widgets to keep existing code, but we recommend restricting the use of painting code to within paint event handlers where possible. More information about this change can be found in the Painting and Redrawing Widgets section of the Porting to Qt 4 document. Qt DesignerThe version of Qt Designer supplied with Qt 3 provided extensive code editing and project management features (control over .ui.h and .pro files), and encouraged users to design main window applications from within the Qt Designer environment. The version of Qt Designer supplied with Qt 4 is intended to be integrated with other software development tools (such as integrated development environments), and does not support these project-level features. We recommend using one of the form subclassing approaches with forms created using Qt Designer. This avoids the need to use .ui.h files and special purpose code editors. Existing Qt 3 forms created using Qt Designer can be gradually ported to Qt 4 by following the advice in the Porting UI Files to Qt 4 guide. However, some extra effort will be required to move application logic from .ui.h files into the main body of a Qt 4 application. Menu Items (QMenuItem)The old-style construction of menus by creating individual menu items has been superseded in Qt 4 by the use of generic actions which can be used in menus, toolbars, and as keyboard shortcuts. Qt 3 also supports this action-based approach, so, by using QAction throughout your application, less work will be required to adapt your application to Qt 4. Pointer-Based Classes (QPtr*)Qt 3 provides a group of pointer-based classes (QPtrList, QPtrDict, QPtrVector, etc.) that help manage collections of pointers to objects (usually QObject subclasses) in an application. In addition, the value-based collection classes (QValueList, QValueDict, QValueVector, etc.) provide a way to store standard value types which cannot be easily stored in pointer-based collections. Qt 4 introduces a single set of collection classes which does not require developers to pay as much attention to memory allocation and object ownership issues. As a result, Qt 3's pointer-based classes have no direct equivalent classes in Qt 4. To ease migration, use Qt 3's value-based classes to store most objects, including pointers; for example, use QValueVector<QWidget *> rather than QPtrVector<QWidget *>. These can be replaced by Qt 4's QVector, QLinkedList, and QList later. Other Collection Classes (QStrList, Q*Dict)Some collection classes in Qt 3 have been deprecated in favor of easier to use, higher level alternatives. These include the dictionary classes (QAsciiDict, QDict, QIntDict, QPtrDict) and QStrList. QStrList can usually replaced by the higher level QStringList class in Qt 3; this is also available in Qt 4. It is recommended that you use the QMap class instead of the QDict classes. In Qt 4, QMap is also complemented by the QHash class. Memory Arrays (QMemArray)In Qt 3, the QMemArray class is used as a simple array container for simple data types. This class is deprecated in Qt 4 in favor of the QVector and QVarLengthVector classes which provide more powerful and consistent array objects. Qt 3's closest equivalent class to Qt 4's QVector is the QValueVector class. For many purposes, this can be used instead of QMemArray. URL Operations (QUrlOperator)The URL operator in Qt 3 provides an abstract way to handle files via HTTP, FTP, and on the local file system. However, Qt 4 only provides this functionality through the use of the Q3UrlOperator. From Qt 4.4, the Network Access API provides a subset of the features provided by QUrlOperator that are mostly intended for use with applications that use the HTTP and FTP protocols. See the QNetworkRequest, QNetworkReply, and QNetworkAccessManager documentation for further details. It is also possible to perform operations on remote files through the QNetworkAccessManager and QFtp classes, and on local files with the QFile class. SQL Cursors (QSqlCursor)In Qt 3, one of the preferred methods of working with SQL is to use a cursor to manipulate the contents of a database. In Qt 4, the preferred method of working with SQL is to use the model/view architecture (QSqlQueryModel and QSqlTableModel) and, as a result, the cursor interface is only supplied in the Q3SqlCursor class. The easiest way to ensure continuity between Qt 3 and Qt 4 is to use QSqlQuery rather than QSqlCursor, and migrate to QSqlQueryModel later. Domain Name Service (QDns)The QDns class in Qt 4 provides a much simpler interface than the QDns class in Qt 3, and is mainly used for host name resolution. As a result, many of the more complex features of Qt 3's QDns class are only available through Qt 4's Q3Dns compatibility class. To resolve host names with Qt 3, it is recommended that you use the higher level interface of QSocket rather than QDns. The equivalent functionality is available in Qt 4 in the QAbstractSocket and QHostInfo classes. Wizard Dialogs (QWizard)Qt 3 provides support for "wizard" dialogs in the form of the QWizard class. Prior to Qt 4.3, this class was made available as Q3Wizard, and provides the same interface for creating relatively complex wizards. In Qt 4.3 and later, a revised QWizard class can be used to create this kind of dialog, but existing Qt 3 wizard implementations may need to be redesigned to work with the new QWizard API. Abstract Grid Views (QGridView)Before the introduction of the Qt 3 QTable class, QGridView was the recommended way to create tables of custom items. With the introduction of QTable, the QGridView class was effectively obsoleted, and the QTable class should now be used to display tabular information in your Qt 3 application. This approach allows you to use QTableWidget as a replacement when later porting your application to Qt 4. Specialized Scrolling ViewsIn Qt 3, the QScrollView class provides a viewport that can be used to display part of a larger widget, and will optionally provide scroll bars for navigation purposes. In Qt 4, this functionality is superseded by classes such as QScrollArea, which provides a more intuitive interface for developers to use. QScrollView is available in Qt 4 as the Q3ScrollView class. In Qt 3, it is recommended that QScrollView should be used with child widgets rather than subclassed. However, it should be noted that this approach may not be appropriate if you need to use extremely large scrolling areas in your application, since Qt 3 widgets cannot be wider or taller than 32767 pixels. Significantly Changed FeaturesSome Qt 3 features have changed significantly for Qt 4. and the recommended way of using them has therefore changed significantly, too. This is most notably true for the drag and drop API. Additionally, some of the more specialized features in Qt 3 are often used to help customize widgets and add extra polish to an application. Although these improvements make applications more presentable to users, many of them are unnecessary with Qt 4, and may create additional porting work. Drag and DropQt 4 introduces a simpler and more intuitive implementation of drag and drop between widgets, and with other applications. As a result, there is no simple approach that can be used to make drag and drop in a Qt 3 application easier to port to Qt 4. Extensive Customization of Item ViewsEach of the classes that are used to display list, tree, and table items in Qt 3 can be subclassed for the purposes of customizing their appearance. The item view framework in Qt 4 is implemented according to a different paradigm (model/view) which does not allow items to be customized using this method. Although Qt 4 provides compatibility classes (Q3ListBoxItem, Q3ListViewItem, and Q3TableItem) that can be used in the same way as their Qt 3 counterparts, these cannot be used within the standard model/view framework. It is recommended that, to minimize porting effort, extensive customization of item classes should be avoided in Qt 3, if at all possible. Double BufferingQt 3 applications often use double buffering for reducing flicker when painting custom widgets. This approach is unnecessary with Qt 4 because double buffering is automatically performed by the paint engine. It still makes sense to use double buffering in Qt 4 in certain contexts. For example, in Chapter 5 of GUI Programming with Qt 3, double buffering was presented as a speed optimization and not just as a means of reducing flicker. Data-Aware FormsThe QDataTable, QDataBrowser, and QDataView classes in Qt 3 allow integration between widgets and SQL-based databases. In Qt 4.1 and earlier, the preferred way to create a data-aware widget is to connect an generic item view (such as a table view) to a SQL model. In Qt 4.2 and later, the QDataWidgetMapper class can be used to map data to widgets in a form-based user interface. New applications written with Qt 3 should use QSqlQuery in preference to an approach based on the old-style data-aware widgets. This offers a choice of porting strategies when later migrating the application to Qt 4: You can either continue to use QSqlQuery or take the opportunity to use the model/view classes to handle database integration. Dock Windows and AreasIn Qt 4, the way that dock windows are constructed and used in main window applications differs significantly to the pattern of use provided by Qt 3. As a result, the introduction of a simpler and cleaner API means that Qt 3 applications that make extensive use of dock window areas will require careful examination when they are ported to Qt 4. We recommend that the QMainWindow class be used in preference to the Q3MainWindow compatibility class when an existing Qt 3 main window application is ported to Qt 4. Therefore, we recommend that specialized use of dock window areas should be avoided when writing a Qt 3 application with Qt 4 in mind. Custom StylesThe style system used to provide consistent themes for Qt's standard widgets has been revised for Qt 4. As a result, custom styles for Qt 3 require some porting work to be done before they can be used with Qt 4. To ease the porting process, we recommend that you avoid implementing custom widget styles for Qt 3 applications unless it is absolutely necessary for your users. In Qt 4.2 and later, Qt Style Sheets can be used to implement many common modifications to existing styles, and this may be sufficient for Qt 3 applications. EventsIn Qt 3, QCloseEvents were not accepted by default. In Qt 4, the event handler QWidget::closeEvent() receives QCloseEvents, and accepts them by default closing the application. To avoid this, please reimplement QWidget::closeEvent(). |