2013-08-19 4 views
9

Я пытаюсь импортировать TimeExample Qt Quick Extension Plugin из установки Qt 5.1.0 для Android.Как развернуть qt5 qml-плагин для Android?

libqmlqtimeexampleplugin.so построен в build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports успешно

Затем я создал простой Qt Quick2 приложения (встроенные элементы) из Qt Creator. Что я должен добавить в файл проекта приложения, чтобы получить плагин QML в пакете вывода «.apk»?

Теперь он говорит:

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 нам удалось получить плагин QML, признанный приложением Qt для Android, только путем развертывания плагина в каталоге QT_INSTALL_QML, где находятся официальные Qt-модули Qt. В нашем случае это каталог /opt/Qt/5.3/android_armv7/qml.

Plugin Side

Наш файл .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 (от андроида-armv7 toolchain of Qt), затем make install. Он устанавливает файл qmldir и плагин. Также в каталог QT_INSTALL_QML.

, как мы строим и развернуть проект, который использует плагин является qmake (опять же, из-андроида ARMv7 набора инструментов в Qt), то make install INSTALL_ROOT=. (устанавливается в каталог для сборки), а затем запустить androiddeployqt.Последняя команда создает структуру проекта Android с помощью qmldirs в активах и библиотеках в libs/и связывает все это в apk через ant. Подробнее об этой процедуре см. http://qt-project.org/wiki/Android.

Одним словом, мы смогли получить наш плагин QML в рамках проекта Android, поместив его в приватный Qt-каталог qml.

+0

Интересно, но у iirc гораздо более простой способ, я мог бы копать/попробовать код, если вам интересно. – mlvljr

+0

Мне интересно @mlvljr! – user981733

+0

@ user981733 Хорошо, позвольте мне заглянуть в это в последующие дни: – mlvljr

0

После прочтения источника в Qt о QAbstractFileEngineHandler, я нашел что-то уродливое в Qt:

  1. Qt действительно реализован какой-то механизм, чтобы обеспечить "SearchPath" (не URL), как "QRC:", «активы: », где ядром является QAbstractFileEngineHandler.

  2. QAbstractFileEngineHandler становится уже не общественности в Qt5, это только обеспечить абстрактно QFile, QFileInfo, QDir, QIcon и вещей, предоставленных QFile, включая QImage, плюс QAndroidAssetsFileEngineHandler, которая специализируется на Android активов.

  3. Таким образом, схема SearchPath несовместима с QUrl, даже если они выглядят настолько похожими, что вы знаете, что QtQuick задает источник для некоторого URL-адреса, поэтому файл qml не будет загружаться префиксом «assets:» напрямую.

  4. Вы можете найти это ниже [static] void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths) в документе Qt:

    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 модульное тестирование около SearchPath протестировано только на QFile

Более того, void addResourceSearchPath(const QString &path) является устареванием однако setSearchPath неисправен, я чувствую себя довольно замешательство по этому вопросу. Может быть, мне стоит взглянуть в QUrl сейчас :)