Porting to Qt 4

VisIt has used Qt 3.x for a number of years, missing out on a variety of new features, including better licensing agreements from Trolltech that have come out recently. It's time to port VisIt to Qt 4.


Running qt3to4 generates code that uses Qt3 classes, which exist in a compatibility layer on top of Qt 4. This project will create a direct Qt 4 port of VisIt that uses no Qt3 classes. This means that qt3to4 cannot be used. Instead, files that use Qt will be ported one at a time until the code builds. Then testing and recoding will commence.

Helping out

This project has been completed.

Configuring & Building Qt4

We are currently using Qt 4.4.3, to build obtain a tarball from Trolltech untar and run:

./configure --prefix=[install dir] -make libs -make tools -fast -no-separate-debug-info -no-qt3support -no-dbus -no-sql-mysql -no-sql-sqlite 
gmake -j 4
gmake install

For platform specific details see: Qt4 Build Notes

Project status

This table lists the actions that comprise this porting project as well as their status.

Action items More information Status
configure Make it recognize Qt 4 and set up Makefile variables. For the Mac, Qt is now built as a framework by default so let VisIt use it as a framework. Done
Makefile.in Change Makefile.in for many libraries and executables to use the new Makefile variables for Qt Done
vtkqt Port vtkqt library to Qt 4. Done
winutil Port winutil library to Qt 4. Done
viewer Port viewer to Qt 4. Done
gui Port gui to Qt 4. Done
plot plugins Port plot plugins to Qt 4. Done
operator plugins Port operator plugins to Qt 4. Done: See Qt4 Operator Porting Progress
visit-bin-dist Make visit-bin-dist use install_name_tool on the Mac to make the Qt frameworks @executable_path relative. There could be a visit-install component to this as well. Done
build_visit Change build_visit to download and use Qt 4. Done
XMLEdit Port XMLEdit to Qt 4. Done
xml2window Make xml2window generate Qt 4 code. Done
xml2makefile Make xml2makefile emit Makefiles consistent with configure/make changes for Qt 4. Done
xml2projectfile Port xml2projectfile, xml2vc7 Done
Build Qt 4 on hoth/sunspot Build & install. Update config-sites Qt is built on hoth.
Build Qt 4 on OCF Build & install. Update config-sites Done
Build Qt 4 on SCF Build & install. Update config-sites Done
Build Qt 4 on Windows Build & check in DLLs into windowsbuild tree Done (for MSVC 7)
Adjust Windows build for Qt 4 Adjust Windows projects for Qt 4, make sure that Qt DLLs get installed with NSIS, Install Qt libs/includes for plugin development Done
Test build with Qt 4.5 Tech Preview See if changes are compatible with latest version of Qt4, Qt-4.5-tp1 Success on Rhel 4

Remaining tasks

There are still some bugs that need to be fixed. Here is a list of items that we can cross of as we complete them:

  1. Fix Subset window item spacing -- they're too close vertically when the font is small. Clamp vertical spacing to a minimum size
  2. Figure out the Mac focus problem (gui menus disabled when viewer is active). This should be possible to fix.
  3. Find a good way to accept default appearance params (b/c on most linux platforms they will look better than our best guess)
  4. Color of lineout interactor on Mac does not match foreground color
  5. Try and make the viswin toolbars take up more than 1 line by default

Items that have been ported but need verification later

  • vtkQt/vtkQtImagePrinter.C
  • winutil/QvisVariableMenu, etc.
  • The engine has a dependency on libvtkqt due to libviswindow_ser on the Mac. Remove the dependency!

