This document describes the process of porting applications from Qt 3 to Qt 4. If you haven't yet made the decision about porting, or are unsure about whether it is worth it, take a look at the key features offered by Qt 4. See also Moving from Qt 3 to Qt 4 for tips on how to write Qt 3 code that is easy to port to Qt 4.
Other porting guides:
The Qt 4 series is not binary compatible with the 3 series. This means programs compiled for Qt 3 must be recompiled to work with Qt 4. Qt 4 is also not completely source compatible with 3, however nearly all points of incompatibility cause compiler errors or run-time messages (rather than mysterious results). Qt 4 includes many additional features and discards obsolete functionality. Porting from Qt 3 to Qt 4 requires some effort, but once completed the considerable additional power and flexibility of Qt 4 is available for use in your applications.
To port code from Qt 3 to Qt 4:
QT += qt3support
to your
.pro
file if you use
qmake
; otherwise, edit your makefile or project file to link against the
Qt3Support
library and add
-DQT3_SUPPORT
to your compiler flags. (You might also need to specify other libraries. See
Qt 4 的新功能
了解细节。)
The
qt3to4
porting tool replaces occurrences of Qt 3 classes that don't exist anymore in Qt 4 with the corresponding Qt 3 support class; for example,
QListBox
is turned into
Q3ListBox
.
At some point, you might want to stop linking against the Qt 3 support library ( Qt3Support ) and take advantage of Qt 4's new features. The instructions below explain how to do that for each compatibility class.
除了
Qt3Support
classes (such as
Q3Action
,
Q3ListBox
,和
Q3ValueList
), Qt 4 provides compatibility functions when it's possible for an old API to cohabit with the new one. For example,
QString
提供
QString::simplifyWhiteSpace
() compatibility function that's implemented inline and that simply calls
QString::simplified
().
The compatibility functions are not documented here; instead, they are documented for each class.
If you have the line
QT += qt3support
在您的
.pro
file,
qmake
will automatically define the
QT3_SUPPORT
symbol, turning on compatibility function support. You can also define the symbol manually (e.g., if you don't want to link against the
Qt3Support
library), or you can define
QT3_SUPPORT_WARNINGS
instead, telling the compiler to emit a warning when a compatibility function is called. (This works only with GCC 3.2+ and MSVC 7.)
If you get stuck, ask on the qt-interest mailing list. If you are a licensed customer, you can also contact Qt's technical support team.
Table of contents:
In Qt 3, it was possible to use the
qt_cast()
function to determine whether instances of
QObject
subclasses could be safely cast to derived types of those subclasses. For example, if a
QFrame
instance is passed to a function whose signature specifies a
QWidget
pointer as its argument,
qt_cast()
could be used to obtain a
QFrame
pointer so that the instance's functions can be accessed.
In Qt 4, much of this functionality is provided by the qobject_cast () function, and additional functions also provide similar functionality for certain non- QObject types:
| Qt 3 function | Qt 4 function |
|---|---|
| T *qt_cast<T *>( QObject *) | T *qobject_cast<T *> ( QObject *) |
| T qgraphicsitem_cast<T> ( QGraphicsItem *) | |
| T qstyleoption_cast<T> ( QStyleOption *) | |
| T qvariant_cast<T> (const QVariant &) | |
| T qdbus_cast(const QDBusArgument &) |
The table below lists the classes that have been renamed in Qt 4. If you compile your applications with
QT3_SUPPORT
defined, the old names will be available.
Whenever you see an occurrence of the name on the left, you can safely replace it with the Qt 4 equivalent in your program. The qt3to4 tool performs the conversion automatically.
| Qt 3 class name | Qt 4 class name |
|---|---|
| QIconSet | QIcon |
| QWMatrix | QMatrix |
| QGuardedPtr | QPointer |
The table below lists the enums and typedefs that have been renamed in Qt 4. If you compile your applications with
QT3_SUPPORT
defined, the old names will be available.
Whenever you see an occurrence of the name on the left, you can safely replace it with the Qt 4 equivalent in your program. The qt3to4 tool performs the conversion automatically.
| Qt 3 type name | Qt 4 type name |
|---|---|
| QApplication::ColorMode | QApplication::ColorSpec |
| QButton::ToggleState | QCheckBox::ToggleState |
| QCursorShape | Qt::CursorShape |
| QFile::FilterSpec | QFile::Filters |
| QFile::PermissionSpec | QFile::Permission |
| QFile::SortSpec | QFile::SortFlags |
| QFile::Status | QFile::Error |
| QFileInfo::PermissionSpec | QFile::Permission |
| QGrid::Direction | Qt::Orientation |
| QGridWidget::Direction | Qt::Orientation |
| QIODevice::Offset | qlonglong |
| QImage::ScaleMode | Qt::AspectRatioMode |
| QSize::ScaleMode | Qt::AspectRatioMode |
| QSocket::Error | Q3Socket::Error |
| QSocket::State | Q3Socket::State |
| QStyle::SCFlags | QStyle::SubControls |
| QStyle::SFlags | QStyle::State |
| QTS | QTextStream |
| QUrlDrag | QUriDrag |
| QWidget::FocusPolicy | Qt::FocusPolicy |
| Q_LLONG | qlonglong |
| Q_ULLONG | qulonglong |
| Qt::Dock | Qt::ToolBarDock |
| Qt::MacintoshVersion | QSysInfo::MacVersion |
| Qt::TextFlags | Qt::TextFlag |
| Qt::WindowsVersion | QSysInfo::WinVersion |
The table below lists the enum values that have been renamed in Qt 4. If you compile your applications with
QT3_SUPPORT
defined, the old names will be available.
Whenever you see an occurrence of the name on the left, you can safely replace it with the Qt 4 equivalent in your program. The qt3to4 tool performs the conversion automatically.
In addition, the following 窗口标志 have been either replaced with widget attributes or have been deprecated:
| Qt 3 type | Qt 4 equivalent |
|---|---|
| Qt::WDestructiveClose | 使用 QWidget::setAttribute ( Qt::WA_DeleteOnClose ) 代替。 |
| Qt::WStaticContents | 使用 QWidget::setAttribute ( Qt::WA_StaticContents ) 代替。 |
| Qt::WNorthWestGravity | |
| Qt::WNoAutoErase | 使用 QWidget::setAttribute ( Qt::WA_NoBackground ) 代替。 |
| Qt::WResizeNoErase | |
| Qt::WRepaintNoErase | |
| Qt::WPaintClever | Unnecessary in Qt 4. |
| Qt::WMacNoSheet | Unnecessary in Qt 4. |
In Qt 4.1, the widget flags used to determine window modality were replaced by a single enum that can be used to specify the modal behavior of top-level widgets:
| Qt 3 type | Qt 4 equivalent |
|---|---|
| Qt::WShowModal | 使用 QWidget::setWindowModality ( Qt::ApplicationModal ) 代替。 |
| Qt::WGroupLeader | 使用 QWidget::setWindowModality ( Qt::WindowModal ) for each child dialog of the group leader, but do not change the modality of the group leader itself. |
Some properties have been renamed in Qt 4, to make Qt's API more consistent and more intuitive. For example,
QWidget
's
caption
property has been renamed
windowTitle
to make it clear that it refers to the title shown in the window's title bar.
In addition, the property system has been extended to allow properties to be redefined in subclasses with the
Q_PROPERTY
() macro, removing the need for a
Q_OVERRIDE()
宏。
The table below lists the Qt properties that have been renamed in Qt 4. Occurrences of these in
Qt Designer
UI files are automatically converted to the new name by
uic
.
A handful of properties in Qt 3 are no longer properties in Qt 4, but the access functions still exist as part of the Qt 4 API. These are not used by Qt Designer ; the only case where you need to worry about them is in highly dynamic applications that use Qt's meta-object system to access properties. Here's the list of these properties with the read and write functions that you can use instead:
Some properties have been removed from Qt 4, but the associated access functions are provided if
QT3_SUPPORT
is defined to help porting to Qt 4. When converting Qt 3 UI files to Qt 4,
uic
generates calls to the Qt 3 compatibility functions. Note that this only applies to the properties of the
Qt3Support
library, i.e.
QT3_SUPPORT
properties of the other libraries must be ported manually when converting Qt 3 UI files to Qt 4.
The table below lists these properties with the read and write functions that you can use instead. The documentation for the individual functions explains how to replace them with non-compatibility Qt 4 functions.
| Qt 3 property |
Qt 4 read function (
QT3_SUPPORT
)
|
Qt 4 write function (
QT3_SUPPORT
)
|
|---|---|---|
| QMenuBar::separator | QMenuBar::separator () | QMenuBar::setSeparator () |
| QPushButton::menuButton | QPushButton::isMenuButton () | N/A |
| QTabWidget::margin | QTabWidget::margin () | QTabWidget::setMargin () |
| QTextEdit::textFormat | QTextEdit::textFormat () | QTextEdit::setTextFormat () |
| QWidget::backgroundBrush | QWidget::backgroundBrush() | N/A |
| QWidget::backgroundMode | QWidget::backgroundMode () | QWidget::setBackgroundMode () |
| QWidget::backgroundOrigin | QWidget::backgroundOrigin() | QWidget::setBackgroundOrigin() |
| QWidget::colorGroup | QWidget::colorGroup () | QWidget::setColorGroup() |
| QWidget::customWhatsThis | QWidget::customWhatsThis() | QWidget::setCustomWhatsThis() |
| QWidget::inputMethodEnabled | QWidget::inputMethodEnabled() | QWidget::setInputMethodEnabled () |
| QWidget::ownCursor | QWidget::ownCursor () | N/A |
| QWidget::ownFont | QWidget::ownFont () | N/A |
| QWidget::ownPalette | QWidget::ownPalette () | N/A |
| QWidget::paletteBackgroundColor | QWidget::paletteBackgroundColor() | QWidget::setPaletteBackgroundColor () |
| QWidget::paletteBackgroundPixmap | QWidget::paletteBackgroundPixmap() | QWidget::setPaletteBackgroundPixmap () |
| QWidget::paletteForegroundColor | QWidget::paletteForegroundColor() | QWidget::setPaletteForegroundColor () |
| QWidget::underMouse | QWidget::underMouse () | N/A |
The following Qt 3 properties and their access functions are no longer available in Qt 4. In most cases, Qt 4 provides similar functionality.
| Qt 3 property | Qt 4 equivalent |
|---|---|
| QButton::autoRepeat | N/A |
| QButton::autoResize | 调用 QWidget :setFixedSize( QWidget::sizeHint ()) whenever you change the contents. |
| QButton::exclusiveToggle | 见 QAbstractButton::autoExclusive . |
| QButton::pixmap | 使用 QAbstractButton::icon 代替。 |
| QButton::toggleState | 使用 QCheckBox::setState () 和 QCheckBox::state () 代替。 |
| QButton::toggleType | 使用 QCheckBox::setTristate () 代替。 |
| QComboBox::autoResize | 调用 QWidget :setFixedSize( QWidget::sizeHint ()) whenever you change the contents. |
| QFrame::contentsRect | 使用 Q3Frame::contentsRect () 代替。 |
| QFrame::margin | 使用 QWidget::setContentsMargins () 代替。 |
| QTabBar::keyboardFocusTab | N/A |
| QToolButton::offIconSet | 使用 off component of QAbstractButton::icon 代替。 |
| QToolButton::onIconSet | 使用 on component of QAbstractButton::icon 代替。 |
| QWidget::microFocusHint | N/A |
| QMimeSource::serialNumber () | N/A |
Qt 4 is the first version of Qt that contains no explicitly shared classes. All classes that were explicitly shared in Qt 3 are 隐式 shared in Qt 4:
This means that if you took a copy of an instance of the class (using operator=() or the class's copy constructor), any modification to the copy would affect the original and vice versa. Needless to say, this behavior is rarely desirable.
Fortunately, nearly all Qt 3 applications don't rely on explicit sharing. When porting, you typically only need to remove calls to detach() and/or copy(), which aren't necessary anymore.
If you deliberately rely on explicit sharing in your application, you can use pointers or references to achieve the same result in Qt 4.
例如,若有代码像
void asciify(QByteArray array)
{
for (int i = 0; i < (int)array.size(); ++i) {
if ((uchar)array[i] >= 128)
array[i] = '?';
}
}
可以把它重写成
void asciify(QByteArray &array) { for (int i = 0; i < array.size(); ++i) { if ((uchar)array[i] >= 128) array[i] = '?'; } }
(Notice the
&
in the parameter declaration.)
When implementing custom widgets in Qt 3, it was possible to use QPainter to draw on a widget outside paint events. This made it possible to integrate Qt applications with third party libraries and tools that impose their own rendering models. For example, a widget might be repainted in a slot using data obtained from an external source.
In Qt 4, it is only possible to paint on a widget from within its paintEvent() handler function. This restriction simplifies Qt's interaction with native window systems, improves the performance of applications by reducing the number of redraw operations, and also enables features to be implemented to improve the appearance of widgets, such as a backing store.
Generally, we recommend redesigning applications to perform all painting operations in paintEvent() functions, deferring actual painting until the next time this function is called. Applications can post paint events to trigger repaints, and it may be possible to examine your widget's internal state to determine which part of the widget needs to be repainted.
If asynchronous repaints are used extensively by your application, and it is not practical to redesign the rendering model to perform all painting operations from within a widget's paintEvent() function, it may be necessary to consider using an intermediate painting step. In this approach, one or more images can be updated asynchronously and painted on the widget in the paint event. To avoid excessive buffering, it may be worthwhile disabling the backing store by setting the widget's Qt::WA_PaintOnScreen widget attribute.
On certain platforms, the Qt::WA_PaintOutsidePaintEvent widget attribute can be set to allow a widget to be painted from outside paint events.
注意: Setting widget attributes to disable key features of Qt's widget rendering model may also cause other features to be disabled.
当
QT3_SUPPORT
is defined, the default connection type for signals and slots is the
Qt::AutoCompatConnection
type. This allows so-called
compatibility
signals and slots (defined in Qt 3 support mode to provide Qt 3 compatibility features) to be connected to other signals and slots.
However, if Qt is compiled with debugging output enabled, and the developer uses other connection types to connect to compatibility signals and slots (perhaps by building their application without Qt 3 support enabled), then Qt will output warnings to the console to indicate that compatibility connections are being made. This is intended to be used as an aid in the process of porting a Qt 3 application to Qt 4.
The
QAccel
class has been renamed
Q3Accel
and moved to the
Qt3Support
module. In new applications, you have three options:
The Q3Accel class also supports multiple accelerators using the same object, by calling Q3Accel::insertItem () multiple times. In Qt 4, the solution is to create multiple QShortcut 对象。
The QAccessibleInterface class has undergone some API changes in Qt 4, to make it more consistent with the rest of the Qt API.
If you have classes that inherit QAccessibleInterface or one of its subclasses ( QAccessibleObject , QAccessibleWidget , etc.), you must port them the new QAccessibleInterface API.
见 Virtual Functions for a list of QAccessibleInterface virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The
QAccessibleTitleBar
has been renamed Q3AccessibleTitleBar and moved to the
Qt3Support
库。
The
QAction
class has been redesigned in Qt 4 to integrate better with the rest of the menu system. It unifies the old
QMenuItem
class and the old
QAction
class into one class, avoiding unnecessary data duplication and the need to learn two different APIs.
The old
QAction
and
QActionGroup
classes have been renamed
Q3Action
and
Q3ActionGroup
and moved to
Qt3Support
. In addition, the new
QAction
class has compatibility functions to ease transition to Qt 4. Note that when using
Q3ToolBar
and
Q3PopupMenu
, their actions must be
Q3Action
。
见 Virtual Functions for a list of QAction virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The QAction class has been completely redesigned in Qt 4 to integrate better with the rest of the menu system. See the section on QAction 了解细节。
The QApplication class has been split into two classes: QCoreApplication and QApplication . The new QApplication 类继承 QCoreApplication and adds GUI-related functionality. In practice, this has no consequences for existing Qt applications.
In addition, the following API changes were made:
Also, QWidgetList has changed from being a typedef for QPtrList< QWidget > to being a typedef for QList < QWidget *>. See the section on QWidgetList below for details.
例如,若有代码像
QWidgetList *list = QApplication::topLevelWidgets();
QWidgetListIt it(*list);
QWidget *widget;
while ((widget = it.current())) {
if (widget->inherits("MainWindow"))
((MainWindow *)widget)->updateRecentFileItems();
++it;
}
delete list;
可以把它重写成
QWidgetList list = QApplication::topLevelWidgets();
for (int i = 0; i < list.size(); ++i) {
if (MainWindow *mainWin = qobject_cast<MainWindow *>(list.at(i)))
mainWin->updateRecentFileItems();
}
The
QAquaStyle
class first appeared in Qt 3.0, when the Qt for Mac OS X port was first released. It emulated Apple's "Aqua" theme. In Qt 3.1,
QAquaStyle
was obsoleted by
QMacStyle
, which uses Appearance Manager to perform its drawing.
The
QAquaStyle
class is no longer provided in Qt 4. Use
QMacStyle
代替。
QAsciiCache<T>
has been renamed
Q3AsciiCache
<T> and moved to the
Qt3Support
library. It has been replaced by
QCache
<
QByteArray
, T>.
For details, read the section on QCache<T> , mentally substituting QByteArray for QString .
QAsciiDict<T> and QAsciiDictIterator<T> have been renamed Q3AsciiDict <T> 和 Q3AsciiDictIterator <T> and moved to the Qt3Support library. They have been replaced by the more modern QHash <Key, T> and QMultiHash <Key, T> classes and their associated iterator classes.
When porting old code that uses Q3AsciiDict <T> to Qt 4, there are four classes that you can use:
For details, read the section on QDict<T> , mentally substituting QByteArray for QString .
The
QAsyncIO
class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.
If you use this mechanism in your application, please submit a report to the Task Tracker on the Qt website and we will try to find a satisfactory substitute.
The undocumented
QBackInsertIterator
class has been removed from the Qt library. If you need it in your application, feel free to copy the source code from the Qt 3
<qtl.h>
头文件。
In Qt 3, QBitArray inherited from QByteArray . In Qt 4, QBitArray is a totally independent class. This makes very little difference to the user, except that the new QBitArray doesn't provide any of QByteArray 's byte-based API anymore. These calls will result in a compile-time error, except calls to QBitArray::truncate (), whose parameter was a number of bytes in Qt 3 and a number of bits in Qt 4.
QBitArray was an explicitly shared class in Qt 3. See Explicit Sharing 了解更多信息。
The
QBitVal
class has been renamed QBitRef.
The
QButton
class has been replaced by
QAbstractButton
in Qt 4. Classes like
QPushButton
and
QRadioButton
inherit from
QAbstractButton
. As a help when porting older Qt applications, the
Qt3Support
library contains a
Q3Button
class implemented in terms of the new
QAbstractButton
.
If you used the
QButton
class as a base class for your own button type and want to port your code to the newer
QAbstractButton
, you need to be aware that
QAbstractButton
has no equivalent for the
Q3Button::drawButton
(
QPainter
*) virtual function. The solution is to reimplement
QWidget::paintEvent
() 在您的
QAbstractButton
subclass as follows:
void MyButton::paintEvent(QPaintEvent *) { QPainter painter(this); drawButton(&painter); }
| Q3Button function | QAbstractButton equivalent |
|---|---|
| Q3Button::autoResize() | 调用 QWidget :setFixedSize( QWidget::sizeHint ()) whenever you change the contents. |
| Q3Button::isExclusiveToggle() | 使用 QAbstractButton::group () 或 QAbstractButton::autoExclusive () 代替。 |
| Q3Button::pixmap () const | QAbstractButton::icon () |
| Q3Button::setAutoResize() | N/A |
| Q3Button::setPixmap (const QPixmap &) | QAbstractButton::setIcon (const QIcon &) |
| Q3Button::setState(ToggleState) | See remark below |
| Q3Button::setToggleType(ToggleType) | See remark below |
| Q3Button::state() | See remark below |
| Q3Button::stateChanged(int) | See remark below |
| Q3Button::toggleType() | See remark below |
Remarks:
QButton
had a "toggle type", which could be QButton::SingleShot, QButton::Toggle, or QButton::Tristate. The new
QAbstractButton
class doesn't support "tristate" directly; this feature is implemented in
QCheckBox
instead. The two other "toggle types" (
QButton::SingleShot
and
QButton::Toggle
) are replaced by a
QAbstractButton::checkable
特性。
QButton::Off
,
QButton::NoChange
,或
QButton::On
. In Qt 4, this mechanism has been moved to
QCheckBox
.
见
Virtual Functions
for a list of
QButton
virtual member functions in Qt 3 that aren't virtual in Qt 4.
见
特性
for a list of
QButton
properties in Qt 3 that have changed in Qt 4.
The
QButtonGroup
class has been completely redesigned in Qt 4. For compatibility, the old
QButtonGroup
class has been renamed
Q3ButtonGroup
and has been moved to
Qt3Support
. Likewise, the
QHButtonGroup
and
QVButtonGroup
convenience subclasses have been renamed
Q3HButtonGroup
and
Q3VButtonGroup
and moved to the
Qt3Support
库。
The old
QButtonGroup
, as well as
Q3ButtonGroup
, can be used in two ways:
不像 Q3ButtonGroup ,新 QButtonGroup doesn't inherit QWidget . It is very similar to a "hidden Q3ButtonGroup ".
If you use a Q3ButtonGroup , Q3HButtonGroup ,或 Q3VButtonGroup as a widget and want to port to Qt 4, you can replace it with QGroupBox . In Qt 4, radio buttons with the same parent are automatically part of an exclusive group, so you normally don't need to do anything else. See also the section on QGroupBox 下文。
见 Virtual Functions for a list of QButtonGroup virtual member functions in Qt 3 that are no longer virtual in Qt 4.
In Qt 3, QByteArray was simply a typedef for QMemArray<char>. In Qt 4, QByteArray is a class in its own right, with a higher-level API in the style of QString .
Here are the main issues to be aware of when porting to Qt 4:
例如,若有代码像
QByteArray ba(64);
可以把它重写成
QByteArray ba(64, '\0');
ba.at(0) = 'X';
will no longer compile. Instead, use QByteArray::operator[]:
ba[0] = 'X';
QByteArray was an explicitly shared class in Qt 3. See Explicit Sharing 了解更多信息。
QCache <T> has been renamed Q3Cache <T> and moved to Qt3Support . The new QCache class has a different API, and takes different template parameters: QCache <Key, T>.
When porting to Qt 4, QCache < QString , T> is the obvious substitute for Q3Cache <T>. The following table summarizes the API differences.
| Q3Cache <T> function | QCache < QString , T> equivalent |
|---|---|
| Q3Cache::Q3Cache (int maxCost, int size, bool caseSensitive) | See remark below |
| Q3Cache::autoDelete () | N/A |
| Q3Cache::count () | QCache::count () 或 QCache::size () (equivalent) |
| Q3Cache::setAutoDelete () | See remark below |
| Q3Cache::size () | N/A |
| Q3Cache::statistics () | N/A |
| Q3Cache::operator=() | See remark below |
Remarks:
bool
value that indicates whether or not the item actually was inserted in the cache. If the item wasn't inserted, it was the caller's responsibility to delete the item. The new
QCache::insert
() 函数返回
void
and either adds it to the cache or deletes it right away. Old code like
if (!cache.insert(key, object)) delete object;
becomes
cache.insert(key, object);
Q3Cache<QWidget> cache; cache.insert(widget->name(), widget); ... QWidget *foo = cache.take("foo"); if (foo) foo->show();
becomes
typedef QWidget *QWidgetPtr; QCache<QString, QWidgetPtr> cache; cache.insert(widget->name(), new QWidgetPtr(widget)); ... QWidgetPtr *ptr = cache.take("foo"); if (ptr) { QWidget *foo = *ptr; delete ptr; foo->show(); }
An alternative is to stick to using Q3Cache .
QCacheIterator<T> has been renamed Q3CacheIterator <T> and moved to the Qt3Support library. The new QCache class doesn't offer any iterator types.
The canvas module classes have been renamed and moved to the Qt3Support 库。
| Qt 3 class name | Compatibility class in Qt 4 |
|---|---|
QCanvas
|
Q3Canvas |
QCanvasEllipse
|
Q3CanvasEllipse |
QCanvasItem
|
Q3CanvasItem |
QCanvasItemList
|
Q3CanvasItemList |
QCanvasLine
|
Q3CanvasLine |
QCanvasPixmap
|
Q3CanvasPixmap |
QCanvasPixmapArray
|
Q3CanvasPixmapArray |
QCanvasPolygon
|
Q3CanvasPolygon |
QCanvasPolygonalItem
|
Q3CanvasPolygonalItem |
QCanvasRectangle
|
Q3CanvasRectangle |
QCanvasSpline
|
Q3CanvasSpline |
QCanvasSprite
|
Q3CanvasSprite |
QCanvasText
|
Q3CanvasText |
QCanvasView
|
Q3CanvasView |
The 图形视图框架 替换 QCanvas . For more on porting to Graphics View, see Porting to Graphics View .
In Qt 4, QColor is a value type like QPoint or QRect . Graphics system-specific code has been implemented in QColormap .
The
QColor::maxColors()
function has been replaced by
QColormap::size
().
The
QColor::numBitPlanes()
function has been replaced by
QColormap::depth
().
The
QColor::setNamedColor()
function no longer supports the named color in the same way as Qt 3. Qt 4's
setNamedColor()
uses the new W3C convention as stated
here
.
The predefined colors listed in the table above were static QColor objects in Qt 3. In Qt 4, they are enum values of type Qt::GlobalColor . Thanks to the implicit QColor ( Qt::GlobalColor ) constructor, the enum values are automatically converted to QColor s in most contexts. Occasionally, you might need a cast.
例如,若有代码像
QColor lightCyan = Qt::cyan.light(180);
可以把它重写成
QColor lightCyan = QColor(Qt::cyan).light(180);
In Qt 3, a
QPalette
consisted of three
QColorGroup
objects. In Qt 4, the (rarely used)
QColorGroup
abstraction has been eliminated. For source compatibility, a
QColorGroup
class is available when
QT3_SUPPORT
有定义。
新的 QPalette still works in terms of color groups, specified through enum values ( QPalette::Active , QPalette::Disabled ,和 QPalette::Inactive ). It also has the concept of a current color group, which you can set using QPalette::setCurrentColorGroup ().
The QPalette object returned by QWidget::palette () 返回 QPalette initialized with the correct current color group for the widget. This means that if you had code like
painter.setBrush(colorGroup().brush(QColorGroup::Text));
you can simply replace colorGroup() with palette():
painter.setBrush(palette().brush(QPalette::Text));
The
QColorDrag
class has been renamed
Q3ColorDrag
and moved to the
Qt3Support
library. In Qt 4, use
QMimeData
instead and call QMimeData::setColor() to set the color.
In Qt 3, the list box used to display the contents of a
QComboBox
widget could be accessed by using the
listBox()
function. In Qt 4, the standard list box is provided by a
QListView
widget, and can be accessed with the
view()
函数。
见 Virtual Functions for a list of QComboBox virtual member functions in Qt 3 that are no longer virtual in Qt 4.
In Qt 3,
QCString
inherited from
QByteArray
. The main drawback of this approach is that the user had the responsibility of ensuring that the string is '\0'-terminated. Another important issue was that conversions between
QCString
and
QByteArray
often gave confusing results. (See the
Achtung! Binary and Character Data
article in
Qt 季刊
for an overview of the pitfalls.)
Qt 4 solves that problem by merging the
QByteArray
and
QCString
classes into one class called
QByteArray
. Most functions that were in
QCString
previously have been moved to
QByteArray
. The '\0' issue is handled by having
QByteArray
allocate one extra byte that it always sets to '\0'. For example:
QByteArray ba("Hello"); ba.size(); // returns 5 (the '\0' is not counted) ba.length(); // returns 5 ba.data()[5]; // returns '\0'
The
Qt3Support
library contains a class called
Q3CString
that inherits from the new
QByteArray
class and that extends it to provide an API that is as close to the old
QCString
class as possible. Note that the following functions aren't provided by
Q3CString
:
The following functions have lost their last parameter, which specified whether the search was case sensitive or not:
In both cases, the solution is to convert the
QCString
到
QString
and use the corresponding
QString
functions instead.
Also be aware that
QCString::size()
(inherited from
QByteArray
) used to return the size of the character data
包括
the '\0'-terminator, whereas the new
QByteArray::size
() is just a synonym for
QByteArray::length
(). This brings
QByteArray
in line with
QString
.
When porting to Qt 4, occurrences of
QCString
should be replaced with
QByteArray
or
QString
. The following table summarizes the API differences between the
Q3CString
class and the Qt 4
QByteArray
and
QString
类:
| Q3CString function | Qt 4 equivalent |
|---|---|
| Q3CString::Q3CString (const char *, uint) | See remark below |
| Q3CString::Q3CString (int) | QByteArray::QByteArray (int, char) |
| Q3CString::leftJustify () | QString::leftJustified () |
| Q3CString::length () | QByteArray::length () 或 QByteArray::size () (equivalent) |
| Q3CString::lower () | QByteArray::toLower () |
| Q3CString::rightJustify () | QString::rightJustified () |
| Q3CString::setExpand () | See remark below |
| Q3CString::simplifyWhiteSpace () | QByteArray::simplified () |
| Q3CString::sprintf () | QString::sprintf () |
| Q3CString::stripWhiteSpace () | QByteArray::trimmed () |
| Q3CString::toDouble () | QString::toDouble () |
| Q3CString::toFloat () | QString::toFloat () |
| Q3CString::toInt () | QString::toInt () |
| Q3CString::toLong () | QString::toLong () |
| Q3CString::toShort () | QString::toShort () |
| Q3CString::toUInt () | QString::toUInt () |
| Q3CString::toULong () | QString::toULong () |
| Q3CString::toUShort () | QString::toUShort () |
| Q3CString::upper () | QByteArray::toUpper () |
Remarks:
例如,若有代码像
QCString str1("Hello", 4); // "Hel"
QCString str2("Hello world!", n);
可以把它重写成
QByteArray str1("Hello", 3);
QByteArray str2("Hello world!");
str2.truncate(n - 1);
例如,若有代码像
QCString str("Hello world");
str.setExpand(16, '\n'); // "Hello world \n"
可以把它重写成
QByteArray str("Hello world");
while (str.size() < 16)
str += ' ';
str += '\n';
Since the old
QCString
class inherited from
QByteArray
, everything that is said in the
QByteArray section
applies for
QCString
还。
In Qt 3, developers could create a custom event by constructing a new QCustomEvent , and send relevant data to other components in the application by passing a void pointer, either on construction or using the setData() function. Objects could receive custom events by reimplementing the customEvent() function, and access the stored data using the event's data() function.
In Qt 4, custom events are created by subclassing QEvent . Event-specific data can be stored in a way that is appropriate for your application. Custom events are still delivered to each object's customEvent() handler function, but as QEvent objects rather than as deprecated QCustomEvent 对象。
The
QDataBrowser
class has been renamed
Q3DataBrowser
and moved to the
Qt3Support
library. In Qt 4.2, you should use the
QDataWidgetMapper
class to create data-aware forms.
见 QtSql Module for an overview of the new SQL classes.
The
QDataPump
class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.
If you use this mechanism in your application, please submit a report to the Task Tracker on the Qt website and we will try to find a satisfactory substitute.
The
QDataSink
class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0.
If you use this mechanism in your application, please submit a report to the Task Tracker on the Qt website and we will try to find a satisfactory substitute.
The
QDataSource
class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0. If you use this mechanism in your application, please submit a report to the
Task Tracker
on the Qt website and we will try to find a satisfactory substitute.
The
QDataTable
class has been renamed
Q3DataTable
and moved to the
Qt3Support
library. In Qt 4.2, you should use the
QDataWidgetMapper
class to create data-aware forms.
见 QtSql Module for an overview of the new SQL classes.
The
QDataView
class has been renamed
Q3DataView
and moved to the
Qt3Support
library. In Qt 4.2, you should use the
QDataWidgetMapper
class to create data-aware forms.
见 QtSql Module for an overview of the new SQL classes.
The QDateEdit class in Qt 4 is a convenience class based on QDateTimeEdit . The old class has been renamed Q3DateEdit and moved to the Qt3Support 库。
见
Virtual Functions
for a list of
QDateEdit
virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The
QDateTimeEditBase
class has been renamed
Q3DateTimeEditBase
and moved to
Qt3Support
。使用
QDateTimeEdit
or
QAbstractSpinBox
代替。
The old
QDateTimeEdit
class has been renamed
Q3DateTimeEditBase
and moved to
Qt3Support
. The new
QDateTimeEdit
in Qt 4 has been rewritten from scratch to provide a more flexible and powerful API.
见 Virtual Functions for a list of QDateTimeEdit virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The
QDeepCopy<T>
class in Qt 3 provided a means of ensuring that implicitly shared and explicitly shared classes referenced unique data. This was necessary because the reference counting in Qt's container classes was done in a thread-unsafe manner.
With Qt 4,
QDeepCopy<T>
has been renamed
Q3DeepCopy
<T> and moved to the
Qt3Support
library. Removing it from existing code is straightforward.
例如,若有代码像
QString str1 = "I am a string"; QDeepCopy<QString> str2 = str1; QString str3 = QDeepCopy<QString>(str2);
可以把它重写成
QString str1 = "I am a string"; QString str2 = str1; QString str3 = str2;
见 Virtual Functions for a list of QDial virtual member functions in Qt 3 that are no longer virtual in Qt 4.
见 特性 for a list of QDial properties in Qt 3 that have changed in Qt 4.
QDict<T>
has been renamed
Q3Dict
<T> and moved to
Qt3Support
. It has been replaced by the more modern
QHash
<Key, T> and
QMultiHash
<Key, T> classes.
When porting old code that uses QDict<T> to Qt 4, there are four classes that you can use:
| Qt 4 class | When to use it |
|---|---|
| QMultiHash < QString , T *> | 由于 Q3Dict <T> is pointer-based and allows duplicate keys, this is usually the most straightforward conversion. |
| QMultiHash < QString , T> |
If type
T
是
可赋值数据类型
, you can use
T
as the value type rather than
T *
. This often leads to nicer code.
|
| QHash < QString , T *> | If you don't use duplicate keys, you can use QHash 而不是 QMultiHash . QMultiHash 继承自 QHash . |
| QHash < QString , T> |
The APIs of Q3Dict <T> 和 QMultiHash < QString , T *> are quite similar. The main issue is that Q3Dict supports auto-delete whereas QMultiHash doesn't.
The following table summarizes the API differences between the two classes:
| Q3Dict function | QMultiHash equivalent |
|---|---|
| Q3Dict::Q3Dict (int size, bool caseSensitive) | See remarks below |
| Q3Dict::autoDelete () | N/A |
| Q3Dict::count () | QMultiHash::count () 或 QMultiHash::size () (equivalent) |
| Q3Dict::find (const QString &) | QMultiHash::value (const QString &) |
| Q3Dict::remove (const QString &) | QMultiHash::take (const QString &) |
| Q3Dict::resize (uint) | QMultiHash::reserve (int) |
| Q3Dict::setAutoDelete () | See discussion below |
| Q3Dict::size () | QMultiHash::capacity () |
| Q3Dict::statistics () | N/A |
| Q3Dict::operator[](const QString &) | See remark below |
Remarks:
若使用
Q3Dict
's auto-delete feature (by calling
Q3Dict::setAutoDelete
(true)), you need to do some more work. You have two options: Either you call
delete
yourself whenever you remove an item from the container, or you use
QMultiHash
<
QString
, T> instead of
QMultiHash
<
QString
, T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call
delete
.
The following table summarizes the idioms that you need to watch out for if you want to call
delete
yourself.
| Q3Dict idiom | QMultiHash idiom |
|---|---|
dict.replace(key, value); |
delete hash.take(key); hash.insert(key, value); |
dict.remove(key, value); |
delete hash.take(key); |
dict.clear();
(also called from Q3Dict 's destructor) |
while (!hash.isEmpty()) { T *value = *hash.begin(); hash.erase(hash.begin()); delete value; } In 99% of cases, the following idiom also works: qDeleteAll(hash); hash.clear();
However, it may lead to crashes if
|
注意,
Q3Dict
's destructor automatically calls clear(). If you have a
Q3Dict
data member in a custom class and use the auto-delete feature, you will need to call
delete
on all the items in the container from your class destructor to avoid a memory leak.
最后,
QDictIterator<T>
(renamed
Q3DictIterator
<T>) must also be ported. There are no fewer than four iterator classes that can be used as a replacement:
QHash::const_iterator
,
QHash::iterator
,
QHashIterator
,和
QMutableHashIterator
. The most straightforward class to use when porting is
QHashIterator
<
QString
, T *>. The following table summarizes the API differences:
| Q3DictIterator 函数 | Qt 4 equivalent |
|---|---|
| Q3DictIterator::count () | QHash::count () 或 QHash::size () |
| Q3DictIterator::current () | QHashIterator::value () |
| Q3DictIterator::currentKey () | QHashIterator::key () |
| Q3DictIterator::isEmpty () | QHash::isEmpty () |
| Q3DictIterator::toFirst () | QHashIterator::toFront () |
| Q3DictIterator::operator()() | QHashIterator::value () |
| Q3DictIterator::operator*() | QHashIterator::value () |
| Q3DictIterator::operator++() | See remark below |
注意, QHashIterator has a different way of iterating than Q3DictIterator . A typical loop with Q3DictIterator 看起来像这样:
Q3DictIterator<QWidget> i(dict); while (i.current() != 0) { do_something(i.currentKey(), i.current()); ++i; }
Here's the equivalent QHashIterator loop:
QHashIterator<QString, QWidget *> i(hash); while (i.hasNext()) { i.next(); // must come first do_something(i.key(), i.value()); }
见 Java 风格迭代器 了解细节。
The following functions used to have a boolean
acceptAbsPath
parameter that defaulted to true:
In Qt 3, if
acceptAbsPath
is true, a file name starting with '/' is be returned without change; if
acceptAbsPath
is false, an absolute path is prepended to the file name. For example:
| Current directory | File name |
acceptAbsPath
|
File path |
|---|---|---|---|
| /home/tsmith | index.html | true | /home/tsmith/index.html |
| false | /home/tsmith/index.html | ||
| /home/tsmith | /index.html | true | /index.html |
| false | /home/tsmith/index.html |
In Qt 4, this parameter is no longer available. If you use it in your code, you can check that QDir::isRelativePath () returns false instead.
例如,若有代码像
QDir dir("/home/tsmith");
QString path = dir.filePath(fileName, false);
可以把它重写成
QDir dir("/home/tsmith"); QString path; if (dir.isRelativePath(fileName)) path = dir.filePath(fileName); else path = fileName;
QDir::encodedEntryList() has been removed.
fileInfoList(), entryInfoList(), and drives() now return a QList < QFileInfo > and not a QPtrList< QFileInfo > *. Code using these methods will not work with the Qt3Support library and must be adapted instead.
见 Virtual Functions for a list of QDir virtual member functions in Qt 3 that are no longer virtual in Qt 4.
QDir::match () now always matches case insensitively.
QDir::homeDirPath () has been removed. Use QDir::home () instead, and extract the path separately.
Qt 3 used its own implementation of the DNS protocol and provided a low-level
QDns
class. Qt 4's
QHostInfo
class uses the system's
gethostbyname()
function from a thread instead.
The old
QDns
class has been renamed
Q3Dns
and moved to the
Qt3Support
library. The new
QHostInfo
class has a radically different API: It consists mainly of two static functions, one of which is blocking (
QHostInfo::fromName
()), the other non-blocking (
QHostInfo::lookupHost
()). See the
QHostInfo
class documentation for details.
The
QDockArea
class has been renamed
Q3DockArea
and moved to the
Qt3Support
library. In Qt 4,
QMainWindow
handles the dock and toolbar areas itself. See the
QMainWindow
文档编制了解细节。
The old
QDockWindow
class has been renamed
Q3DockWindow
and moved to the
Qt3Support
library. In Qt 4, there is a new
QDockWidget
class with a different API. See the class documentation for details.
见 Virtual Functions for a list of QDockWidget virtual member functions in Qt 3 that are no longer virtual in Qt 4.
注意: Q3DockWindow 's horizontallyStretchable property can be achieved in QDockWidget with 大小策略 .
The
QDragObject
class has been renamed
Q3DragObject
and moved to the
Qt3Support
library. In Qt 4, it has been replaced by the
QMimeData
class. See the class documentation for details.
注意, Q3DragObject::DragCopyOrMove drag and drop mode is interpreted differently to Qt 3's QDragObject::DragCopyOrMove mode. In Qt 3, a move operation was performed by default, and the user had to hold down the Ctrl key to perform a copy operation. In Qt 4, a copy operation is performed by default; the user has to hold down the Shift key to perform a move operation.
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The
QDropSite
class has been renamed
Q3DropSite
and moved to the
Qt3Support
库。
The QDropSite class has been obsolete ever since Qt 2.0. The only thing it does is call QWidget::setAcceptDrops (true)。
例如,若有代码像
class MyWidget : public QWidget, public QDropSite
{
public:
MyWidget(const QWidget *parent)
: QWidget(parent), QDropSite(this)
{
}
...
}
可以把它重写成
class MyWidget : public QWidget { public: MyWidget(const QWidget *parent) : QWidget(parent) { setAcceptDrops(true); } ... }
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The
QEditorFactory
class has been renamed
Q3EditorFactory
and moved to the
Qt3Support
库。
见 QtSql Module for an overview of the new SQL classes.
In Qt 3,
QEventLoop
combined the Qt event loop and the event dispatching. In Qt 4, these tasks are now assigned to two distinct classes:
QEventLoop
and
QAbstractEventDispatcher
.
If you subclassed QEventLoop to integrate with another library's event loop, you must subclass QAbstractEventDispatcher instead. See the class documentation for details.
Developers using
QEventLoop::loopLevel()
in Qt 3 should use QCoreApplication::loopLevel() instead. Note that this function is marked as obsolete, but it is expected to be available for the lifetime of Qt 4.
The
QFileDialog
class in Qt 4 has been totally rewritten. It provides most of the functionality of the old
QFileDialog
class, but with a different API. Some functionality, such as the ability to preview files, is expected to be added in a later Qt 4 release.
The old
QFileDialog
,
QFileIconProvider
,和
QFilePreview
classes has been renamed
Q3FileDialog
,
Q3FileIconProvider
,和
Q3FilePreview
and have been moved to
Qt3Support
. You can use them if you need some functionality not provided yet by the new
QFileDialog
类。
The following table lists which functions have been renamed or removed in Qt 4.
Remarks:
例如,若有代码像
fileDialog->addFilter(tr("JPEG files (*.jpg *.jpeg)"));
可以把它重写成
QStringList filters = fileDialog->filters();
filters << tr("JPEG files (*.jpg *.jpeg)");
fileDialog->setFilters(filters);
例如,若有代码像
fileDialog->setSelectedFilter(3);
可以把它重写成
fileDialog->selectFilter(fileDialog->filters().at(3));
There are no equivalent virtual functions to the two Q3FileDialog::setSelectedFilter () virtual functions in the QFileDialog API. In addition, these functions have been renamed or removed, as described above.
The QFocusData class is not available in Qt 4. Some of its functionality is available via the QWidget::nextInFocusChain () 和 QWidget::focusNextPrevChild () 函数。
The setReason() function is no longer present in Qt 4. It is necessary to define the reason when constructing a focus event.
QFont::Script
has been moved to
QFontDatabase::WritingSystem
.
The QFrame class has been made more lightweight in Qt 4, by reducing the number of properties and virtual functions. The reduction in the number of virtual functions is significant because QFrame is the base class of many Qt classes.
Here's an overview of the changes:
margin
property (which wasn't honored by Qt's layout managers anyway).
To help with porting, the Qt3Support library contains a Q3Frame 类继承 QFrame and provides a similar API to the old QFrame class. If you derived from QFrame in your application, you might want to use Q3Frame as a base class as a first step in the porting process, and later move on to the new QFrame 类。
见 Virtual Functions for a list of QFrame virtual member functions in Qt 3 that are no longer virtual in Qt 4.
QFtp no longer inherits from QNetworkProtocol 。见 section on QNetworkProtocol 了解细节。
The old
QFtp
class has been renamed
Q3Ftp
and moved to the
Qt3Support
库。
The QGLayoutIterator class no longer exists in Qt 4. This makes only a difference if you implemented custom layout managers (i.e., QLayout subclasses).
The new approach is much simpler: It consists in reimplementing QLayout::itemAt () 和 QLayout::takeAt (). These functions operate on indexes, eliminating the need for a layout iterator class.
The
QGrid
class is now only available as
Q3Grid
in Qt 4. You can achieve the same result as
QGrid
by creating a
QWidget
with a grid layout:
例如,若有代码像
QGrid *grid = new QGrid(2, Qt::Horizontal); QPushButton *child1 = new QPushButton(grid); QPushButton *child2 = new QPushButton(grid); QPushButton *child3 = new QPushButton(grid); QPushButton *child4 = new QPushButton(grid);
可以把它重写成
QWidget *grid = new QWidget; QPushButton *child1 = new QPushButton(grid); QPushButton *child2 = new QPushButton(grid); QPushButton *child3 = new QPushButton(grid); QPushButton *child4 = new QPushButton(grid); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(child1, 0, 0); layout->addWidget(child2, 0, 1); layout->addWidget(child3, 1, 0); layout->addWidget(child4, 1, 1); grid->setLayout(layout);
见 Virtual Functions for a list of QGridLayout virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The
QGridView
class has been renamed
Q3GridView
and moved to the
Qt3Support
library. In Qt 4, we recommend that you use
QTableView
or
QAbstractItemView
for presenting tabular data.
见 模型/视图编程 for an overview of the new item view classes.
The
QGroupBox
class has been redesigned in Qt 4. Many of the features of the old
QGroupBox
class can be obtained by using the
Q3GroupBox
class from the
Qt3Support
库。
新的 QGroupBox is more lightweight. It doesn't attempt to duplicate functionality already provided by QGridLayout , and it does not inherit from QFrame . As a result, the following members have been removed:
Naturally, the
columns
and
orientation
properties have also been removed.
If you rely on some of the missing functionality in your application, you can use Q3GroupBox 而不是 QGroupBox as a help to porting.
见 Virtual Functions for a list of QGroupBox virtual member functions in Qt 3 that are no longer virtual in Qt 4.
The
QHBox
class is now only available as
Q3HBox
in Qt 4. You can achieve the same result as
QHBox
by creating a
QWidget
with an horizontal layout:
例如,若有代码像
QHBox *hbox = new QHBox; QPushButton *child1 = new QPushButton(hbox); QPushButton *child2 = new QPushButton(hbox);
可以把它重写成
QWidget *hbox = new QWidget; QPushButton *child1 = new QPushButton; QPushButton *child2 = new QPushButton; QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(child1); layout->addWidget(child2); hbox->setLayout(layout);
Note that child widgets are not automatically placed into the widget's layout; you will need to manually add each widget to the QHBoxLayout .
The
QHeader
class has been renamed
Q3Header
and moved to the
Qt3Support
library. In Qt 4, it is replaced by the
QHeaderView
类。
见 模型/视图编程 for an overview of the new item view classes.
The
QHGroupBox
class has been renamed
Q3HGroupBox
and moved to the
Qt3Support
library. Qt 4 does not provide a specific replacement class for
QHGroupBox
since
QGroupBox
is designed to be a generic container widget. As a result, you need to supply your own layout for any child widgets.
见 #QGroupBox for more information about porting code that uses group boxes.
QHttp no longer inherits from QNetworkProtocol . See the See the section on QNetworkProtocol 了解细节。
The old
QHttp
,
QHttpHeader
,
QHttpRequestHeader
,和
QHttpResponseHeader
classes have been renamed
Q3Http
,
Q3HttpHeader
,
Q3HttpRequestHeader
,和
Q3HttpResponseHeader
and have been moved to the
Qt3Support
库。
The QIconFactory class is no longer part of Qt. It has been replaced by the QIconEngine 类。
The QIconSet class is no longer part of Qt. It has been replaced by the QIcon 类。
The
QIconView
,
QIconViewItem
,
QIconDrag
,和
QIconDragItem
classes has been renamed
Q3IconView
,
Q3IconViewItem
,
Q3IconDrag
,和
Q3IconDragItem
and moved to the
Qt3Support
library. New Qt applications should use
QListWidget
or its base class
QListView
instead, and call
QListView::setViewMode
(
QListView::IconMode
) to obtain an "icon view" look.
见 模型/视图编程 for an overview of the new item view classes.
The
QImageDrag
class has been renamed
Q3ImageDrag
and moved to the
Qt3Support
library. In Qt 4, use
QMimeData
instead and call QMimeData::setImage() to set the image.
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The
QImageIO
class has been split into two classes:
QImageReader
and
QImageWriter
. The table below shows the correspondance between the two APIs:
| Qt 3 function | Qt 4 equivalents |
|---|---|
| QImageIO::description() | QImageWriter::text() |
| QImageIO::fileName() | QImageReader::fileName () 和 QImageWriter::fileName () |
| QImageIO::format() | QImageReader::format () 和 QImageWriter::format () |
| QImageIO::gamma() | QImageWriter::gamma () |
| QImageIO::image() | Return value of QImageReader::read () |
| QImageIO::inputFormats() | QImageReader::supportedImageFormats () |
| QImageIO::ioDevice() | QImageReader::device () 和 QImageWriter::device () |
| QImageIO::outputFormats() | QImageWriter::supportedImageFormats () |
| QImageIO::parameters() | N/A |
| QImageIO::quality() | QImageWriter::quality () |
| QImageIO::read() | QImageReader::read () |
| QImageIO::setDescription() | QImageWriter::setText () |
| QImageIO::setFileName() | QImageReader::setFileName () 和 QImageWriter::setFileName () |
| QImageIO::setFormat() | QImageReader::setFormat () 和 QImageWriter::setFormat () |
| QImageIO::setGamma() | QImageWriter::setGamma () |
| QImageIO::setIODevice() | QImageReader::setDevice () 和 QImageWriter::setDevice () |
| QImageIO::setImage() | Argument to QImageWriter::write () |
| QImageIO::setParameters() | N/A |
| QImageIO::setQuality() | QImageWriter::setQuality () |
| QImageIO::setStatus() | N/A |
| QImageIO::status() | QImageReader::error () 和 QImageWriter::error () |
| QImageIO::write() | QImageWriter::write () |
QIntCache<T> has been moved to Qt3Support . It has been replaced by QCache <int, T>.
For details, read the
section on QCache<T>
, mentally substituting
int
for
QString
.
QIntDict<T> and QIntDictIterator<T> have been moved to Qt3Support . They have been replaced by the more modern QHash <Key, T> and QMultiHash <Key, T> classes and their associated iterator classes.
When porting old code that uses QIntDict<T> to Qt 4, there are four classes that you can use:
For details, read the
section on QDict<T>
, mentally substituting
int
for
QString
.
The QIODevice class's API has been simplified to make it easier to subclass and to make it work more smoothly with asynchronous devices such as QTcpSocket and QProcess .
The following virtual functions have changed name or signature:
| Qt 3 function | 注释 |
|---|---|
| QIODevice::at () const | Renamed QIODevice::pos (). |
| QIODevice::at (Offset) | Renamed QIODevice::seek (). |
| QIODevice::open (int) | The parameter is now of type QIODevice::OpenMode . |
| QIODevice::readBlock (char *, Q_ULONG ) | QIODevice::read (char *, qint64) |
| QIODevice::writeBlock (const char *, Q_ULONG ) | QIODevice::write (const char *, qint64) |
注意: QIODevice::open ( QIODevice::OpenMode ) is no longer pure virtual.
The following functions are no longer virtual or don't exist anymore:
| QIODevice::getch () | Renamed QIODevice::getChar () and implemented in terms of QIODevice::readData (). |
| QIODevice::putch (int) | Renamed QIODevice::putChar () and implemented in terms of QIODevice::writeData (). |
| QIODevice::readAll () | Implemented in terms of QIODevice::readData (). |
| QIODevice::readLine (char *, Q_ULONG ) | Implemented in terms of QIODevice::readData () |
| QIODevice::ungetch (int) | Renamed QIODevice::ungetChar () and simulated using an internal unget buffer. |
The
IO_xxx
flags have been revised, and the protected setFlags() function removed. Most of the flags have been eliminated because errors are best handled by implementing certain functions in
QIODevice
subclasses rather than through the base classes. The file access flags, such as
IO_ReadOnly
and
IO_WriteOnly
, have been moved to the
QIODevice
class to avoid polluting the global namespace. The table below shows the correspondence between the Qt 3
IO_xxx
flags and the Qt 4 API:
| Qt 3 constant | Qt 4 equivalent |
|---|---|
| IO_Direct | Use ! QIODevice::isSequential () instead (notice the not ). |
| IO_Sequential | 使用 QIODevice::isSequential () 代替。 |
| IO_Combined | N/A |
| IO_TypeMask | N/A |
| IO_Raw | QIODevice::Unbuffered |
| IO_Async | N/A |
| IO_ReadOnly | QIODevice::ReadOnly |
| IO_WriteOnly | QIODevice::WriteOnly |
| IO_ReadWrite | QIODevice::ReadWrite |
| IO_Append | QIODevice::Append |
| IO_Truncate | QIODevice::Truncate |
| IO_Translate | QIODevice::Text |
| IO_ModeMask | N/A |
| IO_Open | 使用 QIODevice::isOpen () 代替。 |
| IO_StateMask | N/A |
| IO_Ok | N/A |
| IO_ReadError | N/A |
| IO_WriteError | N/A |
| IO_FatalError | N/A |
| IO_ResourceError | N/A |
| IO_OpenError | N/A |
| IO_ConnectError | N/A |
| IO_AbortError | N/A |
| IO_TimeOutError | N/A |
| IO_UnspecifiedError | N/A |
The QIODeviceSource class was used internally in Qt 2.x in conjunction with QImageConsumer. It was obsoleted in Qt 3.0. If you use this mechanism in your application, please submit a report to the Task Tracker on the Qt website and we will try to find a satisfactory substitute.
QLabel doesn't enable word-wrap automatically anymore when rich text is used. You can enable it by calling QLabel::setWordWrap () or by setting the wordWrap property. The reason for this change is that the old behavior was confusing to many users.
Also,
QLabel
no longer offers an
autoResize
property. Instead, you can call
QWidget::setFixedSize
() on the label, with
QLabel::sizeHint
() as the argument, whenever you change the contents of the
QLabel
.
另请参阅 Virtual Functions for a list of QLabel virtual member functions in Qt 3 that are no longer virtual in Qt 4.
In Qt 4, margins are always handled by layouts; there is no QLayout::setSupportsMargin() function anymore.
The deleteAllItems() function is now only available if
QT3_SUPPORT
is defined. If you maintain a
QList
of layout items, you can use
qDeleteAll
() to remove all the items in one go.
In Qt 3, it was possible to change the resizing behavior for layouts in top-level widgets by adjusting the layout's
resizeMode
property. In Qt 4, this property has been replaced by the
QLayout::sizeConstraint
property which provides more control over how the layout behaves when resized.
另请参阅 section on QLayoutIterator 和 section on QGLayoutIterator .
The
QLayoutIterator
class is obsoleted in Qt 4. It is available only if
QT3_SUPPORT
is defined. It can be replaced by the
QLayout::itemAt
() 和
QLayout::takeAt
() functions, which operate on indexes.
例如,若有代码像
QLayoutIterator it = layout()->iterator();
QLayoutItem *child;
while ((child = it.current()) != 0) {
if (child->widget() == myWidget) {
it.takeCurrent();
return;
++it;
}
可以把它重写成
int i = 0;
QLayoutItem *child;
while ((child = layout()->itemAt(i)) != 0) {
if (child->widget() == myWidget) {
layout()->takeAt(i);
return;
}
++i;
}
见 特性 for a list of QLineEdit properties in Qt 3 that have changed in Qt 4.
默认值
QLineEdit
's
dragEnabled
property was
true
in Qt 3. In Qt 4, the default value is
false
.
注意, QLineEdit in Qt 4 is no longer a subclass of QFrame . If you need to visually style a line edit with a frame, we recommend either using a QFrame as a container for a QLineEdit or customizing the line edit with a 样式表 .
The
QListBox
,
QListBoxItem
,
QListBoxText
,和
QListBoxPixmap
classes have been renamed
Q3ListBox
,
Q3ListBoxItem
,
Q3ListBoxText
,和
Q3ListBoxPixmap
and have been moved to the
Qt3Support
library. New Qt applications should use
QListWidget
or its base class
QListView
代替。
见 模型/视图编程 for an overview of the new item view classes.
The
QListView
,
QListViewItem
,
QCheckListItem
,和
QListViewItemIterator
classes have been renamed
Q3ListView
,
Q3ListViewItem
,
Q3CheckListItem
,和
Q3ListViewItemIterator
, and have been moved to the
Qt3Support
library. New Qt applications should use one of the following four classes instead:
QTreeView
or
QTreeWidget
for tree-like structures;
QListWidget
or the new
QListView
class for one-dimensional lists.
见 模型/视图编程 for an overview of the new item view classes.
The
QLocalFs
class is no longer part of the public Qt API. It has been renamed
Q3LocalFs
and moved to
Qt3Support
。使用
QDir
,
QFileInfo
,或
QFile
代替。
The
QMainWindow
class has been redesigned in Qt 4 to provide a more modern look and feel and more flexibility. The API has changed to reflect that. The old
QMainWindow
class has been renamed
Q3MainWindow
and moved to
Qt3Support
。见
QMainWindow
class documentation for details.
QMemArray<T> has been moved to Qt3Support . It has been replaced by the QVector <T> class.
The following table summarizes the API differences between the two classes.
| QMemArray::assign(const QMemArray<T> &) | QVector::operator=() |
| QMemArray::assign(const T *, uint) | See remark below |
| QMemArray::duplicate(const QMemArray &) | QVector::operator=() |
| QMemArray::duplicate(const T *, uint) | See remark below |
| QMemArray::setRawData(const T *, uint) | N/A |
| QMemArray::resetRawData(const T *, uint) | N/A |
| QMemArray::find(const T &, uint) | QVector::indexOf (const T &, int) |
| QMemArray::contains(const T &) | QVector::count (const T &) |
| QMemArray::sort() | qSort () |
| QMemArray::bsearch(const T &d) | qBinaryFind () |
| QMemArray::at(uint) | QVector::operator[]() |
| QMemArray::operator const T *() | QVector::constData () |
Remarks:
例如,若有代码像
QMemArray<QSize> array;
...
array.assign(data, size);
可以把它重写成
QVector<QSize> vector;
...
vector.resize(size);
qCopy(data, data + size, vector.begin());
In Qt 3, QMenuBar inherited from QFrame and QMenuData ; in Qt 4, it is a direct subclass of QWidget . Applications that provided customized menu bars will need to take advantage of the styling features described in the Qt 样式表 文档。
It is not possible to add widgets to menu bars in Qt 4.
In Qt 4, the
QMenu
class provides a menu widget that can be used in all the places where menus are used in an application. Unlike
QMenuData
,
QMenu
is designed around the concept of actions, provided by the
QAction
class, instead of the identifiers used in Qt 3.
In Qt 3, it was possible to insert widgets directly into menus by using a specific
QMenuData::insertItem()
overload. In Qt 4.2 and later, the
QWidgetAction
class can be used to wrap widgets for use in Qt 4's action-based APIs.
The QMessageBox::iconPixmap () function used to return a "const QPixmap *". In Qt 4, it returns a QPixmap .
The
QMimeSourceFactory
has been renamed
Q3MimeSourceFactory
and moved to the
Qt3Support
library. New Qt applications should use Qt 4's
资源系统
代替。
The QMovie API has been revised in Qt 4 to make it more consistent with the other Qt classes (notably QImageReader ). The table below summarizes the changes.
| Qt 3 function | Qt 4 equivalent |
|---|---|
| QMovie::connectResize() | Connect to QMovie::resized () |
| QMovie::connectStatus() | Connect to QMovie::stateChanged () |
| QMovie::connectUpdate() | Connect to QMovie::updated () |
| QMovie::disconnectResize() | Disconnect from QMovie::resized () |
| QMovie::disconnectStatus() | Disconnect from QMovie::stateChanged () |
| QMovie::disconnectUpdate() | Disconnect from QMovie::updated () |
| QMovie::finished () | 使用 QMovie::state () 代替 |
| QMovie::frameImage () | 使用 QMovie::currentImage () 代替 |
| QMovie::frameNumber () | 使用 QMovie::currentFrameNumber () 代替 |
| QMovie::framePixmap () | 使用 QMovie::currentPixmap () 代替 |
| QMovie::getValidRect() | Use frameRect() instead |
| QMovie::isNull () | 使用 QMovie::isValid () 代替 |
| QMovie::pause () | 使用 QMovie::setPaused (true) instead |
| QMovie::paused () | 使用 QMovie::state () 代替 |
| QMovie::pushData() | N/A |
| QMovie::pushSpace() | N/A |
| QMovie::restart () | 使用 QMovie::jumpToFrame (0) instead |
| QMovie::running () | 使用 QMovie::state () 代替 |
| QMovie::step () | 使用 QMovie::jumpToFrame () 和 QMovie::setPaused () 代替 |
| QMovie::step () | 使用 QMovie::jumpToNextFrame () 代替 |
| QMovie::steps() | 使用 QMovie::currentFrameNumber () 和 QMovie::frameCount () 代替 |
| QMovie::unpause () | 使用 QMovie::setPaused (false) instead |
The
QMultiLineEdit
class in Qt 3 was a convenience
QTextEdit
subclass that provided an interface compatible with Qt 2's
QMultiLineEdit
class. In Qt 4, it is called
Q3MultiLineEdit
, it inherits
Q3TextEdit
, and it is part of
Qt3Support
。使用
QTextEdit
in new code.
The QNetworkProtocol , QNetworkProtocolFactoryBase, QNetworkProtocolFactory<T>, and QNetworkOperation classes are no longer part of the public Qt API. They have been renamed Q3NetworkProtocol , Q3NetworkProtocolFactoryBase, Q3NetworkProtocolFactory<T>, and Q3NetworkOperation and have been moved to the Qt3Support 库。
In Qt 4 applications, you can use classes like QFtp and QNetworkAccessManager directly to perform file-related actions on a remote host.
QObject::children () now returns a QObjectList instead of a pointer to a QObjectList . See also the comments on QObjectList 下文。
使用 QObject::findChildren () instead of QObject::queryList(). For example:
QList<QWidget *> myWidgets = myParent->findChildren<QWidget *>();
QObject::killTimers() has been removed because it was unsafe to use in subclass. (A subclass normally doesn't know whether the base class uses timers or not.)
The
QObject::name
property has been renamed
QObject::objectName
.
QObject::objectTrees()
has been removed. If you are primarly interested in widgets, use
QApplication::allWidgets
() 或
QApplication::topLevelWidgets
().
The QObjectDictionary class is a synonym for QAsciiDict< QMetaObject >. See the section on QAsciiDict<T> .
In Qt 3, the QObjectList class was a typedef for QPtrList< QObject >. In Qt 4, it is a typedef for QList < QObject *>. See the section on QPtrList<T> .
To reimplement painter backends one previously needed to reimplement the virtual function QPaintDevice::cmd(). This function is taken out and should is replaced with the function QPaintDevice::paintEngine () and the abstract class QPaintEngine . QPaintEngine provides virtual functions for all drawing operations that can be performed on a painter backend.
bitBlt () and copyBlt() are now only compatibility functions. Use QPainter::drawPixmap () 代替。
All functions that used to be provided by the
QPaintDeviceMetrics
class have now been moved to
QPaintDevice
.
例如,若有代码像
QPaintDeviceMetrics metrics(widget);
int deviceDepth = metrics.depth();
可以把它重写成
int deviceDepth = widget->depth();
For compatibility, the old
QPaintDeviceMetrics
class has been renamed
Q3PaintDeviceMetrics
and moved to
Qt3Support
.
The QPainter class has undergone some changes in Qt 4 because of the way rectangles are drawn. In Qt 4, the result of drawing a QRect with a pen width of 1 pixel is 1 pixel wider and 1 pixel taller than in Qt 3.
For compatibility, we provide a Q3Painter class in Qt3Support that provides the old semantics. See the Q3Painter documentation for details and for the reasons why we had to make this change.
The QPainter::CoordinateMode enum has been removed in Qt 4. All clipping operations are now defined using logical coordinates and are subject to transformation operations.
The QPainter::RasterOP enum has been replaced with QPainter::CompositionMode .
In Qt 3, a QPicture could be saved in the SVG file format. In Qt 4, the SVG support is provided by the QtSvg module, which includes classes for displaying the contents of SVG files.
If you would like to generate SVG files, you can use the Q3Picture compatibility class or the QSvgGenerator class introduced in Qt 4.3.
The mask() function has been changed to return a reference to a QBitmap rather than a pointer. As a result, it is no longer possible simply to test for a null pointer when determining whether a pixmap has a mask. Instead, you need to explicitly test whether the mask bitmap is null or not.
例如,若有代码像
if (pixmap.mask())
widget->setMask(*pixmap.mask());
可以把它重写成
if (!pixmap.mask().isNull())
widget->setMask(pixmap.mask());
The
QPixmap::setOptimization()
and
QPixmap::setDefaultOptimization()
mechanism is no longer available in Qt 4.
The
QPointArray
class has been renamed
QPolygon
in Qt 4 and has undergone significant changes. In Qt 3,
QPointArray
inherited from QMemArray<
QPoint
>. In Qt 4,
QPolygon
继承自
QVector
<
QPoint
>. Everything mentioned in the
section on QMemArray<T>
apply for
QPointArray
还。
The
Qt3Support
library contains a
Q3PointArray
class that inherits from
QPolygon
and provides a few functions that existed in
QPointArray
but no longer exist in
QPolygon
. These functions include
Q3PointArray::makeArc
(),
Q3PointArray::makeEllipse
(),和
Q3PointArray::cubicBezier
(). In Qt 4, we recommend that you use
QPainterPath
for representing arcs, ellipses, and Bezier curves, rather than
QPolygon
.
The
QPolygon::setPoints
() 和
QPolygon::putPoints
() functions return
void
in Qt 4. The corresponding Qt 3 functions returned a
bool
indicating whether the array was successfully resized or not. This can now be checked by checking
QPolygon::size
() after the call.
For most purposes, QPopupMenu has been replaced by QMenu in Qt 4. For compatibility with older applications, Q3PopupMenu provides the old API and features that are specific to pop-up menus. Note that, when using Q3PopupMenu , the menu's actions must be Q3Action 。
In Qt 3, it was common practice to add entries to pop-up menus using the insertItem() function, maintaining identifiers for future use; for example, to dynamically change menu items. In Qt 4, menu entries are completely represented by actions for consistency with other user interface components, such as toolbar buttons. Create new menus with the QMenu class, and use the overloaded QMenu::addAction () functions to insert new entries. If you need to manage a set of actions created for a particular menu, we suggest that you construct a QActionGroup and add them to that.
The 主窗口范例 provided show how to use Qt's action system to construct menus, toolbars, and other common user interface elements.
The QPrinter class now expects printing to be set up from a QPrintDialog .
The QProcess class has undergone major improvements in Qt 4. It now inherits QIODevice , which makes it possible to combine QProcess 采用 QTextStream 或 QDataStream .
The old
QProcess
class has been renamed
Q3Process
and moved to the
Qt3Support
库。
The
QProgressBar
API has been significantly improved in Qt 4. The old
QProgressBar
API is available as
Q3ProgressBar
在
Qt3Support
库。
The
QProgressDialog
API has been significantly improved in Qt 4. The old
QProgressDialog
API is available as
Q3ProgressDialog
在
Qt3Support
库。
见 特性 for a list of QProgressDialog properties in Qt 3 that have changed in Qt 4.
The
QPtrCollection<T>
abstract base class has been renamed
Q3PtrCollection
<T> moved to the
Qt3Support
library. There is no direct equivalent in Qt 4.
见 容器类 for a list of Qt 4 containers.
QPtrDict<T>
and
QPtrDictIterator<T>
have been renamed
Q3PtrDict
<T> 和
Q3PtrDictIterator
<T> and have been moved to the
Qt3Support
library. They have been replaced by the more modern
QHash
<Key, T> and
QMultiHash
<Key, T> classes and their associated iterator classes.
When porting old code that uses Q3PtrDict <T> to Qt 4, there are four classes that you can use:
(You can naturally use other types than
void *
for the key type, e.g.
QWidget *
)。
To port
Q3PtrDict
<T> to Qt 4, read the
section on QDict<T>
, mentally substituting
void *
for
QString
.
QPtrList<T>, QPtrListIterator<T>, and QPtrListStdIterator<T> have been moved to the Qt3Support library. They have been replaced by the more modern QList and QLinkedList classes and their associated iterator classes.
When porting to Qt 4, you have the choice of using QList <T> or QLinkedList <T> as alternatives to QValueList<T>. QList <T> has an index-based API and provides very fast random access (QList::operator[]), whereas QLinkedList <T> has an iterator-based API.
The following table summarizes the API differences between QPtrList<T> and QList <T *>:
| QPtrList function | QList equivalent |
|---|---|
| QPtrList::contains(const T *) | QList::count (T *) |
| QPtrList::containsRef(const T *) | QList::count (T *) |
| QPtrList::find(const T *) | See remark below |
| QPtrList::findRef(const T *) | See remark below |
| QPtrList::getFirst() | QList::first () |
| QPtrList::getLast() | QList::last () |
| QPtrList::inSort(const T *) | N/A |
| QPtrList::remove(const T *) | QList::removeAll (T *) |
| QPtrList::remove(uint) | QList::removeAt (int) |
| QPtrList::removeNode(QLNode *) | N/A |
| QPtrList::removeRef(const T *) | QList::removeAll (T *) |
| QPtrList::sort() | See remark below |
| QPtrList::takeNode(QLNode *) | N/A |
| QPtrList::toVector(QGVector *) | See remark below |
Remarks:
例如,若有代码像
QPtrList<QWidget> list;
...
QPtrVector<QWidget> vector;
list.toVector(&vector);
可以把它重写成
QList<QWidget *> list;
...
QVector<QWidget *> vector;
vector.resize(list.size());
qCopy(list.begin(), list.end(), vector.begin());
bool
that indicates whether the element was removed or not. The corresponding
QList
functions return
void
. You can achieve the same result by calling
QList::isEmpty
() before attempting to remove an item.
If you use QPtrList's auto-delete feature (by calling QPtrList::setAutoDelete(true)), you need to do some more work. You have two options: Either you call
delete
yourself whenever you remove an item from the container, or you can use
QList
<T> instead of
QList
<T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call
delete
.
The following table summarizes the idioms that you need to watch out for if you want to call
delete
yourself.
| QPtrList idiom | QList idiom |
|---|---|
list.replace(index, value); |
delete list[index]; list[index] = value; |
list.removeFirst();
|
delete list.takeFirst(); |
list.removeLast();
|
delete list.takeLast(); |
list.remove(index);
|
delete list.takeAt(index); |
list.remove(value);
|
int i = list.indexOf(value); if (i != -1) delete list.takeAt(i); |
list.remove();
(removes the current item) |
QMutableListIterator<T *> i; ... delete i.value(); i.remove(); |
list.clear();
(also called from QPtrList's destructor) |
while (!list.isEmpty()) delete list.takeFirst(); In 99% of cases, the following idiom also works: qDeleteAll(list); list.clear();
However, it may lead to crashes if
|
Be aware that QPtrList's destructor automatically calls clear(). If you have a QPtrList data member in a custom class and use the auto-delete feature, you will need to call
delete
on all the items in the container from your class destructor to avoid a memory leak.
QPtrList had the concept of a "current item", which could be used for traversing the list without using an iterator. When porting to Qt 4, you can use the Java-style QListIterator <T *> (or QMutableListIterator <T *>) class instead. The following table summarizes the API differences:
| QPtrList function | QListIterator equivalent |
|---|---|
| QPtrList::at() | N/A |
| QPtrList::current() | QMutableListIterator::value () |
| QPtrList::currentNode() | N/A |
| QPtrList::findNext(const T *) | QListIterator::findNext (const T *) |
| QPtrList::findNextRef(const T *) | QListIterator::findNext (const T *) |
| QPtrList::first() | QPtrList::toFront() |
| QPtrList::last() | QPtrList::toBack() |
| QPtrList::next() | QPtrList::next() |
| QPtrList::prev() | QPtrList::previous() |
| QPtrList::remove() | QMutableListIterator::remove () |
| QPtrList::take() | QMutableListIterator::remove () |
注意, QListIterator has a different way of iterating than QPtrList. A typical loop with QPtrList looks like this:
QPtrList<QWidget> list; ... while (list.current() != 0) { do_something(list.current()); list.next(); }
Here's the equivalent QListIterator loop:
QList<QWidget *> list; ... QListIterator<QWidget *> i(list); while (i.hasNext()) do_something(i.next());
Finally, QPtrListIterator<T> must also be ported. There are no fewer than four iterator classes that can be used as a replacement: QList::const_iterator , QList::iterator , QListIterator ,和 QMutableListIterator . The most straightforward class to use when porting is QMutableListIterator <T *> (if you modify the list through the iterator) or QListIterator <T *> (if you don't). The following table summarizes the API differences:
| QPtrListIterator function | Qt 4 equivalent |
|---|---|
| QPtrListIterator::atFirst() |
!
QListIterator::hasPrevious
() (notice the
!
)
|
| QPtrListIterator::atLast() |
!
QListIterator::hasNext
() (notice the
!
)
|
| QPtrListIterator::count() | QList::count () 或 QList::size () |
| QPtrListIterator::current() | QMutableListIterator::value () |
| QPtrListIterator::isEmpty() | QList::isEmpty () |
| QPtrListIterator::toFirst() | QListIterator::toFront () |
| QPtrListIterator::toLast() | QListIterator::toBack () |
| QPtrListIterator::operator() | QMutableListIterator::value () |
| QPtrListIterator::operator*() | QMutableListIterator::value () |
Again, be aware that QListIterator has a different way of iterating than QPtrList. A typical loop with QPtrList looks like this:
QPtrList<QWidget> list; ... QPtrListIterator<QWidget> i; while (i.current() != 0) { do_something(i.current()); i.next(); }
Here's the equivalent QListIterator loop:
QList<QWidget *> list; ... QListIterator<QWidget *> i(list); while (i.hasNext()) do_something(i.next());
Finally, QPtrListStdIterator<T> must also be ported. This is easy, because QList also provides STL-style iterators ( QList::iterator and QList::const_iterator ).
QPtrQueue has been moved to the Qt3Support library. It has been replaced by the more modern QQueue 类。
The following table summarizes the differences between QPtrQueue<T> and QQueue <T *>:
| QPtrQueue function | QQueue equivalent |
|---|---|
| QPtrQueue::autoDelete() | See discussion below |
| QPtrQueue::count() | QQueue::count () 或 QQueue::size () (equivalent) |
| QPtrQueue::current() | QQueue::head () |
| QPtrQueue::remove() | QQueue::dequeue () |
| QPtrQueue::setAutoDelete() | See discussion below |
If you use QPtrQueue's auto-delete feature (by calling QPtrQueue::setAutoDelete(true)), you need to do some more work. You have two options: Either you call
delete
yourself whenever you remove an item from the container, or you can use
QQueue
<T> instead of
QQueue
<T *> (i.e. store values directly instead of pointers to values). Here, we will show when to call
delete
.
| QPtrQueue idiom | QQueue idiom |
|---|---|
queue.dequeue();
|
delete queue.dequeue(); |
queue.remove();
|
delete queue.dequeue(); |
queue.clear();
(also called from QPtrQueue's destructor) |
while (!queue.isEmpty()) delete queue.dequeue(); In 99% of cases, the following idiom also works: qDeleteAll(queue); queue.clear();
However, it may lead to crashes if
|
QPtrStack has been moved to the Qt3Support library. It has been replaced by the more modern QStack 类。
The following table summarizes the differences between QPtrStack<T> and QStack <T *>:
| QPtrStack function | QStack equivalent |
|---|---|
| QPtrStack::autoDelete() | See discussion below |
| QPtrStack::count() | QStack::count () 或 QStack::size () (equivalent) |
| QPtrStack::current() | QStack::top () |
| QPtrStack::remove() | QStack::pop () |
| QPtrStack::setAutoDelete() | See discussion below |
If you use QPtrStack's auto-delete feature (by calling QPtrStack::setAutoDelete(true)), you need to do some more work. You have two options: Either you call
delete
yourself whenever you remove an item from the container, or you can use
QStack
<T> instead of
QStack
<T *> (i.e. store values directly instead of pointers to values). Here, we will show when to call
delete
.
| QPtrStack idiom | QStack idiom |
|---|---|
stack.pop();
|
delete stack.pop(); |
stack.remove();
|
delete stack.pop(); |
stack.clear();
(also called from QPtrStack's destructor) |
while (!stack.isEmpty()) delete stack.pop(); In 99% of cases, the following idiom also works: qDeleteAll(stack); stack.clear();
However, it may lead to crashes if
|
QPtrVector<T> has been moved to Qt3Support . It has been replaced by the more modern QVector 类。
When porting to Qt 4, you can use QVector <T *> as an alternative to QPtrVector<T>. The APIs of QPtrVector<T> and QVector <T *> are somewhat similar. The main issue is that QPtrVector supports auto-delete whereas QVector doesn't.
The following table summarizes the API differences between the two classes:
| QPtrVector function | QVector equivalent |
|---|---|
| QPtrVector::autoDelete() | See discussion below |
| QPtrVector::bsearch(const T *) | qBinaryFind () |
| QPtrVector::contains(const T *) | QVector::count (T *) |
| QPtrVector::containsRef(const T *) | QVector::count (T *) |
| QPtrVector::count() | See remark below |
| QPtrVector::insert(uint, T *) | See remark below |
| QPtrVector::isNull() | N/A |
| QPtrVector::remove(uint) | See remark below |
| QPtrVector::setAutoDelete() | See discussion below |
| QPtrVector::sort() | qSort () |
| QPtrVector::take(uint) | See remark below |
| QPtrVector::toList(QGList *) | QList::QList (const QVector &) |
Remarks:
vect[i] = ptr
to set a
QVector
item to a particular value.
vect[i] = 0
to set a
QVector
item to 0.
例如,若有代码像
int numValidItems = vect.count();
可以把它重写成
int numValidItems = vect.size() - vect.count(0);
若使用
QVector
's auto-delete feature (by calling QVector::setAutoDelete(true)), you need to do some more work. You have two options: Either you call
delete
yourself whenever you remove an item from the container, or you use
QVector
<T> instead of
QVector
<T *> (i.e. store values directly instead of pointers to values). Here, we'll see when to call
delete
.
The following table summarizes the idioms that you need to watch out for if you want to call
delete
yourself.
| QPtrVector idiom | QVector idiom |
|---|---|
vect.insert(i, ptr); |
delete vect[i]; vect[i] = ptr; |
vect.remove(i);
|
delete vect[i]; vect[i] = 0; |
T *ptr = vect.take(i); |
T *ptr = vect[i]; vect[i] = 0; |
vect.resize(n)
|
while (n > vect.size()) vect.append(0); while (n < vect.size() { T *ptr = vect.last(); vect.remove(vect.size() - 1); delete ptr; } |
vect.clear();
(also called from QPtrVector's destructor) |
for (int i = 0; i < vect.size(); ++i) T *ptr = vect[i]; vect[i] = 0; delete ptr; } In 99% of cases, the following idiom also works: qDeleteAll(vect); vect.clear();
However, it may lead to crashes if
|
Be aware that QPtrVector's destructor automatically calls clear(). If you have a QPtrVector data member in a custom class and use the auto-delete feature, you will need to call
delete
on all the items in the container from your class destructor to avoid a memory leak.
见 特性 for a list of QPushButton properties in Qt 3 that have changed in Qt 4.
In Qt 3, various "range control" widgets (
QDial
,
QScrollBar
,
QSlider
, and QSpin) inherited from both
QWidget
and
QRangeControl
.
In Qt 4,
QRangeControl
has been replaced with the new
QAbstractSlider
and
QAbstractSpinBox
classes, which inherit from
QWidget
and provides similar functionality. Apart from eliminating unnecessary multiple inheritance, the new design allows
QAbstractSlider
to provide signals, slots, and properties.
The old
QRangeControl
class has been renamed
Q3RangeControl
and moved to the
Qt3Support
library, together with the (undocumented)
QSpinWidget
类。
若使用
QRangeControl
as a base class in your application, you can switch to use
QAbstractSlider
or
QAbstractSpinBox
代替。
例如,若有代码像
class VolumeControl : public QWidget, public QRangeControl
{
...
protected:
void valueChange() {
update();
emit valueChanged(value());
}
void rangeChange() {
update();
}
void stepChange() {
update();
}
};
可以把它重写成
class VolumeControl : public QAbstractSlider
{
...
protected:
void sliderChange(SliderChange change) {
update();
if (change == SliderValueChange)
emit valueChanged(value());
}
};
The search() and searchRev() functions have been renamed to indexIn() and lastIndexIn() respectively.
The following changes have been made to QRegion in Qt 4:
见 特性 for a list of QScrollBar properties in Qt 3 that have changed in Qt 4.
The
QScrollView
class has been renamed
Q3ScrollView
and moved to the
Qt3Support
library. It has been replaced by the
QAbstractScrollArea
and
QScrollArea
类。
Note that Qt 4 in general uses the QScrollArea::widget () function where Qt 3 used QScrollView::viewport(). The rationale for this is that it is no longer possible to draw directly on a scroll area. The QScrollArea::widget () function returns the widget set on the scroll area.
QScrollView
was designed to work around the 16-bit limitation on widget coordinates found on most window systems. In Qt 4, this is done transparently for
all
widgets, so there is no longer a need for such functionality in
QScrollView
. For that reason, the new
QAbstractScrollArea
and
QScrollArea
classes are much more lightweight, and concentrate on handling scroll bars.
The
QServerSocket
class has been renamed
Q3ServerSocket
and moved to the
Qt3Support
library. In Qt 4, it has been replaced by
QTcpServer
.
采用 Q3ServerSocket , connections are accepted by reimplementing a virtual function ( Q3ServerSocket::newConnection ()). With QTcpServer , on the other hand, you don't need to subclass. Instead, simply connect to the QTcpServer::newConnection () 信号。
The QSettings class has been rewritten to be more robust and to respect existing standards (e.g., the INI file format). The API has also been extensively revised. The old API is still provided when Qt 3 support is enabled.
Since the format and location of settings have changed between Qt 3 and Qt 4, the Qt 4 version of your application won't recognize settings written using Qt 3.
The
QShared
class has been obsoleted by the more powerful
QSharedData
and
QSharedDataPointer
as a means of creating custom implicitly shared classes. It has been renamed
Q3Shared
and moved to the
Qt3Support
库。
An easy way of porting to Qt 4 is to include this class into your project and to use it instead of
QShared
:
struct Shared { Shared() : count(1) {} void ref() { ++count; } bool deref() { return !--count; } uint count; };
If possible, we recommend that you use QSharedData and QSharedDataPointer instead. They provide thread-safe reference counting and handle all the reference counting behind the scenes, eliminating the risks of forgetting to increment or decrement the reference count.
The QSignal class has been renamed to Q3Signal and moved to the Qt3Support library. The preferred approach is to create your own QObject subclass with a signal that has the desired signature. Alternatively, you can call QMetaObject::invokeMethod () if you want to invoke a slot.
QSimpleRichText has been obsoleted by QTextDocument . It has been renamed Q3SimpleRichText and moved to the Qt3Support 库。
Previously, you would do the following with Q3SimpleRichText :
// Declare the object QSimpleRichText richText(text, font); // Set the width of the paragraph to w richText.setWidth(w); // Or set a reasonable default size richText.adjustSize(); // Query for its used size int width = richText.widthUsed(); int height = richText.height(); // Draw richText.draw(painter, x, y, clipRect, colorGroup);
However, with QTextDocument , you use the following code instead:
// Declare the object QTextDocument doc; // If text is rich text, use setHtml() doc.setHtml(text); // Otherwise, use setPlainText() doc.setPlainText(text); // Set the width of the paragraph of text to w doc.setTextWidth(w); // Query for the used size int width = doc.idealWidth(); int height = doc.size().height(); // Draw painter.translate(x, y); doc.drawContents(painter, clipRect); // If you have a palette/colorgroup you can draw using lower-level functions: QAbstractTextDocumentLayout::PaintContext context; context.palette = myPalette; doc.documentLayout()->draw(painter, context);
见 富文本处理 for an overview of the Qt 4 rich text classes.
The QSlider::sliderStart() and QSlider::sliderRect() functions have been removed.
The slider's rect can now be retrieved using the code snippet below:
QSlider *slider; slider->style()->subControlRect(CC_Slider, sliderOption, SC_SliderHandle, slider);
In addition, the direction of a vertical QSlider has changed, i.e. the bottom is now the minimum, and the top the maximum. You can use the QAbstractSlider::invertedAppearance property to control this behavior.
见 特性 for a list of QSlider properties in Qt 3 that have changed in Qt 4.
The
QSocket
class has been renamed
Q3Socket
and moved to the
Qt3Support
library. In Qt 4, it has been replaced by the
QTcpSocket
class, which inherits most of its functionality from
QAbstractSocket
.
The
QSocketDevice
class has been renamed
Q3SocketDevice
and moved to the
Qt3Support
library. In Qt 4, there is no direct equivalent to
Q3SocketDevice
:
QAbstractSocketEngine
internal class that offers a low-level socket API similar to
Q3SocketDevice
. Should the need for such functionality arise in Qt 4 applications, we will consider making this class public in a future release.
The QSortedList <T> class has been deprecated since Qt 3.0. In Qt 4, it has been moved to the Qt3Support 库。
In new code, we recommend that you use QList <T> instead and use qSort () to sort the items.
The function setResizeMode() has been moved into Qt3Support . Set the stretch factor in the widget's size policy to get equivalent functionality.
The obsolete function drawSplitter() has been removed. Use QStyle::drawPrimitive () to acheive similar functionality.
见 特性 for a list of QSpinBox properties in Qt 3 that have changed in Qt 4.
The
QSqlCursor
class has been renamed
Q3SqlCursor
and moved to the
Qt3Support
library. In Qt 4, you can use
QSqlQuery
,
QSqlQueryModel
,或
QSqlTableModel
, depending on whether you want a low-level or a high-level interface for accessing databases.
见 QtSql Module for an overview of the new SQL classes.
QSqlDatabase is now a smart pointer that is passed around by value. Simply replace all QSqlDatabase pointers by QSqlDatabase 对象。
The
QSqlEditorFactory
class has been renamed
Q3SqlEditorFactory
and moved to
Qt3Support
.
见 QtSql Module for an overview of the new SQL classes.
The enum
类型
was renamed to
ErrorType
, The values were renamed as well:
The QSqlFieldInfo class has been moved to Qt3Support . Its functionality is now provided by the QSqlField 类。
见 QtSql Module for an overview of the new SQL classes.
The
QSqlForm
class has been renamed
Q3SqlForm
and moved to the
Qt3Support
库。
见 QtSql Module for an overview of the new SQL classes.
The
QSqlPropertyMap
class has been renamed
Q3SqlPropertyMap
moved to the
Qt3Support
库。
见 QtSql Module for an overview of the new SQL classes.
QSqlQuery::prev () was renamed to QSqlQuery::previous (). QSqlQuery::prev () remains, but it just calls previous(). QSqlQuery no longer has any virtual methods, i.e., exec(), value(), seek(), next(), prev(), first(), last(), and the destructor are no longer virtual.
QSqlRecord behaves like a vector now, QSqlRecord::insert () will actually insert a new field instead of replacing the existing one.
The QSqlRecordInfo class has been moved to Qt3Support . Its functionality is now provided by the QSqlRecord 类。
见 QtSql Module for an overview of the new SQL classes.
The
QSqlSelectCursor
class has been renamed
Q3SqlSelectCursor
and moved to the
Qt3Support
库。
见 QtSql Module for an overview of the new SQL classes.
The
QStoredDrag
class has been renamed
Q3StoredDrag
and moved to the
Qt3Support
library. In Qt 4, use
QMimeData
instead and call
QMimeData::setData
() to set the data.
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The QStrList and QStrIList convenience classes have been deprecated since Qt 2.0. In Qt 4, they have been moved to the Qt3Support library. If you used any of these, we recommend that you use QStringList or QList < QByteArray > 代替。
The QStrVec and QStrIVec convenience classes have been deprecated since Qt 2.0. In Qt 4, they have been moved to Qt3Support . If you used any of these, we recommend that you use QStringList or QList < QByteArray > 代替。
Here are the main issues to be aware of when porting QString to Qt 4:
例如,若有代码像
str1 = QString::null;
if (str2 == QString::null)
do_something(QString::null);
可以把它重写成
str1.clear();
if (str2.isNull())
do_something(QString());
In new code, we recommend that you don't rely on the distinction between a null string and a (non-null) empty string. See null 和空字符串之间的区别 了解细节。
const char *
. For consistency,
QString::utf8
() 和
QString::local8Bit
(), which already returned a
QByteArray
(actually a
QCString
), have been renamed
QString::toUtf8
() 和
QString::toLocal8Bit
().
To obtain a
const char *
pointer to ASCII or Latin-1 data, use
QString::toAscii
() 或
QString::toLatin1
() to obtain a
QByteArray
containing the data, then call
QByteArray::constData
() to access the character data directly. Note that the pointer returned by this function is only valid for the lifetime of the byte array; you should avoid taking a pointer to the data contained in temporary objects.
QString greeting = "Hello"; const char *badData = greeting.toAscii().constData(); // data is invalid QByteArray asciiData = greeting.toAscii(); const char *goodData = asciiData.constData();
在以上范例中,
goodData
pointer is valid for the lifetime of the
asciiData
byte array. If you need to keep a copy of the data in a non-Qt data structure, use standard C memory allocation and string copying functions to do so
before
destroying the byte array.
str.at(0) = 'X';
will no longer compile. Instead, use QString::operator[]:
str[0] = 'X';
bool
parameter that specified case sensitivity. In Qt 4, in the interest of code readability and maintainability, the
bool
parameters have been replaced by the
Qt::CaseSensitivity
enum, which can take the values
Qt::CaseSensitive
and
Qt::CaseInsensitive
.
例如,若有代码像
if (url.startsWith("http:", false))
...
可以把它重写成
if (url.startsWith("http:", Qt::CaseInsensitive))
...
例如,若有代码像
str.setExpand(32, '$');
可以把它重写成
str[32] = '$';
QT_NO_ASCII_CAST
and
QT_NO_CAST_ASCII
macros have been renamed
QT_NO_CAST_TO_ASCII
and
QT_NO_CAST_FROM_ASCII
,分别。
NULL
in order to determine whether strings are empty are no longer allowed. Use
isEmpty()
代替。
QStringList now inherits from QList < QString > and can no longer be converted to a QValueList< QString >. Since QValueList inherits QList a cast will work as expected.
This change implies some API incompatibilities for QStringList . For example, at() returns the string, not an iterator. See the section on QValueList 了解细节。
静态 QStringList::split () function for splitting strings into lists of smaller strings has been replaced by QString::split (), which returns a QStringList .
The QStyle API has been overhauled and improved. Most of the information on why this change was done is described in the QStyle overview .
由于 QStyle is mostly used internally by Qt's widgets and styles and since it is not essential to the good functioning of an application, there is no compatibility path. This means that we have changed many enums and functions and the qt3to4 porting tool will not change much in your qstyle code. To ease the pain, we list some of the major changes here.
QStyleOption has taken on a more central role and is no longer an optional argument, please see the QStyleOption 文档编制,了解更多信息。
The QStyle::StyleFlags have been renamed QStyle::StateFlags and are now prefixed State_ instead of Style_, in addition the Style_ButtonDefault flag has moved to QStyleOptionButton .
The QStyle::PrimitiveElement enumeration has undergone extensive change. Some of the enums were moved to QStyle::ControlElement , some were removed and all were renamed. This renaming is not done by the qt3to4 porting tool, so you must do it yourself. The table below shows how things look now.
The QStyle::drawControlMask() and QStyle::drawComplexControlMask() functions have been removed. They are replaced with a style hint.
The QStyle::drawItem() overloads that took both a pixmap and a string have been removed. Use QStyle::drawItemText () 和 QStyle::drawItemPixmap () 直接。
The QStyle::itemRect() overload that took both a pixmap and a string is also removed, use either QStyle::itemTextRect () 或 QStyle::itemPixmapRect () 代替。
The QStyleSheet and QStyleSheetItem classes have been renamed Q3StyleSheet and Q3StyleSheetItem , and have been moved to the Qt3Support 库。
见 富文本处理 for an overview of the Qt 4 rich text classes, and Qt 样式表 for a description of CSS-like style sheet support in Qt 4.2 and above.
The
QSyntaxHighlighter
class from Qt 3 has been renamed
Q3SyntaxHighlighter
and moved to the
Qt3Support
library. Since Qt 4.1, it has been replaced by a new
QSyntaxHighlighter
class based on Qt 4's new rich text engine.
见 特性 for a list of QTabBar properties in Qt 3 that have changed in Qt 4.
The
QTabDialog
class is no longer part of the public Qt API. It has been renamed
Q3TabDialog
and moved to
Qt3Support
. In Qt 4 applications, you can easily obtain the same result by combining a
QTabWidget
采用
QDialog
and provide
QPushButton
s yourself.
另请参阅 dialogs/tabdialog example, which shows how to implement tab dialogs in Qt 4.
见 特性 for a list of QTabWidget properties in Qt 3 that have changed in Qt 4.
The
QTable
,
QTableItem
,
QComboTableItem
,
QCheckTableItem
,和
QTableSelection
classes have been renamed
Q3Table
,
Q3TableItem
,
Q3ComboTableItem
,
Q3CheckTableItem
,和
Q3TableSelection
and moved to the
Qt3Support
library. New Qt applications should use the new
QTableWidget
or
QTableView
class instead.
Some of these classes behave differently with respect to the way they handle
NULL
pointers. For example,
Q3TableItem::setPixmap
() no longer accepts
NULL
or 0 to indicate that the item should contain a null pixmap; in this case, a null pixmap should be constructed and passed explicitly to the function.
见 模型/视图编程 for an overview of the new item view classes.
The loadCharmap() and loadCharmapFromFile() functions are no longer available in Qt 4. You need to create your own codec if you want to create a codec based on a POSIX2 charmap definition.
The
QTextDrag
class has been renamed
Q3TextDrag
and moved to the
Qt3Support
library. In Qt 4, use
QMimeData
instead and call
QMimeData::setText
() to set the data.
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The old QTextEdit and QTextBrowser classes have been renamed Q3TextEdit and Q3TextBrowser , and have been moved to Qt3Support . The new QTextEdit and QTextBrowser have a somewhat different API.
The
QTextEdit::setWrapPolicy()
function has been renamed to
setWordWrapMode()
和
QTextEdit::setWrapColumnOrWidth()
function has been renamed to
setLineWrapColumnOrWidth()
。
Q3TextEdit::setWrapPolicy
() 和
Q3TextEdit::setWrapColumnOrWidth
() still provide this functionality in the
Q3TextEdit
类。
见 富文本处理 for an overview of the Qt 4 rich text classes.
The QTextIStream convenience class is no longer provided in Qt 4. Use QTextStream directly instead.
The QTextOStream convenience class is no longer provided in Qt 4. Use QTextStream directly instead.
The undocumented
QTextOStreamIterator
class has been removed from the Qt library. If you need it in your application, feel free to copy the source code from the Qt 3
<qtl.h>
头文件。
QTextStream has undergone a number of API and implementation enhancements, and some of the changes affect QTextStream 's behavior:
endl
or
flush
if you need
QTextStream
to flush its write buffer. The stream is flushed automatically if
QTextStream
is deleted or when the device is closed.
QIODevice::Text
mode (formerly
IO_Translate
).
注意,当使用 QTextStream 在 QFile in Qt 4, calling QIODevice::reset () on the QFile 将不会有期望结果,因为 QTextStream now buffers the file. Use the QTextStream::seek () 函数代替。
The
QTextView
class has been renamed
Q3TextView
and moved to the
Qt3Support
库。
The QTimeEdit class in Qt 4 is a convenience class based on QDateTimeEdit . The old class has been renamed Q3TimeEdit and moved to the Qt3Support 库。
见
Virtual Functions
for a list of
QTimeEdit
virtual member functions in Qt 3 that are no longer virtual in Qt 4.
Windows restricts the granularity of timers, but starting with Qt 4, we emulate a finer time resolution. On Windows XP we use the multimedia timer API, which gives us 1 millisecond resolution for QTimer .
Note that Windows 2000 has a lower timer resolution, and that code relying on underlying system timer restrictions encounters no such limitations using Qt 4 (e.g., setting an interval of 0 millisecond results in Qt occupying all of the processor time when no GUI events need processing).
The old
QToolBar
class, which worked with the old
QMainWindow
and
QDockArea
classes and inherited from
QDockWindow
, has been renamed
Q3ToolBar
and moved to
Qt3Support
. Note that, when using
Q3ToolBar
, the toolbar's actions must be
Q3Action
。
Use the new QToolBar class in new applications.
注意: Q3ToolBar 's horizontallyStretchable property can be achieved in QToolBar with 大小策略 .
见 特性 for a list of QToolButton properties in Qt 3 that have changed in Qt 4.
Note that many of the properties that could previously be set in the constructor must now be set separately.
The QToolTip::setGloballyEnabled() function no longer exists. Tooltips can be disabled by installing an event filter on qApp (the unique QApplication object) to block events of type QEvent::ToolTip .
The
QUriDrag
class has been renamed
Q3UriDrag
and moved to the
Qt3Support
library. In Qt 4, use
QMimeData
instead and call QMimeData::setUrl() to set the URL.
见 Porting to Qt 4 - Drag and Drop for a comparison between the drag and drop APIs in Qt 3 and Qt 4.
The QUrl class has been rewritten from scratch in Qt 4 to be more standard-compliant. The old QUrl class has been renamed Q3Url and moved to the Qt3Support 库。
新的 QUrl class provides an extensive list of compatibility functions to ease porting from Q3Url to QUrl . A few functions require you to change your code:
int
parameter specifies a combination of
formatting options
.
The
QUrlOperator
class is no longer part of the public Qt API. It has been renamed Q3UrlOperator and moved to
Qt3Support
.
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
,和
QNetworkAccessManager
文档编制进一步了解细节。
The QValueList<T> class has been replaced by QList <T> 和 QLinkedList <T> in Qt 4. As a help when porting older Qt applications, the Qt3Support library contains a QValueList<T> class implemented in terms of the new QLinkedList <T>. Similarly, it contains QValueListIterator<T> and QValueListConstIterator<T> classes implemented in terms of QLinkedList <T>::iterator and QLinkedList <T>::const_iterator.
When porting to Qt 4, you have the choice of using QList <T> or QLinkedList <T> as alternatives to QValueList<T>. QList <T> has an index-based API and provides very fast random access (QList::operator[]), whereas QLinkedList <T> has an iterator-based API.
Here's a list of problem functions:
例如,若有代码像
for (QValueList<T>::iterator i = list.fromLast(); i != list.begin(); --i)
do_something(*i);
可以把它重写成
QLinkedList<T>::iterator i = list.end();
while (i != list.begin()) {
--i; // decrement i before using it
do_something(*i);
}
The QValueVector<T> class has been replaced by QVector <T> in Qt 4. As a help when porting older Qt applications, the Qt3Support library contains a Q3ValueVector <T> class implemented in terms of the new QVector <T>.
When porting from QValueVector<T> to QVector <T>, you might run into the following incompatibilities:
bool *
that is set to true if the index is within bounds. This functionality doesn't exist in
QVector
; instead, check the index against
QVector::size
() yourself.
见 容器类 for an overview of the Qt 4 container classes.
Some changes to the rest of the Qt library have implications on QVariant :
QVariant::ColorGroup
enum value is defined only if
QT3_SUPPORT
有定义。
QVariant::IconSet
enum value has been renamed
QVariant::Icon
.
QVariant::CString
enum value is now a synonym for
QVariant::ByteArray
.
Also, the QVariant (bool, int) constructor has been replaced by QVariant (bool). Old code like QVariant (true, 0) should be replaced with QVariant (true); otherwise, the QVariant (int, void *) overload might accidentally be triggered.
很多 QVariant 's convenience functions in Qt 3, such as toColor() and toKeySequence(), have been removed to enable QVariant to be part of the QtCore 模块。 QVariant is still able to hold values of these types.
Types which are not supported by any of the QVariant constructors can be stored as variants with the QVariant::fromValue () function. Types with no suitable convenience function for unpacking can be retrieved with the QVariant::value () function or passed directly to classes that implement the QVariant() operator.
| Qt 3 function | Qt 4 function |
|---|---|
| toBitmap () | QVariant::value () |
| toBrush () | QVariant::value () |
| toColorGroup () | 使用 QVariant::value () 采用 QPalette 代替。 |
| toColor () | QVariant::value () |
| toCString () | QVariant::toByteArray () |
| toCursor () | QVariant::value () |
| toFont () | QVariant::value () |
| toIconSet () | 使用 QVariant::value () 采用 QIcon 代替。 |
| toImage () | QVariant::value () |
| toKeySequence () | QVariant::value () |
| toPalette () | QVariant::value () |
| toPen () | QVariant::value () |
| toPixmap () | QVariant::value () |
| toPointArray () | QVariant::value () |
| toRegion () | QVariant::value () |
| toSizePolicy () | QVariant::value () |
见 QVariant::Type enum for a list of types supported by QVariant .
The
QVBox
class is now only available as
Q3VBox
in Qt 4. You can achieve the same result as
QVBox
by creating a
QWidget
with a vertical layout:
例如,若有代码像
QVBox *vbox = new QVBox; QPushButton *child1 = new QPushButton(vbox); QPushButton *child2 = new QPushButton(vbox);
可以把它重写成
QWidget *vbox = new QWidget; QPushButton *child1 = new QPushButton; QPushButton *child2 = new QPushButton; QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(child1); layout->addWidget(child2); vbox->setLayout(layout);
Note that child widgets are not automatically placed into the widget's layout; you will need to manually add each widget to the QVBoxLayout .
The
QVGroupBox
class has been renamed
Q3VGroupBox
and moved to the
Qt3Support
library. Qt 4 does not provide a specific replacement class for
QVGroupBox
since
QGroupBox
is designed to be a generic container widget. As a result, you need to supply your own layout for any child widgets.
见 #QGroupBox for more information about porting code that uses group boxes.
The
QWhatsThis
class has been redesigned in Qt 4. The old
QWhatsThis
class is available as
Q3WhatsThis
in
Qt3Support
.
Widget background painting has been greatly improved, supporting flicker-free updates and making it possible to have semi-transparent widgets. This renders the following background handling functions obsolete:
noErase
boolean parameter is gone
Sample code on how to do obtain similar behavior from Qt 4, previously handled by some of the above functions can be found in the Qt 3 Support Members for QWidget 页面。
A widget now receives change events in its QWidget::changeEvent () handler. This makes the following virtual change handlers obsolete:
The following functions were slots, but are no more:
The following functions were incorrectly marked as virtual:
The internal clearWState() function was removed. Use QWidget::setAttribute () 代替。
setWFlags() was renamed QWidget::setWindowFlags ().
clearWFlags() has no direct replacement. You can use
QWidget::setAttribute
() instead. For example,
setAttribute(..., false)
to clear an attribute. More information <<<<<<< HEAD is available
here
. ======= is available
here
. >>>>>>> c61eb6d... WIP: Changes needed to build 4.8 docs using latest version of QDoc
testWFlags() was renamed to testAttribute() .
见 特性 for a list of QWidget properties in Qt 3 that have changed in Qt 4.
The
QWidgetFactory
class has been replaced by
QFormBuilder
in Qt 4.
The QWidgetIntDict class was a synonym for QIntDict< QWidget >. It is no longer available in Qt 4. If you link against Qt3Support , you can use Q3IntDict < QWidget > instead; otherwise, see the section on QDict<T> .
In Qt 3, the QWidgetList class was a typedef for QPtrList< QWidget >. In Qt 4, it is a typedef for QList < QWidget *>. See the section on QPtrList<T> .
The QWidgetPlugin class is no longer available in Qt 4. To create custom widget plugins, subclass QDesignerCustomWidgetInterface to provide information about the custom widget, and build a plugin in the way described in the 自定义 Widget 插件 范例。
The QWidgetStack class is no longer part of the Qt public API. It has been renamed Q3WidgetStack and moved to Qt3Support . In Qt 4 applications, you can use QStackedWidget instead to obtain the same results.
The
QWizard
class was reintroduced in Qt 4.3. See the
通俗向导范例
,
许可向导范例
and
类向导范例
了解更多细节。
The
QWorkspace
in Qt 4 class requires explicit adding of MDI windows with
QWorkspace::addWindow
().