lee*_*mes 6 c++ qt qml qt-quick qtquick2
在编写不使用QML并且不依赖于新的Qt 5功能的Qt应用程序时,我们可以使用Qt 4和Qt 5编译它(除了少数源不兼容性).
当我们想要使用Qt 5功能但希望回归到同等但效率较低的Qt 4解决方案时,我们可以简单地使用an #if来检查Qt版本,例如使用新的QStringLiteral但是QString::fromUtf8在使用Qt 4编译时回落.
我们怎么能用QtQuick做同样的事情?请注意,有可能使用QDeclarativeView与QtQuick 1.xQt中5,但不会使用Qt的从5新场景图仅1.x被支持QDeclarativeView,只2.x支持在QQuickView,即使我不使用快速2.0中引入的功能.
我想要的是:
QDeclarativeView和朋友一起使用; 在QML中:import QtQuick 1.xQQuickView朋友; 在QML中:import QtQuick 2.xQtQuick 1.x和另一个用于QtQuick 2.x关于C++部分,这似乎很容易.在Qt 4中,我们可以简单地添加:
#include <QApplication>
#include <QDeclarativeView>
#include <QDeclarativeEngine>
typedef QApplication QGuiApplication;
typedef QDeclarativeView QQuickView;
Run Code Online (Sandbox Code Playgroud)
然后在Qt 4和Qt 5中使用QGuiApplication,QQuickView等等.但是当QML文件包含导入声明时QtQuick,我无法添加一个#if来决定1.x和2.x. 是否有正式的方法,比方说,添加一个别名来进行QtQuick 1.x工作QQuickView(实际上它被解析为QtQuick 2.0)?
我所做的是在部署所有 QML 文件时替换它们中的字符串QtQuick x.y。如果您的源树中有一个文件夹qml,并且希望qml在构建树中有相同的文件夹,您可以部署该文件夹,但替换字符串以匹配您想要的 QtQuick 版本。
以下解决方案适用于 POSIX 系统,因为它需要一些命令行工具;在 Linux (Ubuntu) 上测试。也许有 Windows 命令行经验的人可以添加适用于 Windows 的版本。
添加.pro:(以下代码假设从构建文件夹中可以使用 访问源文件夹../src/;如果不是这种情况,请更改注释所在的路径***)
// Define QT5 macro for use in C++, and select the correct module for QML:
greaterThan(QT_MAJOR_VERSION, 4) {
DEFINES += QT5
QT += quick
} else {
QT += declarative
}
// Define qmake variables for QtQuick version, and if you want, QtQuick Controls:
equals(QT_MAJOR_VERSION, 4) {
equals(QT_MINOR_VERSION, 7) {
QT_QUICK_VERSION = 1.0
}
equals(QT_MINOR_VERSION, 8) {
QT_QUICK_VERSION = 1.1
}
}
equals(QT_MAJOR_VERSION, 5) {
QT_QUICK_VERSION = 2.$${QT_MINOR_VERSION}
equals(QT_MINOR_VERSION, 1): QT_QUICKCONTROLS_VERSION = 1.0
equals(QT_MINOR_VERSION, 2): QT_QUICKCONTROLS_VERSION = 1.1
equals(QT_MINOR_VERSION, 3): QT_QUICKCONTROLS_VERSION = 1.2
}
// Add a pre-build step which copies your qml folder
QtQuickVersion.target = FORCE
QtQuickVersion.commands = "rm -rf qml/;"
QtQuickVersion.commands += "cp -r ../src/qml/ .;" // <-- *** Here is the source path
!isEmpty(QT_QUICK_VERSION) {
QtQuickVersion.commands += "grep -rl 'QtQuick [0-9]\\.[0-9]' qml/ | xargs -r sed -i 's/QtQuick [0-9]\\.[0-9]/QtQuick $${QT_QUICK_VERSION}/g';"
}
!isEmpty(QT_QUICKCONTROLS_VERSION) {
QtQuickVersion.commands += "grep -rl 'QtQuick.Controls [0-9]\\.[0-9]' qml/ | xargs -r sed -i 's/QtQuick.Controls [0-9]\\.[0-9]/QtQuick.Controls $${QT_QUICKCONTROLS_VERSION}/g';"
}
// Give the Makefile target *any* name which will *not* be created
// as a file, so the step is always executed
PRE_TARGETDEPS += FORCE
QMAKE_EXTRA_TARGETS += QtQuickVersion
Run Code Online (Sandbox Code Playgroud)
在 C++ ( main.cpp)中,您可以创建一个QQuickView回退到QDeclarativeViewQt 4 的函数:
#ifdef QT5
#include <QGuiApplication>
#include <QQuickView>
#include <QQmlEngine>
#else
#include <QApplication>
#include <QDeclarativeView>
#include <QDeclarativeEngine>
typedef QApplication QGuiApplication;
typedef QDeclarativeView QQuickView;
// The following is the official fallback for QStringLiteral,
// see qstring.h in Qt 5 after #ifndef QStringLiteral */
#define QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1)
#endif
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv);
// (add qmlRegisterType etc.)
// Open the QML view with the main QML document:
QQuickView view;
view.setSource(QUrl::fromLocalFile(QStringLiteral("qml/main.qml")));
view.show();
// Needed for "Qt.quit()" within QML:
QObject::connect(view.engine(), SIGNAL(quit()), &a, SLOT(quit()));
// I normally use this sizing behavior:
view.setResizeMode(QQuickView::SizeRootObjectToView);
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码打开的QML 文件qml/main.qml如下所示:
// This import will replaced with the largest supported QtQuick version:
import QtQuick 1.0
Rectangle {
width: 450
height: 200
Text {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
font.pointSize: Math.min(parent.width / 10, parent.height / 5)
// This text will also be replaced to show the correct QtQuick version:
text: "Hello from\nQtQuick 1.0!"
// Some fancy animations...
SequentialAnimation on scale {
running: true; loops: Animation.Infinite
NumberAnimation { from: 1; to: .6; easing.type: Easing.InOutQuad; duration: 600 }
NumberAnimation { from: .6; to: 1; easing.type: Easing.InOutQuad; duration: 600 }
}
SequentialAnimation on rotation {
running: true; loops: Animation.Infinite
NumberAnimation { from: -10; to: 10; easing.type: Easing.InOutQuad; duration: 2000 }
NumberAnimation { from: 10; to: -10; easing.type: Easing.InOutQuad; duration: 2000 }
}
}
MouseArea {
anchors.fill: parent
onClicked: Qt.quit()
}
}
Run Code Online (Sandbox Code Playgroud)
QML 文件包含一个导入指令,它将选择正确的 QtQuick 版本(您可以在构建文件夹中检查它)。元素中的字符串Text也会被替换,因此您将在此演示中轻松看到该版本。