Porting QT3 Applications to QT4

QT4 changed a number of things substantially from QT3. The IDE has been removed. It seems that kdevelop integrates QT4 OK but Eclipse integration does not yet seem perfect. The best thing is that QT4 is available as open-source for a number of different platforms, including Windows and Linux. Documentation is extensive, including lots of background explanation of the frameworks used. There were a few problems with it that hopefully will be ironed out over time.

1. Under Fedora 5 qmake is run as qmake-qt4 to distinguish it from that of a QT3 installation.

2. Tools are provided for conversion of a QT3 application to QT4. I did use those, and it may have changed a few things positively. There were so many additional changes to be made that in the end I removed all QT3Support widgets and replaced them with QT4 equivalences. Some widgets converted to QT4 badly and had to be removed and replaced (there was no apparent consistency, other widgets of the same type converted OK). There were so many problems with the resulting code that it may have been better to avoid using the utilities. Nevertheless it was a valuable learning experience.

3. Instead of subclassing a generated base class for each window or dialog, a header file is generated that creates a class for all the widgets in the window or dialog. You then add an instance of that class to your window or dialog class, and run a setup function. This creates the window and all its widgets. The widgets then have to be accessed as members of that instance. This was quite easy to change over.

4. A great number of member functions and properties of the QT4 classes changed their names from the equivalent QT3 classes and/or their implementation, and had to be meticulously checked and replaced. The conversion routines did not do a good job of detecting the necessary changes (after all there are thousand of member functions for hundreds of classes).

5. I rebuilt the entire main window adding menus, toolbar and table. The table classes have changed significantly and there is a steep learning curve associated with trying to adapt to the new model/view approach. These changes are a step in the right direction it is now both elegant and flexible compared to the old approach.

6. I added icons and the help file to the resource tree. This allows them to be included into the binary and it is much easier to keep reference them in the code. As in QT3, the menu creates actions which can be associated with an icon and name in the action editor, and dragged across to the toolbar.

7. I chose a QTableWidget for the table. There were two problems encountered here. One is that I only wanted checkboxes in some of the cells. The documentation on this point is very confusing. Basically you add a string QTableWidgetItem to each cell, and you can make it explicitly checkable. That adds a checkbox with the string in the cell. You also need to explicitly set the checkbox to a default state or it doesn't appear. To give a checkbox only, simply use a null string. The second issue with the documentation is that a QTableWidgetItem has an integer parameter called "type". This is not at all explained in the documentation, and changing its value seemed to have no apparent effect.

8. For labels on the columns, under QT3 I read and changed them individually. For QT4 I decided to use a separate QStringList of labels that I modified and reloaded to the table with setHorizontalHeaderLabels() each time the columns were changed.

9. The concept of a column or row being selected has disappeared from QT4. It appears that only items can be tested for being selected. While there is a way to reproduce what I was doing in QT3 to identify columns or rows selected for deletion, I ended up providing two buttons that simply deleted the selected currentColumn or currentRow respectively. This is probably less confusing for the user, and anyway I'm too lazy to find another solution.

10. A ButtonGroup class exists but is not provided as part of the QT4 GUI builder. However the GroupBox can be used to group radio buttons as by default they take on an exclusive role when grouped under the same parent. For that matter they do not even need a containing box.

11. To show help, the implementation of QTextBrowser has substantially changed, however it is the appropriate class to use. This must be displayed using show().

12. Another funny quirk, maybe a bug, with QT4 is that it could write string constants to QOutputStream, but could not read them back as QStrings as the documentation seemed to imply (and as QT3 happily did). Maybe they are considered a different class (they are stored as byte characters while QStrings seem to be Unicode). I solved this by creating a QString from the string constants and writing that instead.

13. QProgressDialog will not display properly unless you add qApp->processEvents(). The documentation for both QT3 and QT4 is ambiguous. Both claim that the setProgress() function did the qApp call, and indeed QT3 worked happily with just this. Without the qApp->processEvents(), QT4 did show a progress bar, but lacking the caption text and cancel button, and only updated every 10 seconds.

14. QString no longer supports the << operator for output using std::cout. qDebug() is probably the best choice for debug output anyway, and is a bit easier to use.

K. Sarkies 16 October 2006

Warning: this author uses another popular PC operating system sparingly and usually on an emergency basis, and for playing games of course. All software is developed on and for Linux, which is the only OS worth spending time and effort on, apart from the Commodore 64 that is.

Contact: My email address can be constructed from the username "ksarkies" and the ISP DNS address internode.on.net in the usual way.

First created
12 October 2006
Last Modified 12 October 2006
© Ken Sarkies 2006