I am trying to import TimeExample Qt Quick Extension Plugin from Qt 5.1.0 android installation.
libqmlqtimeexampleplugin.so
is built sucessfully in build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports
Then I created simple Qt Quick2 Application (built-in Elements) from Qt Creator. What should I add to application project file to get QML plugin in output ".apk" package?
Now it says:
W/Qt (23528): assets:/qml/TimeExampleTest/main.qml:2 (): assets:/qml/TimeExampleTest/main.qml:2:1: module "TimeExample" is not installed
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
With Qt 5.3, we managed to get our QML plugin recognized by a Qt Android app only by deploying the plugin to the QT_INSTALL_QML directory where official Qt QML modules reside. This directory is /opt/Qt/5.3/android_armv7/qml in our case.
Plugin Side
Our .pro
file for the plugin looks like:
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
}
Our qmldir
(in the plugin source tree root) file is:
module com.mycompany.qmlcomponents
plugin prova
Application Side
The .pro file looks like:
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
}
We don't actually know if the inclusion of the extra libprova.so is necessary. It's most probably not.
The main.cpp
looks like:
#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();
}
The main.qml
just includes the plugin like:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtMultimedia 5.0
import com.mycompany.qmlcomponents 1.0
...
Building and Deployment
The way we build and deploy the plugin is to qmake
(from the android-armv7 toolchain of Qt), then make install
. It installs the qmldir file and the plugin .so to the QT_INSTALL_QML directory.
The way we build and deploy the project that uses the plugin is to qmake
(again, from the android-armv7 toolchain of Qt), then make install INSTALL_ROOT=.
(installs to build directory), then run androiddeployqt
. The last command creates the Android project structure with the qmldirs in assets/ and libraries in libs/ and bundles the whole thing in an apk via ant
. For the details of this procedure, refer to http://qt-project.org/wiki/Android.
In short, we were only able to get our QML plugin recognized inside an Android project by putting it inside the private Qt qml directory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With