2014-01-28 8 views
5

QML을 사용하지 않고 새로운 Qt 5 기능에 의존하지 않는 Qt 응용 프로그램을 작성할 때, 우리는 Qt 4와 Qt 5로 컴파일 할 수 있습니다 (소스 불일치 문제는 거의 없습니다).Qt 4 (QtQuick 1.x) 및 Qt 5 (QtQuick 2.x)와 호환되는 C++/QML 프로젝트

Qt 5 기능을 사용하려고하지만 Qt 4와 동등하지만 효율성이 떨어지는 솔루션으로 되돌리려는 경우 #if을 사용하여 Qt 버전을 확인하면됩니다. 새로운 QStringLiteral을 사용하지만 Qt 4로 컴파일 할 때 QString::fromUtf8으로 되돌아갑니다.

QtQuick으로 어떻게 똑같이 할 수 있습니까? QDeclarativeView을 Qt 5에 QtQuick 1.x과 함께 사용할 수는 있지만 Qt 5의 새로운 장면 그래프는 사용하지 않습니다. 은 QDeclarativeView에서 지원되며 2.x 만 지원됩니다. 도입 된 기능을 사용하지 않아도 QQuickView에 지원됩니다. Quick 2.0.

내가 원하는 것은 :

  • Qt는 4 컴파일, QDeclarativeView 친구를 사용; QML에서 : import QtQuick 1.x
  • Qt 5로 컴파일 할 때 새로운 QQuickView 및 friends; QML에서 :
  • import QtQuick 2.x 만 QML 파일을 하나의 세트를 가지고 있지만, C++ 부분에 대해서는 QtQuick 2.x

에 대한 QtQuick 1.x과 서로에 대한 하지 일이 쉬운 것 같다.

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

을 다음 두 Qt는 4 Qt는 5 그러나 QML 파일이 QtQuick의 가져 오기 선언을 포함하는 경우, 내가 추가 할 수 없습니다에 등 QGuiApplication, QQuickView를 사용 : Qt는 4에서 우리는 간단하게 추가 할 수 있습니다 #if 1.x와 2.x 사이를 결정하십시오. 예를 들어 별칭을으로 추가하여 QtQuick 1.xQQuickView에서 사용할 수 있도록하는 공식 방법이 있습니까 (실제로는 QtQuick 2.0으로 구문 분석됩니다).

답변

3

배포 할 때 모든 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 
을 C에서

++ (main.cpp), 당신은 Qt를 4 QDeclarativeView 다시 떨어지는 QQuickView를 만들 수 있습니다

#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/main.qml 다음과 같이 볼 수 위의 코드에 의해 연 QML 파일 다음 QML 파일이 적절한 QtQuick 버전을 선택합니다 가져 오기 지시문을 포함

// 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() 
    } 
} 

(당신이 체크인 할 수 있습니다 빌드 폴더). Text 요소의 문자열도 대체되므로이 데모에서는 쉽게 버전을 볼 수 있습니다.

관련 문제