Author: Phil Weinstein, CADSWES
Edit: 7-7-2010 / Status: Ready for Review (1) / Word
Document Copy
Revision: 7-8-2010 (b): minor edits, and added images to sections 2.2
and 2.3.
Revision: 7-8-2010 (c): QtRpl/RplListView (a Q3ListView)
has already been replaced.
The last few RiverWare releases (5.0, 5.1 and 5.2) have been built with Qt version 4 (4.3 or 4.4) with use of the "Qt3 Compatibility Library". Graphical user interface (GUI) modules in RiverWare are now implemented using a mix of Qt4 widgets and Qt3 widgets (adapted for use with Qt4). To complete the Qt4 port, we need to recode all uses of Qt3 widgets to use instead Qt4 widgets. Benefits of completing the Qt4 port include improved user interface capabilities, performance, and ease of maintenance. Also, it will be important for all Qt3 to be removed from RiverWare before we can move to Qt 5 further down the road. (Qt is currently at version 4.6.3, with 4.7 in "beta" release).
The major high-level tasks in the Qt4 port completion are:
See also the analysis done in January 2010: http://cadswes2.colorado.edu/~philw/2010/Qt4Port/PortAssessment5p2.html
This table summarizes the progress of the Qt3 to Qt4 port with respect to the high-level tasks identified in January 2010. See additional information in subsequent numbered sections.
TASK |
January 2010 (Remaining) |
July 2010 (Remaining) |
|||||||||
(1) | Converting "Qt Designer" built UI files from Qt3 to Qt4 | 91 UI Files | 15 UI Files (all DMI). | ||||||||
(2) | Replacing all uses of Qt3 classes (widgets, etc) with Qt4 classes | ||||||||||
(2.1) | Porting Q3MainWindows to Qt4 QMainWindows (not an enumerated development step in the Jan doc). |
46 | 10 (all DMI). | ||||||||
(2.2) | Recoding all uses of Qt3 List and Table widgets |
|
|
||||||||
(2.3) | Porting the Accounting View from Q3Canvas
to [Qt4] QGrahpicsView and QGraphicsScene. |
TO DO | TO DO | ||||||||
(2.4) | Porting RplFrame (a Q3ScrollView with
custom painting) |
TO DO | TO DO | ||||||||
(2.5) | Recoding all uses of other Qt3 Compatibility Library classes. | TO DO | About half done, in the course of other porting work. |
||||||||
(3) | Removing all uses of Qt3-compatibility methods in Qt4 classes. | TO DO | TO DO |
Background
Qt Designer is a GUI building program supporting the definition and lay out of widgets for Qt dialogs and other GUI components. Designer maintains widget layout definitions in "UI" (.ui) files. Qt3 and Qt4 UI files have incompatible formats, and Qt4 Designer cannot directly read Qt3 Designer UI files. However, Qt4 provides a "uic3" (UI compiler) tool which has these two capabilities:
- "uic3" can be used as part of the automated "make" process to generate C++ code from Qt3 UI files (using the Qt3 Compatibility Library). This is currently done in the RiverWare "make".
- "uic3" can be used to convert Qt3 UI files to Qt4 UI files.
The process of using uic3 to convert Qt3 UI files to Qt4 UI files requires quiet a bit of hand-recoding. The major change is that the generated C++ class is no longer a base class for the client dialog. Instead, it is a POD ("plain old data") class which builds widgets inside of the client dialog, and is integrated with the client dialog by delegation (or "aggregation" -- either via a C++ pointer or reference data member). Qt4 Designer doesn't support custom Qt slots. Those Qt slots -- and the signal connections made to them -- need to be written in our C++ code. And icons defined in Qt3 UI files need to be handled differently.
See also this Trolltech webpage: Porting .ui Files to Qt 4 [http://doc.trolltech.com/4.4/porting4-designer.html]
Current Status
This conversion has been applied to all Qt3 UI files except for the DMI-related UI files listed below. These were not addressed because it is possible that many of these UI files will be completely replaced with new ones.
- DbDmi/DatasetMgrDlgBase.ui
- DbDmi/DbDmiDlgBase.ui
- DbDmi/DbDmiEditDlgBase.ui
- DbDmi/DbDmiImpExpDlgBase.ui
- DbDmi/DssDatasetDlgBase.ui
- DbDmi/HdbDatasetDlgBase.ui
- DbDmi/HdbMetaDataDlgBase.ui
- DbDmi/HdbModelRunIdDlgBase.ui
- DbDmi/HdbModelRunIdEditDlgBase.ui
- DbDmi/LoginDlgBase.ui
- DbDmi/NameMapDlgBase.ui
- DbDmi/NameMapMgrDlgBase.ui
- QtDmi/DmiParamDlgBase.ui
- QtDmi/ListCellDlgBase.ui
- QtDmi/MinMaxCellDlgBase.ui
The Qt3 UI file porting status has been documented on this webpage: http://cadswes2.colorado.edu/~philw/2010/Qt4Port/Qt3UiFiles.html (Completed UI files are indicated with an orange background). A handful of UI files had been found to be no longer used in the RiverWare build.
Implementation Notes
All uses of the Qt3 Compatibility Library in Qt 4 need to be removed. This applies to both converted UI files and to our own C++ code. In UI files, this can be done mostly in Qt4 Designer -- though it is sometimes convenient to (carefully) directly edit the UI files (which are XML). Conveniently, the names of all Qt3 classes (in the Qt3 Compatibility Library) start with "Q3", e.g. Q3PopupMenu or Q3ListView.
This work is discussed in the following sections:
(2.1) Porting Q3MainWindows to Qt4 QMainWindows
(2.2) Recoding all uses of Qt3 List and Table widgets
(2.3) Porting the Accounting View from Q3Canvas to QGrahpicsView.
(2.4) Porting RplFrame (a Q3ScrollView with custom painting)
(2.5) Recoding all uses of other Qt3 Compatibility Library classes.
Qt Dialogs are generally implemented with a subclass of either QDialog or QMainWindow. QMainWindows can have menubars, toolbars, statusbars, and child "dock" windows. Only QMainWindows have distinct Qt3-compatibility implementation (Q3MainWindow). In doing this conversion, generally only Q3MainWindows having toolbars and child "dock" windows need special treatment. Generally, the replacement of Q3MainWindow to QMainWindow can be, and was done mechanically, with one exception:
In all cases of Qt4 QMainWindows, a handle to the menubar needed to be obtained directly from the QMainWindow, rather than by explicitly creating a new QMenuBar for the QMainWindow, as was done in Qt3:
OLD: _menuBar = new QMenuBar (this, "_menuBar");
NEW: _menuBar = menuBar(); // QMainWindow
As was mentioned above, much of the replacement of Q3MainWindow to QMainWindow was done mechanically, and checked with compilation and execution testing. This was done with several other Qt3-compatibility widget classes. See notes on these webpages:
Additional (19) Q3MainWindows which had been defined in Qt3 UI files were converted to QMainWindows after their UI files had been converted to Qt4. See notes on this webpage:
Current Status
This conversion has been applied to all Qt3MainWindows except for those in the following DMI-related UI files. These were not addressed because it is possible that many of these UI files will be completely replaced with new ones.
List and table widgets are the most numerous complex GUI components in RiverWare. Each dialog's Lists (including TreeViews) and Tables often have interactions with many other GUI and non-GUI software components. This, and the profound change in Qt4's List and Table widgets -- with the introduction of the new "model/view framework" -- has proved to make conversion of RiverWare's lists and tables quite time consuming.
Except in two very special cases, all of RiverWare's Qt3 lists and tables were "item-based" implementations. This means that a C++ object was associated with each row in a list, or each cell in a table. Qt4 also provides "item-based" lists and tables, but they are intended for only simple uses and have limitations, such as: (1) no custom drawing in cells and (2) difficulty in allowing editing in only certain columns. (The latter is possible, but requires a complex implementation). Qt4 "prefers" an item-less implementation for lists and tables. In the context of converting lists and tables which had been devised using an "item-based" architecture, this is unfortunate. In our Qt3 implementations, the "item objects" had interacted not only with the containing GUI component (list or table), but also directly with the data objects which those items represented (e.g. RiverWare Slots, SimObjs, Accounts, Output Devices, etc.).
The following approaches have been used (or considered) to port individual Q3ListViews to Qt4 widgets:
|
See the discussion on porting the several Q3Tables in the corresponding subsection, below.
DbDmi/DbDmiMgr.hpp: Q3ListView* _listview; Q3GUI/AcctOrderListView.hpp: class AcctOrderListView : public Q3ListView Q3GUI/DiagCfgDlg.Panel.hpp: Q3ListView* _catListView; Q3GUI/DiagOutputListView.hpp: class DiagOutputListView : public Q3ListView Q3GUI/DisplayGroupListView.hpp: class DisplayGroupListView : public Q3ListView Q3GUI/DragDropSimListView.hpp: class DragDropSimListView : public Q3ListView Q3GUI/GusListView.hpp: class GusListView : public Q3ListView Q3GUI/OpenObjectDlg.hpp: Q3ListView* _methodsListView; Q3GUI/OpenObjectDlg.hpp: Q3ListView* _accountsListView; Q3GUI/OpenObjectDlg.hpp: Q3ListView* _olamListView; Q3GUI/RestoreListState.hpp: Q3ListView* _listView; Q3GUI/ScenarioMgrDlg.hpp: Q3ListView* _slotList; Q3GUI/SlotQListView.hpp: class SlotQListView : public Q3ListView Q3GUI/SubbasinMgrListView.hpp: class SubbasinMgrListView : public Q3ListView Q3GUI/TimeStepSelListView.hpp: class TimeStepSelListView : public Q3ListView Q3GUI/WorkspaceListView.hpp: class WorkspaceListView : public Q3ListView QtRpl/RplBlockSelectorDlg.hpp: Q3ListView* _setListView; QtRun/DispatchInfoListView.hpp: class DispatchInfoListView : public Q3ListView QtRun/DmiListView.hpp: class DmiListView : public Q3ListView QtRun/QtMultiRunEditDlg.hpp: class QtMultiRunEditDlg::IterListView : public Q3ListView QtRun/RulesEffectsListView.hpp: class RulesEffectsListView : public Q3ListView QtUtils/GenListView.hpp: class GenListView : public Q3ListView |
Q3GUI/FileInfoWidgets.ui: ... Q3ListView ... _saveList Q3GUI/LinkEditorWidgets.ui: ... Q3ListView ... _srcListView Q3GUI/LinkEditorWidgets.ui: ... Q3ListView ... _destListView Q3GUI/MarkerMgrWidgets.ui: ... Q3ListView ... _listView Q3GUI/OpenObjectWidgets.ui: ... Q3ListView ... _methodsListView Q3GUI/OpenObjectWidgets.ui: ... Q3ListView ... _accountsListView Q3GUI/OutputConfigWidgets.ui: ... Q3ListView ... _listSlots Q3GUI/PlotMembershipWidgets.ui: ... Q3ListView ... _listView Q3GUI/PropagateWidgets.ui: ... Q3ListView ... _listview Q3GUI/SlotListWidgets.ui: ... Q3ListView ... _slotListView QtDmi/DmiEditorWidgets.ui: ... Q3ListView ... _listview QtDmi/DmiHandlerWidgets.ui: ... Q3ListView ... _msgListView QtDmi/DmiMgrWidgets.ui: ... Q3ListView ... _listview QtDmi/DmiParamWidgets.ui: ... Q3ListView ... _listview QtDmi/ListCellWidgets.ui: ... Q3ListView ... _listview QtRpl/RplAnalysisWidgets.ui: ... Q3ListView ... _groupsListView QtRpl/RplAnalysisWidgets.ui: ... Q3ListView ... _descListView QtRpl/RplAnalysisWidgets.ui: ... Q3ListView ... _ascListView QtRpl/RplImportWidgets.ui: ... Q3ListView ... _importListView QtRpl/RplLayoutWidgets.ui: ... Q3ListView ... _breaksListView QtRpl/RplPaletteWidgets.ui: ... Q3ListView ... _userDefinedListView QtRpl/RplPaletteWidgets.ui: ... Q3ListView ... _predefinedListView QtRpl/RplSearchReplaceWidgets.ui: ... Q3ListView ... _searchResultsListView QtRun/MultiRunControlWidgets.ui: ... Q3ListView ... _configListView QtRun/OptParamSubWidgets.ui: ... Q3ListView ... _paramListView |
There are far fewer Q3Tables in RiverWare than Q3ListViews (see prior section). The Q3Tables for the Open Slot Dialogs (for Series and Table Slots) and for the SCT have a common base class (SlotDataQTable), and are quite complicated. These should be ported to the model-based QTableView (not QTableWidget) with a QAbstractTableModel subclass (to support an item-less implementation) and QItemDelegate (to support custom cell drawing). See our implementation for the Qt4 Run Analysis Dialog "grid" table classes: RunAnalGridQTableView, RunAnalGridQItemDelegate, and RunAnalGridQTableModel.
|
|
This has been done for the Simulation View (from which the new Geospatial View has been adapted). With that example, and being that Qt3's QCanvasItems are analogous to Qt4's QGraphicsItems, converting the Accounting View to Qt4 is conceptually a fairly straight port. Also, some design documentation is available for that effort. Two intermediate QGraphicsScene base classes used for the Simulation View would be directly used also for the Accounting View, so many interactive and display features are already in place. (See class diagram below -- Accounting View classes are in Red).
See documents:
|
This applies to our own C++ code as well as the widgets originally in Qt3 UI files not ported automatically by the uic3 tool, notably Q3ButtonGroup, Q3GroupBox, Q3MainWindow and Q3WidgetStack. With the observation that the tools used to port to Qt4 with the Qt3 Compatibility Library (in the preparation of RiverWare 5.0) were overly conservative, some of the unconverted Qt3-compatibility widgets were replaced using an automated process -- for example, generally all Q3PopupMenus were successfully changed to (Qt4) QMenu without further modification. See notes on these webpages:
An updated approximate count of "Q3" widgets in RiverWare code has not been done since January. At that time, we approximated 585 (as C++ class data members, about half from Qt3 UI files). I suspect that we've removed at least half of those.
Progress on the subsequent step will be made easier when all Qt3 compatibility classes (whose names start with "Q3") have been removed from all C++ header files. But the goal, of course, is to remove references to those classes in all RiverWare code.
Many of the Qt4 classes include also "Qt3 support members" (generally, C++ methods). (See, for example, the Qt4 QMenu class). Many of these are overridden methods, e.g. constructors with many initialization parameters -- those have generally been removed from Qt4. Once the prior step of removing all Qt3 classes form RiverWare header files has been completed, it will be useful to enable or disable availability of the Qt3 Compatibility Library for individual source files -- instead of having that library enabled for the entire build. [This is controlled with the QT3_SUPPORT symbol].
--- (end) ---