簡體   English   中英

C ++ / QML項目兼容Qt 4(QtQuick 1.x)和Qt 5(QtQuick 2.x)

[英]C++/QML project compatible with both Qt 4 (QtQuick 1.x) and Qt 5 (QtQuick 2.x)

在編寫不使用QML並且不依賴於新的Qt 5功能的Qt應用程序時,我們可以使用Qt 4和Qt 5編譯它(除了少數源不兼容性)。

當我們想要使用Qt 5功能但希望回歸到同等但效率較低的Qt 4解決方案時,我們可以簡單地使用#if來檢查Qt版本,例如使用新的QStringLiteral但是回退到QString::fromUtf8當用Qt 4編譯時從QString::fromUtf8

我們怎么能用QtQuick做同樣的事情? 請注意,有可能使用QDeclarativeViewQtQuick 1.x使用Qt 5,但不會從Qt的使用新的場景圖5.只有1.x支持在QDeclarativeView只有2.x在支持QQuickView ,即使我不使用Quick 2.0中引入的功能。

我想要的是:

  • 使用Qt 4進行編譯時,請使用QDeclarativeView和朋友; 在QML中: import QtQuick 1.x
  • 使用Qt 5進行編譯時,請使用新的QQuickView和朋友; 在QML中: import QtQuick 2.x
  • 只有一組QML文件,但不是 QtQuick 1.xQtQuick 2.x另一組

關於C ++部分,這似乎很容易。 在Qt 4中,我們可以簡單地添加:

#include <QApplication>
#include <QDeclarativeView>
#include <QDeclarativeEngine>
typedef QApplication QGuiApplication;
typedef QDeclarativeView QQuickView;

然后在Qt 4和Qt 5中使用QGuiApplicationQQuickView等。但是當QML文件包含QtQuick的導入聲明時,我無法添加#if來決定1.x和2.x. 有沒有官方的方法,比方說,添加別名QtQuick 1.xQQuickViewQQuickView (所以它實際上被解析為QtQuick 2.0 )?

我所做的是在部署它們時替換所有QML文件中的字符串QtQuick xy 如果源樹中有文件夾qml ,並且希望在構建樹中具有相同的qml文件夾,則可以部署該文件夾,但替換字符串以匹配所需的QtQuick版本。

以下解決方案適用於POSIX系統,因為它需要一些命令行工具; 在Linux(Ubuntu)上測試過。 也許具有Windows命令行經驗的人可以為Windows添加版本。

添加.pro :(以下代碼假定在build文件夾中,源文件夾可以通過../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

在C ++( main.cpp )中 ,您可以創建一個QQuickView ,它回QQuickView QDeclarativeView

#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();
}

由上面的代碼打開的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()
    }
}

QML文件包含一個import指令,它將選擇正確的QtQuick版本(您可以在build文件夾中查看)。 Text元素中的字符串也會被替換,因此您將在此演示中輕松查看該版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM