2013-08-19 47 views
9

我想從Qt 5.1.0 android安裝中導入TimeExample Qt Quick Extension Plugin。如何將qt5 qml插件部署到android?

libqmlqtimeexampleplugin.so被成功地建立在build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports

然後創建從Qt Creator的Qt的簡單應用Quick2(內置元件)。我應該添加到應用程序項目文件中以在輸出「.apk」包中獲取QML插件?

現在它說:

W/QT(23528):資產:/qml/TimeExampleTest/main.qml:2():資產:/qml/TimeExampleTest/main.qml:2:1 :模塊 「TimeExample」 未安裝

main.qml

import QtQuick 2.0 

import TimeExample 1.0 // import types from the plugin 

Rectangle { 
    width: 360 
    height: 360 
    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      Qt.quit(); 
     } 
    } 

    Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) 

     Time { // this class is defined in C++ (plugin.cpp) 
      id: time 
     } 

     hours: time.hour 
     minutes: time.minute 

    } 
} 

TimeExampleTest.pro

folder_01.source = qml/TimeExampleTest 

folder_01.target = qml 

folder_02.source = /home/artem/Projects/Veedo/Test/build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample 

folder_02.target = imports 

DEPLOYMENTFOLDERS = folder_01 folder_02 

QML_IMPORT_PATH = /home/artem/Projects/Veedo/Test/build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample 

SOURCES += main.cpp 

include(qtquick2applicationviewer/qtquick2applicationviewer.pri) 

qtcAddDeployment() 

OTHER_FILES += \ 
    android/src/org/kde/necessitas/ministro/IMinistro.aidl \ 
    android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ 
    android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ 
    android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ 
    android/AndroidManifest.xml \ 
    android/version.xml \ 
    android/res/values-ja/strings.xml \ 
    android/res/values-rs/strings.xml \ 
    android/res/values-zh-rTW/strings.xml \ 
    android/res/values-fa/strings.xml \ 
    android/res/values-ru/strings.xml \ 
    android/res/values-fr/strings.xml \ 
    android/res/values-ro/strings.xml \ 
    android/res/values-el/strings.xml \ 
    android/res/values-ms/strings.xml \ 
    android/res/values-nb/strings.xml \ 
    android/res/values-et/strings.xml \ 
    android/res/values-pl/strings.xml \ 
    android/res/values-pt-rBR/strings.xml \ 
    android/res/values-es/strings.xml \ 
    android/res/values-id/strings.xml \ 
    android/res/values-de/strings.xml \ 
    android/res/values-it/strings.xml \ 
    android/res/values-zh-rCN/strings.xml \ 
    android/res/values/strings.xml \ 
    android/res/values/libs.xml \ 
    android/res/layout/splash.xml \ 
    android/res/values-nl/strings.xml 

回答

6

通過Qt 5.3,我們設法通過將插件部署到官方Qt QML模塊所在的QT_INSTALL_QML目錄中,讓我們的QML插件能夠被Qt Android應用識別。在我們的例子中,這個目錄是/opt/Qt/5.3/android_armv7/qml。

插件側面

我們.pro文件的插件看起來像:

TEMPLATE = lib 
TARGET = prova 
QT += qml quick multimedia 
CONFIG += qt plugin c++11 console 
CONFIG -= android_install 
TARGET = $$qtLibraryTarget($$TARGET) 
uri = com.mycompany.qmlcomponents 

# Input 
SOURCES += \ 
    src1.cpp \ 
    src2.cpp 

HEADERS += \ 
    src1.h \ 
    src2.h 

##The below is generated automatically by Qt Creator when you create a new "Qt Quick 2 Extension Plugin" project for Android 

#Copies the qmldir file to the build directory 
!equals(_PRO_FILE_PWD_, $$OUT_PWD) { 
    copy_qmldir.target = $$OUT_PWD/qmldir 
    copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir 
    copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" 
    QMAKE_EXTRA_TARGETS += copy_qmldir 
    PRE_TARGETDEPS += $$copy_qmldir.target 
} 

