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.
Contents
Strategy
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:
- Fix Subset window item spacing -- they're too close vertically when the font is small. Clamp vertical spacing to a minimum size
- Figure out the Mac focus problem (gui menus disabled when viewer is active). This should be possible to fix.
- Find a good way to accept default appearance params (b/c on most linux platforms they will look better than our best guess)
- Color of lineout interactor on Mac does not match foreground color
- 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 way | New way |
// Do the center of rotation values.
if(which_widget == 14 || doAll)
{
temp = centerLineEdit->displayText().trimmed();
okay = !temp.isEmpty();
if(okay)
{
double center[3];
if(sscanf(temp.latin1(), "%lg %lg %lg",
¢er[0], ¢er[1], ¢er[2]) == 3)
{
view3d->SetCenterOfRotation(center);
}
else
okay = false;
}
if(!okay)
{
QString c; c.sprintf("%g %g %g",
view3d->GetCenterOfRotation()[0],
view3d->GetCenterOfRotation()[1],
view3d->GetCenterOfRotation()[2]);
msg = tr("The center of rotation values were invalid. "
"Resetting to the last good values of %1.").arg(c);
Error(msg);
view3d->SetCenterOfRotation(view3d->GetCenterOfRotation());
}
}
|
// Do the center of rotation values.
if(which_widget == View3DAttributes::ID_centerOfRotation || doAll)
{
double v[3];
if(LineEditGetDoubles(centerLineEdit, v, 3))
view3d->SetCenterOfRotation(v);
else
{
ResettingError(tr("center of rotation"),
DoublesToQString(view3d->GetCenterOfRotation(), 3));
view3d->SetCenterOfRotation(view3d->GetCenterOfRotation());
}
}
|