Some important changes from Qt3 to Qt4

  • Different libraries for Qt -- smaller modules
  • Header file name changes
  • QApplication::setMainWidget() is no longer used
  • No names passed to object constructors.
  • QString::latin1() -> QString::toLatin1(). Better yet, try QString::toStdString() or try not to convert from QString.
  • QString::ascii() -> QString::toAscii().constData()
  • QString::simplifyWhitespace() -> QString::simplified()
  • QString::stripWhitespace() -> QString::trimmed()
  • QColorGroup -> QPalette
  • QWidget::colorGroup() -> QWidget::palette()
  • Qt4 Equivalent of setCaption() method is setWindowTitle()
  • QMouseEvent::state() -> QMouseEvent::modifiers(), the buttons changed too to Qt::KeyboardModifiers.
    • ShiftButton -> Qt::ShiftModifier
    • ControlButton -> Qt::ControlModifier
    • AltButton -> Qt::AltModifier
  • Menus
    • Use QMenu to replace QPopupMenu
    • No mechanism for querying number of items in a menu. It's all action-based now.
    • For shortcut key sequences wrap with QKeySequence and use the Qt namespace, example: QKeySequence(Qt::CTRL + Qt::Key_N)
    • No insertItem, use addAction
  • QTooltip::add(w, text); -> w->setToolTip(text);
  • Layout constructors no longer accept a layout instance as a parent object. If you want a layout instance as a parent, create your instance with no parent, and use the parent's addLayout() method.
  • QHBox widget now longer exists, replace with q QHBoxLayout (note this is a QLayout child, and QHBox was previously a QWidget child)
  • QListBox was replaced by a more functional QListWidget (based on a MVC design)
    • Instead of having simple text items, items are now instances of type QListWidgetItem
    • Use currentRowChanged(int) to replace the selectionChanged() signal
    • insertItem() now provides an index based insert, use QListWidget::addItem() to add an item to the end of the list.
    • currentItem() provides a pointer to the current QListWidgetItem instance, use currentRow() to get the current item index.
    • Use item(index)->setText(name) to replace Qt3 changeItem(name,index)
  • QGridLayout
    • Constructor no longer takes grid dimensions, they are determined by what is added to the layout.
    • addMultiCellWidget(QWidget *w, int fromRow, int toRow, int fromCol, int toCol) was replaced with: addWidget(QWidget *w,int row, int col,int rowSpan, int colSpan)
    • Use setColumnMinimumWidth to replace Qt3 setColStretch (?)
    • Use setRowMinimumHeight() to replace Qt4 addRowSpacing (?)
  • QButtonGroup
    • QButtonGroup is no longer a widget, so if you need to enable/disable a group of buttons you will need a parent widget
    • QButtonGroup is however a QObject, so it can be assigned a parent to handle memory cleanup
    • Use buttonClicked(int) to replace the clicked(int) signal.
    • Use addButton() to replace Qt3 insert() - make sure you specify an index.
    • QButtonGroups are exclusive by default so if you check on button, the others will change to unchecked.
    • To "check" a button use group->button(id)->setChecked(true)
  • QComboBox
    • insertItem() now provides an index based insert, use QComboBox::addItem() to add an item to the end of the list.
    • Use setCurrentIndex() to replace Qt3 setCurrentItem()calls
  • QLabel
    • The constructor can no longer take the buddy as the first argument. use the setBuddy(QWidget*) method.
  • QMultiLineEdit no longer exists, use QTextEdit.
    • Use toPlainText to replace Qt3 QMultiLineEdit::text()
    • Use setWordWrapMode(QTextOption::NoWrap) to replace Qt3 QMultiLineEdit::setWordWrap(QTextEdit::NoWrap);
  • QFileDialog::getOpenFileName() signature has changed (TODO)
  • QFileDialog::getSaveFileName() signature has changed (TODO)
  • Use QTabWidget::currentChanged(int) to replace Qt3 QTabWidget::currentChanged(QWidget*) signal
  • QXmlInputSource constructor new takes an a pointer to a QFile instance, not a reference
  • QProcess has changed quite a bit
    • You now pass arguments using a QStringList
    • It now inherits from QIODevice with two read channels, one for standard out and one for standard error
    • readyReadStandardOutput and readyReadStandardError signals tell you when standard out/err have data ready
    • To read from a specific channel call setReadChannel() and use the read(), readAll() or readline() functions
  • QString
    • find no longer exists. Use indexOf instead.
  • QScrollView
    • Use "setWidgetResizable(true)" if you want the internal widget to automatically adjust to the scroll area size.

Other style changes

Reading lists of floats or doubles used to make use of sscanf and a bunch of other redundant coding. To streamline the process of getting data from QLineEdit widgets in a window's GetCurrentValues method, adapt windows to use the new style of coding. The resulting code is more concise, consistent between modules, and offers possible internationalization benefits with respect to input handling since it uses QString exclusively in the helper methods that are now used.

Old wayNew way
// Do the center of rotation values.
if(which_widget == 14 || doAll)
    temp = centerLineEdit->displayText().trimmed();
    okay = !temp.isEmpty();
        double center[3];
        if(sscanf(temp.latin1(), "%lg %lg %lg",
                  &center[0], &center[1], &center[2]) == 3)
            okay = false;
        QString c; c.sprintf("%g %g %g",
        msg = tr("The center of rotation values were invalid. "
                 "Resetting to the last good values of %1.").arg(c);
// Do the center of rotation values.
if(which_widget == View3DAttributes::ID_centerOfRotation || doAll)
    double v[3];
    if(LineEditGetDoubles(centerLineEdit, v, 3))
        ResettingError(tr("center of rotation"),
                       DoublesToQString(view3d->GetCenterOfRotation(), 3));