把 QML 应用程序移植到 Qt5

When porting QML-related code from Qt 4.8 to Qt 5, application developers should be aware that the QML infrastructure has undergone considerable changes in Qt 5. The sections below describe these changes and the impact they have on your existing code.

QML 语言变化

There are very few changes in the QML language that affect the porting of existing Qt 4.8 QML code to Qt 5. These are:

  • Individual file imports no longer work (for example, import "MyType.qml"). Import the containing directory instead.
  • Relative file paths in JavaScript files are now resolved relative to the location of the JavaScript file instead of the QML file that imported it.
  • It's no longer possible to override signals from the base component.

QtQuick 模块

The QtQuick module has been updated to version 2. All QML applications should update their import statements to use the new version:

import QtQuick 2.3
					
					

特性和方法变化

类型和 API 变化

行为变化

QtQuick 2 includes a number of behavioral changes and you should thoroughly test your applications after porting. These changes will not necessarily lead to run-time errors, but may break certain assumptions in your code. Below are the prominent changes to be aware of when porting your applications.

Item opacity and visibility:

  • The input handling details of opacity and visible have changed. An opacity of zero no longer affects input handling, where previously it stopped mouse input. A visibility of false no longer affects keyboard input, but still stops mouse input. The new enabled property stops mouse and keyboard input, but does not affect how or whether the item is rendered. A workaround for applying the old behavior in most cases is to bind enabled to (visible && opacity > 0.0) .
  • Previously, if an item was in a positioner (i.e. a Row , Column , Grid and Flow ) and the item's opacity changed to 0, or its visible value became false , the positioner would remove the item from its layout and collapse the space for that item. In QtQuick 2, this now only happens when an item's visible is false ; the item opacity no longer affects whether the item is laid out. (This is consistent with the existing behavior of ListView and GridView ).

文本:

  • The TextEdit::textFormat 特性现在默认为 PlainText 而不是 AutoText .
  • Text::textFormat 被设为 Text.AutoText format, the text object will automatically switch to Text.StyledText 而不是 Text.RichText .

其它:

  • Modifying the Image::sourceSize now fits the image to the size, maintaining aspect ratio.
  • For ListView and GridView cacheBuffer property now has a non-zero default and delegates in the cache buffer are created asynchronously. Also, using a RightToLeft layout now also reverses the preferredHighlightBegin and preferredHighlightEnd .
  • For Loader sourceChanged and sourceComponentChanged signals are now only emitted when their respective properties change value. (Previously Loader emitted both of these signals when either of the relevant properties had changed.)

实验性 Qt.labs 模块的变化

  • The Qt.labs.particles module has been removed. It is replaced by the fully-fledged QtQuick.Particles module which is an enormous improvement on its predecessor.
  • The Qt.labs.shaders module has been removed as the ShaderEffectItem and ShaderEffectSource types from this module have been moved into the QtQuick module. Note the ShaderEffectItem type has been renamed to ShaderEffect .

C++ 代码

In Qt 5, all QML applications are rendered with an OpenGL scenegraph architecture rather than the Graphics View framework used in Qt 4. Due to the scale of this architectural change, the C++ API has been extensively restructured and the QtDeclarative module has been deprecated in favor of two new modules: Qt QML , which implements the QML engine and language infrastructure, and Qt Quick , which implements the visual canvas and scenegraph backend.

All classes that were previously in the QtDeclarative module have been moved into the Qt QML and Qt Quick modules, and their class names have been changed to reflect their new module locations. The class name changes are as follows:

Qt QML Qt Quick

To use the new QQml* and QQuick* classes in Qt 5, link against the approprate module from your qmake .pro file. For example the following will link against both the Qt QML and Qt Quick 模块:

QT += qml quick
					

Required header files can then be included:

#include <QtQml/QQmlEngine>
#include <QtQuick/QQuickView>
					

( QtDeclarative 模块对开发者仍然可用因为 Qt Quick 1 模块,如论述 below 。不管怎样,不应该将它用于新应用程序)。

QDeclarativeItem 和 QDeclarativeView

When porting to QQuickItem , note that QDeclarativeItem inherited from QGraphicsItem ; in contrast, QQuickItem inherits directly from QObject , and any QGraphicsItem -specific functionality is no longer available. In particular, QQuickItem does not have a paint() method for performing custom rendering through the QPainter API. Instead, in Qt 5, custom rendering should be performed through the new QSG* classes to take full advantage of the scene graph. See the Qt Quick 场景图形 documentation details on using these classes.

另外, QQuickPaintedItem 提供 paint() method and can be used as a convenient way to port QDeclarativeItem-based classes that use the QPainter API. Note this method is less performant than using the QSG* 类。

When porting from QDeclarativeView to QQuickView , note that QDeclarativeView inherited from QGraphicsView . In contrast, QQuickView 继承自 QQuickWindow and uses the QWindow infrastructure introduced in Qt 5; any QGraphicsView -specific functionality is no longer available.

Utilities: qmlscene and qml

The qmlviewer tool provided for prototyping and testing QML applications in Qt 4.x has been replaced with the qmlscene tool which integrates with the new scenegraph features in Qt 5. In Qt 5.2, the qml tool was added, intended as the eventual replacement for qmlscene .

QML 插件

All QML plugins should extend QQmlExtensionPlugin in Qt 5.

Additionally, plugins should use the new Qt plugin infrastructure introduced in Qt 5. QML plugins no longer require the Q_EXPORT_PLUGIN2() macro. Instead, they should use the Q_PLUGIN_METADATA () macro within the plugin class declaration.

See the updated 为 QML 创建 C++ 插件 documentation for an overview of creating QML plugins in Qt 5.

Qt 5 中的 QtDeclarative 模块

For the purposes of porting older applications, the QtDeclarative module has been available until Qt 5.6 but has been renamed to Qt Quick 1 . Applications that required Qt Quick 1 specific API (e.g. QDeclarativeView or QDeclarativeItem and the Graphics View integration) can use this module. Note that new applications should use the new Qt QML and Qt Quick modules instead.

要使用 Qt Quick 1 模块,添加 declrative 到 qmake .pro 文件:

QT += declarative
					

Required header files can be included as follows:

#include <QtDeclarative/QDeclarativeView>
#include <QtDeclarative/QDeclarativeItem>