2013-08-19 48 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 :)