#Copies the qmldir file and the built plugin .so to the QT_INSTALL_QML directory 
qmldir.files = qmldir 
unix { 
    installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) 
    qmldir.path = $$installPath 
    target.path = $$installPath 
    INSTALLS += target qmldir 
} 

我們qmldir(在插件的源代碼樹的根)文件:

module com.mycompany.qmlcomponents 
plugin prova 

應用邊

的.pro文件看起來像:

TEMPLATE = app 

QT += qml quick widgets multimedia 

CONFIG+= console 
SOURCES += main.cpp 

RESOURCES += qml.qrc 

# Additional import path used to resolve QML modules in Qt Creator's code model 
QML_IMPORT_PATH = 
# Default rules for deployment. 
include(deployment.pri) 

contains(ANDROID_TARGET_ARCH,armeabi-v7a) { 
    ANDROID_EXTRA_LIBS = \ 
     /opt/Qt/5.3/android_armv7/qml/com/mycompany/qmlcomponents/libprova.so 
} 

,我們真的不知道,如果額外libprova.so的包容是必要的。這很可能不是。

main.cpp樣子:

#include <QApplication> 
#include <QQmlApplicationEngine> 
int main(int argc, char *argv[]){ 
    QApplication app(argc, argv); 
    QQmlApplicationEngine engine; 
    engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); 
    return app.exec(); 
} 

main.qml只包括像插件:

import QtQuick 2.2 
import QtQuick.Controls 1.1 
import QtMultimedia 5.0 

import com.mycompany.qmlcomponents 1.0 

... 

建設和部署

我們構建和部署插件的方式qmake(來自Qt的android-armv7工具鏈),然後make install。它將qmldir文件和插件.so安裝到QT_INSTALL_QML目錄。

我們建立和部署使用插件項目的方法是qmake(再次,從Qt的的Android的ARMv7的工具鏈),然後make install INSTALL_ROOT=.(安裝建目錄),然後運行androiddeployqt。最後一條命令通過資源庫中的qmldirs和libs /中的庫創建Android項目結構,並通過ant將apk中的所有內容捆綁在一起。有關此過程的詳細信息,請參閱http://qt-project.org/wiki/Android

簡而言之,我們只能通過將其置於私有Qt qml目錄中來獲得我們在Android項目中識別的QML插件。

+0

有趣的,但iirc有一個更直接的方法,我可以挖掘/嘗試一些代碼,如果你有興趣。 – mlvljr

+0

我感興趣@mlvljr! – user981733

+0

@ user981733好的,讓我看看在接下來的幾天,然後:) – mlvljr

0

閱讀QAbstractFileEngineHandler Qt的源之後,我發現了一些醜陋的Qt:

  1. 的Qt並實現某種機制來提供 「搜索路徑」(不是URL)像 「QRC:」,「資產: 「,內核是QAbstractFileEngineHandler。

  2. QAbstractFileEngineHandler變得不再市民QT5,它只是一個QFile,QFileInfo,一個QDir,QIcon,並通過一個QFile提供的東西,包括QImage的,加上QAndroidAssetsFileEngineHandler,這是專門爲Android資產提供抽象。

  3. 因此,SearchPath模式與QUrl不兼容,即使它們看起來如此相似,因爲您知道QtQuick已將setSource設置爲某個URL,所以qml文件不會直接通過「assets:」前綴加載。

  4. 可以Qt的文檔中找到這下面[static] void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)

    QDir::setSearchPaths("icons", QStringList(QDir::homePath() + "/images")); 
    QDir::setSearchPaths("docs", QStringList(":/embeddedDocuments")); 
    
    ...  
    QPixmap pixmap("icons:undo.png"); // will look for undo.png in QDir::homePath() + "/images"  
    QFile file("docs:design.odf"); // will look in the :/embeddedDocuments resource path 
    

    你會發現這段代碼無法工作,因爲的QPixmap沒有從QAbstractFileEngineHandler加載圖像,可這是Qt的無證變化。在另一方面,關於搜索路徑QtCore單元測試只在一個QFile

測試更進一步,void addResourceSearchPath(const QString &path)過時,但是setSearchPath是有缺陷的,我覺得這個很困惑。也許我應該看看現在的QUrl :)