Deploying QML modules with C++ plugins: a working (but hacky) solution

2,708 views
Skip to first unread message

Koying

unread,
Nov 24, 2011, 7:26:33 AM11/24/11
to andro...@googlegroups.com
Still working on the Qt components for Android, I had to find a way to deploy the qml modules.
Using assets for .qml, .js and images works ok, but it looks a C++ plugin (i.e. a .so) cannot be executed from the assets.

For reference, this is how I made it work.

The test project is named "TestQMLAndroid". When creating a new project in Qt Creator, a "qml/TestQMLAndroid/" dir is created, containing "main.qml"
I created a "qml/imports" dir when I copied the content of the modules (in this case "qml/imports/com/nokia/android.1.1" and "qml/imports/Qt/labs/components.1.1".
I created another dir, "qml/plugins", where I moved the .so of the modules, i.e. "qml/plugins/libandroidplugin_1_1.so" and "qml/plugins/libqtcomponentsplugin_1_1.so".

In the "TestQMLAndroid.pro", I have:

# Add more folders to ship with the application, here
folder_01.source = qml/TestQMLAndroid
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

android {
    qmlcomponents.source = qml/imports
    qmlcomponents.target = imports
    DEPLOYMENTFOLDERS += qmlcomponents

    qmlplugins.files = \
        qml/plugins/libandroidplugin_1_1.so \
        qml/plugins/libqtcomponentsplugin_1_1.so
        x86 {
            qmlplugins.path = /libs/x86
        } else: armeabi-v7a {
            qmlplugins.path = /libs/armeabi-v7a
        } else {
            qmlplugins.path = /libs/armeabi
        }
    INSTALLS += qmlplugins
}
[...]

In main.cpp, I have

[...]
    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
#ifdef Q_OS_ANDROID
    viewer->addImportPath("/imports/");
    viewer->engine()->addPluginPath(QDir::homePath()+"/../lib");
#endif
    viewer->setMainQmlFile(QLatin1String("qml/main.qml"));
    viewer->engine()->setBaseUrl(QUrl::fromLocalFile("/"));
[...]

As a result, the plugins .so are deployed in the "lib" folder on Android, together with "libTestQMLAndroid.so", which the application library.

Please advice if someone knows a better way. I especially find the 'QDir::homePath()+"/../lib"' to determine the "lib" dir quite hacky...

Regards
- Chris -

BogDan Vatra

unread,
Nov 24, 2011, 1:13:05 PM11/24/11
to andro...@googlegroups.com
Hi,

Looks ok to me, next release will have an environment variable set
to your application library folder, please go to sf.net [1] and open
an issue and next release will have this feature implemented.

Cheers,
BogDan.

[1] https://sourceforge.net/p/necessitas/tickets/

2011/11/24 Koying <cb...@semperpax.com>:

Koying

unread,
Nov 24, 2011, 6:30:57 PM11/24/11
to andro...@googlegroups.com
Ok.

BTW, which ticketing should we use (google or sf?). I'd suggest to stick to one, to avoid duplicates and you having to check multiple places...

BogDan Vatra

unread,
Nov 25, 2011, 1:10:41 AM11/25/11
to andro...@googlegroups.com
I think I gave you the link to sf.net, please check my previous post.

BogDan.

Sent from my HTC Desire HD.


----- Reply message -----
From: "Koying" <cb...@semperpax.com>
To: <andro...@googlegroups.com>
Subject: Deploying QML modules with C++ plugins: a working (but hacky) solution
Date: Fri, Nov 25, 2011 01:30


Ok.

BTW, which ticketing should we use (google or sf?. I'd suggest to stick to one, to avoid duplicates and you having to check multiple places...

Tezine

unread,
Jan 9, 2012, 1:36:24 PM1/9/12
to android-qt
Hi,
I'm trying to create a simple Qt Quick app with your qt components,
but whenever I try to execute it inside the emulator from Qt Creator,
I get the message saying:
qrc:/qml/testeBla/main.qml:2:1: module "com.nokia.android" is not
installed
I'm running Alpha 3 update 2. The app is compiled using armv7 release
and the compiled qt components from http://dl.dropbox.com/u/7264433/QuickComponentsAndroidarmv7.zip.
What am I doing wrong?
It seems that the app is looking for the qml module in a different
place. I set the viewer->addImportPath("/imports/") and viewer-
>engine()->addPluginPath(QDir::homePath()+"/../lib") as you mencioned,
but when I run adb shell, both .so are only inside the app/lib folder.
Is this correct?
Thanks,
Bruno.

Koying

unread,
Jan 10, 2012, 4:49:44 AM1/10/12
to andro...@googlegroups.com
Updated 2012/01/10: I noticed the previous instructions do not work when compiling under Linux due to subtle differences in qmlapplicationviewer.pri. Here are updated instructions (updates in blue):


The test project is named "TestQMLAndroid". When creating a new project in Qt Creator, a "qml/TestQMLAndroid/" dir is created, containing "main.qml"
I created a "qml/imports" dir when I copied the content of the modules (in this case "qml/imports/com/nokia/
android.1.1" and "qml/imports/Qt/labs/components.1.1".
I created another dir, "qml/plugins", where I moved the .so of the modules, i.e. "qml/plugins/libandroidplugin_1_1.so" and "qml/plugins/libqtcomponentsplugin_1_1.so".

In the "TestQMLAndroid.pro", I have:

# Add more folders to ship with the application, here
folder_01.source = qml/TestQMLAndroid
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

android {
    qmlcomponents.source = qml/imports
    qmlcomponents.target =
    DEPLOYMENTFOLDERS += qmlcomponents

    qmlplugins.files = \
        qml/plugins/libandroidplugin_1_1.so \
        qml/plugins/libqtcomponentsplugin_1_1.so
        x86 {
            qmlplugins.path = /libs/x86
        } else: armeabi-v7a {
            qmlplugins.path = /libs/armeabi-v7a
        } else {
            qmlplugins.path = /libs/armeabi
        }
    INSTALLS += qmlplugins
}
[...]

In qmlapplicationviewer/qmlapplicationviewer.pri, I applied the following patch (vs. alpha3):

--- a/qmlapplicationviewer/qmlapplicationviewer.pri
+++ b/qmlapplicationviewer/qmlapplicationviewer.pri
@@ -111,6 +111,7 @@ symbian {
             QMAKE_EXTRA_TARGETS += first copydeploymentfolders
         }
     }
+}
     android {
         installPrefix = /assets
     } else {
@@ -121,7 +122,12 @@ symbian {
         itemfiles = $${item}.files
         $$itemfiles = $$eval($${deploymentfolder}.source)
         itempath = $${item}.path
-        $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+        win32 {
+            sourcePathSegments = $$split($${deploymentfolder}.source, /)
+            $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+        } else {
+            $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+        }
         export($$itemfiles)
         export($$itempath)
         INSTALLS += $$item
@@ -148,7 +154,6 @@ symbian {
     }
     export(target.path)
     INSTALLS += target
-}

 export (ICON)
 export (INSTALLS)

In main.cpp, I have

[...]
    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
#ifdef Q_OS_ANDROID
    viewer->addImportPath("/imports/");
    viewer->engine()->addPluginPath(QDir::homePath()+"/../lib");
#endif
    viewer->setMainQmlFile(QLatin1String("qml/TestQMLAndroid/main.qml"));

    viewer->engine()->setBaseUrl(QUrl::fromLocalFile("/"));
[...]

As a result, the plugins .so are deployed in the "lib" folder on Android, together with "libTestQMLAndroid.so", which is the application library.

Koying

unread,
Jan 10, 2012, 5:01:55 AM1/10/12
to andro...@googlegroups.com
Hi Bruno,

If you are compiling under Linux, please see updated instructions. I tried recently to compile under linux and noticed some issues.

"module not found" refers to what is under "imports", e.g. "com/nokia/android.1.1". Qt searches there for a "qmldir" describing the module. Please check you have, e.g., "imports/com/nokia/android.1.1/qmldir".

The plugins in the "<app>/lib" folder are referenced by the modules. As they are executable libs, they must be there. As of alpha3, the only way I found to find this dir is using 'QDir::homePath()+"/../lib', but that should change in alpha4.

Regards
- Chris -

Tezine

unread,
Jan 10, 2012, 7:17:54 AM1/10/12
to android-qt
Hi Chris,
Thanks for your patience.
I'm running on Windows.
It seems that all qml files under imports inside the app folder in my
pc are not pushed to the emulator by default.
I had to push them all manually to the app/files in the emulator. I
don't know if this is the correct path, but It was the only one that
it stopped complaining about "module not found".
But now, app crashes every time.
Here is my main.qml:
import QtQuick 1.1
import com.nokia.android 1.1
import Qt.labs.componets 1.1
Rectangle {
width: 360
height: 360
color: "orange"
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
CheckBox {
id: check
width: 200
}
}

Follow the emulator stack trace below:
Any ideas?
Thanks again,
Bruno.

D/dalvikvm( 842): DEX prep '/data/data/org.kde.necessitas.ministro/
files/qt/jar/QtIndustrius-14.jar': unzip in 397ms, rewrite 637ms
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtCore.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtCore.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtCore.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtGui.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtGui.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtGui.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtNetwork.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtNetwork.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtNetwork.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtScript.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtScript.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtScript.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSql.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSql.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSql.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSystemInfo.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSystemInfo.so 0x40515d68
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSvg.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSvg.so 0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtSvg.so 0x40515d68,
skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtXmlPatterns.so
0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtXmlPatterns.so
0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtXmlPatterns.so
0x40515d68, skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtDeclarative.so
0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtDeclarative.so
0x40515d68
D/dalvikvm( 842): No JNI_OnLoad found in /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtDeclarative.so
0x40515d68, skipping init
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.ministro/files/qt/plugins/platforms/android/
libandroid-9.so 0x40515d68
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.ministro/files/qt/plugins/platforms/android/
libandroid-9.so 0x40515d68
I/Qt ( 842): qt start
D/dalvikvm( 842): Trying to load lib /data/data/
org.kde.necessitas.example.testeBla/lib/libtesteBla.so 0x40515d68
W/Qt ( 842): Qml debugging is enabled. Only use this in a safe
environment!
D/dalvikvm( 842): Added shared lib /data/data/
org.kde.necessitas.example.testeBla/lib/libtesteBla.so 0x40515d68
I/Qt ( 842): qt start
D/Qt ( 842): startQtApp
D/Qt ( 842): environmentString "HOME=/data/data/
org.kde.necessitas.example.testeBla/files TMPDIR=/data/data/
org.kde.necessitas.example.testeBla/files
MINISTRO_SSL_CERTS_PATH=/data/data/org.kde.necessitas.ministro/files/
qt/ssl QML_IMPORT_PATH=/data/data/org.kde.necessitas.ministro/files/qt/
imports QT_PLUGIN
_PATH=/data/data/org.kde.necessitas.ministro/files/qt/plugins" ("HOME=/
data/data/org.kde.necessitas.example.testeBla/files", "TMPDIR=/data/
data/org.kde.necessit
as.example.testeBla/files", "MINISTRO_SSL_CERTS_PATH=/data/data/
org.kde.necessitas.ministro/files/qt/ssl QML_IMPORT_PATH=/data/data/
org.kde.necessitas.ministro/
files/qt/imports QT_PLUGIN_PATH=/data/data/
org.kde.necessitas.ministro/files/qt/plugins")
D/Qt ( 842): paramsString "QtApp -platform android"
W/Qt ( 842): WARNING: QApplication was not created in the main()
thread.
W/InputManagerService( 239): Window already focused, ignoring focus
gain of: com.android.internal.view.IInputMethodClient$Stub
$Proxy@4072fc78
D/Qt ( 842): QAndroidPlatformIntegrationPlugin::create "android"
D/Qt ( 842):
QAndroidPlatformIntegration::QAndroidPlatformIntegration(): creating
QAndroidPlatformScreen => Using Raster (Software) for painting
D/Qt ( 842): QFbScreen::setPhysicalSize QSize(51, 85)
D/Qt ( 842): QFbScreen::setGeometry QRect(0,0 480x800)
D/Qt ( 842):
QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
W/dalvikvm( 842): dvmFindClassByName rejecting 'org/kde/necessitas/
industrius/QtNativeInputConnection'
D/Qt ( 842): setDisplayMetrics
D/Qt ( 842): setDisplayMetrics done
D/Qt ( 842): setDesktopSize
D/Qt ( 842): setDesktopSize done
I/Qt JAVA ( 842): surfaceChanged: 480,762,480,762
D/Qt ( 842): setDisplayMetrics
D/Qt ( 842): setDisplayMetrics done
D/Qt ( 842): setDesktopSize
D/Qt ( 842): setDesktopSize done
W/dalvikvm( 842): dvmFindClassByName rejecting 'org/kde/necessitas/
industrius/QtExtractedText'
D/Qt ( 842): plugin path: "/data/data/
org.kde.necessitas.example.testeBla/files"
I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** ***
*** *** ***
I/DEBUG ( 31): Build fingerprint: 'generic/sdk/generic:2.3.3/
GRI34/101070:eng/test-keys'
I/DEBUG ( 31): pid: 842, tid: 1158 >>>
org.kde.necessitas.example.testeBla <<<
I/DEBUG ( 31): signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr
81e23998
I/DEBUG ( 31): r0 00000001 r1 000039aa r2 81e28444 r3 81e2ea14
I/DEBUG ( 31): r4 81e9e290 r5 00000002 r6 00000004 r7 00000000
I/DEBUG ( 31): r8 81d06e1c r9 00000000 10 00100000 fp 45ebaeb4
I/DEBUG ( 31): ip 81e00000 sp 45eba6d0 lr 81e239c3 pc
81e23998 cpsr 00000030
I/DEBUG ( 31): #00 pc 00023998 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): #01 lr 81e239c3 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31):
I/DEBUG ( 31): code around pc:
I/DEBUG ( 31): 81e23978 00004ae6 000039e6 4604b510 ffe4f7ff
I/DEBUG ( 31): 81e23988 bd104620 20014b08 49094a08 447a447b
I/DEBUG ( 31): 81e23998 6354f503 4479b510 7274f502 f7f33308
I/DEBUG ( 31): 81e239a8 2001ef12 bf00bd10 0000b07c 00004aaa
I/DEBUG ( 31): 81e239b8 000039aa f7ffb510 4b07ffe5 447b4907
I/DEBUG ( 31):
I/DEBUG ( 31): code around lr:
I/DEBUG ( 31): 81e239a0 7274f502 f7f33308 2001ef12 bf00bd10
I/DEBUG ( 31): 81e239b0 0000b07c 00004aaa 000039aa f7ffb510
I/DEBUG ( 31): 81e239c0 4b07ffe5 447b4907 44794a07 447a6809
I/DEBUG ( 31): 81e239d0 60186812 44784805 f7f36800 bd10eea4
I/DEBUG ( 31): 81e239e0 0007ca26 0007c766 0007c78a 0007c942
I/DEBUG ( 31):
I/DEBUG ( 31): stack:
I/DEBUG ( 31): 45eba690 00000015
I/DEBUG ( 31): 45eba694 81e064d8 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): 45eba698 b000e05c
I/DEBUG ( 31): 45eba69c b0003c51 /system/bin/linker
I/DEBUG ( 31): 45eba6a0 81ea0370 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): 45eba6a4 b00105bc
I/DEBUG ( 31): 45eba6a8 b000dfd0
I/DEBUG ( 31): 45eba6ac 81e9e000 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): 45eba6b0 b0010548
I/DEBUG ( 31): 45eba6b4 b0004769 /system/bin/linker
I/DEBUG ( 31): 45eba6b8 0000002e
I/DEBUG ( 31): 45eba6bc b000dfd0
I/DEBUG ( 31): 45eba6c0 00000424
I/DEBUG ( 31): 45eba6c4 0000065d
I/DEBUG ( 31): 45eba6c8 df002777
I/DEBUG ( 31): 45eba6cc e3a070ad
I/DEBUG ( 31): #00 45eba6d0 81e9e290 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): 45eba6d4 b00037f5 /system/bin/linker
I/DEBUG ( 31): 45eba6d8 b000e0b4
I/DEBUG ( 31): 45eba6dc b000e0b0
I/DEBUG ( 31): 45eba6e0 00002732
I/DEBUG ( 31): 45eba6e4 b00038a7 /system/bin/linker
I/DEBUG ( 31): 45eba6e8 000a1000 [heap]
I/DEBUG ( 31): 45eba6ec 80800000 /data/data/
org.kde.necessitas.ministro/files/qt/lib/libQtCore.so
I/DEBUG ( 31): 45eba6f0 0000002e
I/DEBUG ( 31): 45eba6f4 b000dfd0
I/DEBUG ( 31): 45eba6f8 81e9fc30 /data/data/
org.kde.necessitas.example.testeBla/lib/libandroidplugin_1_1.so
I/DEBUG ( 31): 45eba6fc b000dfd0
I/DEBUG ( 31): 45eba700 00002732
I/DEBUG ( 31): 45eba704 b0004f9f /system/bin/linker
I/DEBUG ( 31): 45eba708 0000002e
I/DEBUG ( 31): 45eba70c b000e05c
I/DEBUG ( 31): 45eba710 b000dfd0
I/DEBUG ( 31): 45eba714 00000005
D/Zygote ( 33): Process 842 terminated by signal (4)
I/ActivityManager( 239): Process org.kde.necessitas.example.testeBla
(pid 842) has died.

Koying

unread,
Jan 10, 2012, 8:17:55 AM1/10/12
to andro...@googlegroups.com
Aren't you mixing CPU architectures?

The component zip is for armv7, so your app must be compiled for armv7, too, and tested on an armv7 emulator, i.e. API14.

Tezine

unread,
Jan 10, 2012, 8:52:01 AM1/10/12
to android-qt
Hi Chris,
I've got the compiled libs from http://dl.dropbox.com/u/7264433/QuickComponentsAndroidarmv7.zip
They're already compiled for arm7, right?
I'm compiling the app under Qt Creator for API 10 in arm7 release mode
using the default Android GCC(arm-4.4.3) toolchain.
Thanks/Bruno.

Jonny

unread,
Jan 11, 2012, 7:46:57 AM1/11/12
to android-qt
Hi Chris,
Just an FYI, I have been using the components with linux and have
deployed a couple apps to the marketplace now without changing
anything in the qmlapplicationviewer.pri.
Its well over my head as to whats going on with the changes to the pri
file, should I make these changes moving forward or if it aint broke
dont fix it? ;)
Cheers,
Jon

On Jan 10, 4:49 am, Koying <c...@semperpax.com> wrote:
> Updated 2012/01/10: I noticed the previous instructions do not work when
> compiling under Linux due to subtle differences in
> qmlapplicationviewer.pri. Here are updated instructions (updates in *blue*):
>
> The test project is named "TestQMLAndroid". When creating a new project in
> Qt Creator, a "qml/TestQMLAndroid/" dir is created, containing "main.qml"
> I created a "qml/imports" dir when I copied the content of the modules (in
> this case "qml/imports/com/nokia/
> android.1.1" and "qml/imports/Qt/labs/components.1.1".
> I created another dir, "qml/plugins", where I moved the .so of the modules,
> i.e. "qml/plugins/libandroidplugin_1_1.so" and
> "qml/plugins/libqtcomponentsplugin_1_1.so".
>
> In the "TestQMLAndroid.pro", I have:
>
> # Add more folders to ship with the application, here
> folder_01.source = qml/TestQMLAndroid
> folder_01.target = qml
> DEPLOYMENTFOLDERS = folder_01
>
> android {
>     qmlcomponents.source = qml/imports
> *    qmlcomponents.target =
> *    DEPLOYMENTFOLDERS += qmlcomponents
>
>     qmlplugins.files = \
>         qml/plugins/libandroidplugin_1_1.so \
>         qml/plugins/libqtcomponentsplugin_1_1.so
>         x86 {
>             qmlplugins.path = /libs/x86
>         } else: armeabi-v7a {
>             qmlplugins.path = /libs/armeabi-v7a
>         } else {
>             qmlplugins.path = /libs/armeabi
>         }
>     INSTALLS += qmlplugins}
>
> [...]
>
> *In qmlapplicationviewer/qmlapplicationviewer.pri, I applied the following
> *
> In main.cpp, I have
>
> [...]
>     viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
> #ifdef Q_OS_ANDROID
>     viewer->addImportPath("/imports/");
>     viewer->engine()->addPluginPath(QDir::homePath()+"/../lib");
> #endif
>     viewer->setMainQmlFile(QLatin1String("qml/*TestQMLAndroid/*main.qml"));

Jonny

unread,
Jan 11, 2012, 7:50:15 AM1/11/12
to android-qt
Hi Tezine,
I am using the 4.6.2 tool chain. Not sure if that makes a difference
or not but you may want to give it a whirl.
Cheers,
Jon

On Jan 10, 8:52 am, Tezine <br...@tezine.com> wrote:
> Hi Chris,
> I've got the compiled libs fromhttp://dl.dropbox.com/u/7264433/QuickComponentsAndroidarmv7.zip

Chris Browet

unread,
Jan 11, 2012, 7:52:07 AM1/11/12
to andro...@googlegroups.com
Definitely, "aint broke dont fix it" ;)

- Chris -

Haroldo Maranhão

unread,
Jan 11, 2012, 8:09:13 AM1/11/12
to andro...@googlegroups.com

----- Mensagem original -----
De: "Chris Browet" <cb...@semperpax.com>
Para: andro...@googlegroups.com
Enviadas: Quarta-feira, 11 de Janeiro de 2012 9:52:07
Assunto: Re: Deploying QML modules with C++ plugins: a working (but hacky) solution

Koying

unread,
Jan 12, 2012, 12:09:42 PM1/12/12
to andro...@googlegroups.com
I've now created a project page for the Qt components for android: http://redmine.semperpax.com/projects/qt-components-android

It allows to download binaries for both armv5 and armv7

- Chris -

ckaminski

unread,
Jan 12, 2012, 10:44:06 PM1/12/12
to andro...@googlegroups.com
Any chance we can get an example project for arm7?  I try these instructions and QtCreator crashes loading the project.  When you create a new project do you pick built-in, symbian or meego?  

Thanks for the hard work.  I'm still pretty new at this.  

-Chris

Chris Browet

unread,
Jan 13, 2012, 2:36:57 AM1/13/12
to andro...@googlegroups.com

Quite obviously, you have to use the necessitas Qt creator coming with the necessitas sdk...

Fabian Braun

unread,
Aug 15, 2012, 12:29:16 PM8/15/12
to andro...@googlegroups.com
Hi,

unfortunatelly the patch doesn't work. What is wrong?

Terminal output:

root@debian-fabianb:/home/fabianb/projects/android-qt/TestQMLAndroid/qmlapplicationviewer# ls -al
total 28
drwxr-xr-x 2 root root 4096 Aug 15 18:07 .
drwxr-xr-x 4 root root 4096 Aug 15 18:08 ..
-rw------- 1 root root 6076 Aug 15 18:07 qmlapplicationviewer.cpp
-rw------- 1 root root 1346 Aug 15 18:07 qmlapplicationviewer.h
-rw------- 1 root root 6035 Aug 15 18:07 qmlapplicationviewer.pri
root@debian-fabianb:/home/fabianb/projects/android-qt/TestQMLAndroid/qmlapplicationviewer# vim
root@debian-fabianb:/home/fabianb/projects/android-qt/TestQMLAndroid/qmlapplicationviewer# patch -p2 qmlapplicationviewer.pri qmlapplicationviewer.pri.patch
patching file qmlapplicationviewer.pri
Hunk #1 FAILED at 111.
Hunk #2 FAILED at 121.
Hunk #3 succeeded at 155 with fuzz 1 (offset 7 lines).
2 out of 3 hunks FAILED -- saving rejects to file qmlapplicationviewer.pri.rej

Thanks for your help!

Chris Browet

unread,
Aug 16, 2012, 5:31:03 AM8/16/12
to andro...@googlegroups.com
Well, probably the fact that the patch is 8 months old and that necessitas didn't froze during that time?

- Chris -

Fabian Braun

unread,
Aug 16, 2012, 8:41:51 AM8/16/12
to andro...@googlegroups.com, cb...@semperpax.com
Does anyone have a patch for the latest version?

Chris Albrecht

unread,
Aug 16, 2012, 8:48:00 AM8/16/12
to andro...@googlegroups.com

I didn't need to use the patch..

Fabian Braun

unread,
Aug 16, 2012, 9:02:05 AM8/16/12
to andro...@googlegroups.com
- I am working with Linux and have installed the latest necessitas version
- I have changed the main.cpp as described.
- I have changed the .pro file as described
- Qt Creator shows the "imports" and "plugins" folders in the project tree under "Other files" and it shows "imports" under QML/qml. But "import com.nokia.android 1.1" (main.qml) is still red underlined and commented with "package not found"
- I use armv7a Release for build.
- If I activate the QTSystemInfo library in the run Settings, the app crashes at start up. Without everything works fine.
- My AVD target is running with android 2.1 API level 7

Any ideas? I have been trying for 2 days know...

Daniel Bittencourt

unread,
Aug 19, 2012, 6:22:08 PM8/19/12
to andro...@googlegroups.com
I made a simple way (hacky) to include qt components on your project:

The files and instructions can be found here: http://dl.dropbox.com/u/6994819/qtcomponents_android.tar.gz

Let me know if you have problems.

Fabian Braun

unread,
Aug 21, 2012, 9:27:21 AM8/21/12
to andro...@googlegroups.com
I followed your instructions and tried with a new necessitas
installattion. When I create a new Project, I select "Qt Quick
Application" and Application Type "Bult-in elements only".


This is the changed .pro file:

# Add more folders to ship with the application, here
folder_01.source = qml/test_qml_components
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

# Deploy Android Qt Components
include(deployment.pri)
qtcAddDeployment()

# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =

symbian:TARGET.UID3 = 0xE7B1DB56

# Smart Installer package's UID
# This UID is from the protected range and therefore the package will
# fail to install if self-signed. By default qmake uses the unprotected
# range value if unprotected UID is defined for the application and
# 0x2002CCCF value if protected UID is given to the application
#symbian:DEPLOYMENT.installer_header = 0x2002CCCF

# Allow network access on Symbian
symbian:TARGET.CAPABILITY += NetworkServices

# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
# CONFIG += mobility
# MOBILITY +=

# Speed up launching on MeeGo/Harmattan when using applauncherd daemon
# CONFIG += qdeclarative-boostable

# Add dependency to Symbian components
# CONFIG += qt-components

# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp

# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
qtcAddDeployment()

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



This is the changed applicationviewer.cpp:

// checksum 0x1098 version 0x70010
/*
This file was generated by the Qt Quick Application wizard of Qt Creator.
QmlApplicationViewer is a convenience class containing mobile device specific
code such as screen orientation handling. Also QML paths and debugging are
handled here.
It is recommended not to modify this file, since newer versions of Qt Creator
may offer an updated version of it.
*/

#include "qmlapplicationviewer.h"

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtDeclarative/QDeclarativeComponent>
#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeContext>
#include <QtGui/QApplication>

#include <qplatformdefs.h> // MEEGO_EDITION_HARMATTAN

#ifdef HARMATTAN_BOOSTER
#include <MDeclarativeCache>
#endif

#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800

#include <qt_private/qdeclarativedebughelper_p.h>

#if !defined(NO_JSDEBUGGER)
#include <jsdebuggeragent.h>
#endif
#if !defined(NO_QMLOBSERVER)
#include <qdeclarativeviewobserver.h>
#endif

// Enable debugging before any QDeclarativeEngine is created
struct QmlJsDebuggingEnabler
{
QmlJsDebuggingEnabler()
{
QDeclarativeDebugHelper::enableDebugging();
}
};

// Execute code in constructor before first QDeclarativeEngine is instantiated
static QmlJsDebuggingEnabler enableDebuggingHelper;

#endif // QMLJSDEBUGGER

class QmlApplicationViewerPrivate
{
QmlApplicationViewerPrivate(QDeclarativeView *view_) : view(view_) {}

QString mainQmlFile;
QDeclarativeView *view;
friend class QmlApplicationViewer;
QString adjustPath(const QString &path);
};

QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_ANDROID
return path;
#endif
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
if (!QDir::isAbsolutePath(path))
return QCoreApplication::applicationDirPath()
+ QLatin1String("/../Resources/") + path;
#else
QString pathInInstallDir;
const QString applicationDirPath = QCoreApplication::applicationDirPath();
pathInInstallDir =
QString::fromAscii("%1/../%2").arg(applicationDirPath, path);

if (QFileInfo(pathInInstallDir).exists())
return pathInInstallDir;
#endif
#endif
return path;
}

QmlApplicationViewer::QmlApplicationViewer(QWidget *parent)
: QDeclarativeView(parent)
, d(new QmlApplicationViewerPrivate(this))
{
connect(engine(), SIGNAL(quit()), SLOT(close()));
setResizeMode(QDeclarativeView::SizeRootObjectToView);

#ifdef Q_OS_ANDROID
engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
// Qt versions prior to 4.8.0 don't have QML/JS debugging services built in
#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
#if !defined(NO_JSDEBUGGER)
new QmlJSDebugger::JSDebuggerAgent(d->view->engine());
#endif
#if !defined(NO_QMLOBSERVER)
new QmlJSDebugger::QDeclarativeViewObserver(d->view, d->view);
#endif
#endif
}

QmlApplicationViewer::QmlApplicationViewer(QDeclarativeView *view,
QWidget *parent)
: QDeclarativeView(parent)
, d(new QmlApplicationViewerPrivate(view))
{
connect(view->engine(), SIGNAL(quit()), view, SLOT(close()));
view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
// Qt versions prior to 4.8.0 don't have QML/JS debugging services built in
#if defined(QMLJSDEBUGGER) && QT_VERSION < 0x040800
#if !defined(NO_JSDEBUGGER)
new QmlJSDebugger::JSDebuggerAgent(d->view->engine());
#endif
#if !defined(NO_QMLOBSERVER)
new QmlJSDebugger::QDeclarativeViewObserver(d->view, d->view);
#endif
#endif
}

QmlApplicationViewer::~QmlApplicationViewer()
{
delete d;
}

QmlApplicationViewer *QmlApplicationViewer::create()
{
#ifdef HARMATTAN_BOOSTER
return new QmlApplicationViewer(MDeclarativeCache::qDeclarativeView(), 0);
#else
return new QmlApplicationViewer();
#endif
}

void QmlApplicationViewer::setMainQmlFile(const QString &file)
{
d->mainQmlFile = d->adjustPath(file);
d->view->engine()->addImportPath("/imports/");
d->view->engine()->addPluginPath(QDir::homePath()+"/../lib");
d->view->setSource(QUrl::fromLocalFile(d->mainQmlFile));
}

void QmlApplicationViewer::addImportPath(const QString &path)
{
d->view->engine()->addImportPath(d->adjustPath(path));
}

void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
{
#if defined(Q_OS_SYMBIAN)
// If the version of Qt on the device is < 4.7.2, that attribute won't work
if (orientation != ScreenOrientationAuto) {
const QStringList v =
QString::fromAscii(qVersion()).split(QLatin1Char('.'));
if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt()
<< 8 | v.at(2).toInt()) < 0x040702) {
qWarning("Screen orientation locking only supported with
Qt 4.7.2 and above");
return;
}
}
#endif // Q_OS_SYMBIAN

Qt::WidgetAttribute attribute;
switch (orientation) {
#if QT_VERSION < 0x040702
// Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
case ScreenOrientationLockPortrait:
attribute = static_cast<Qt::WidgetAttribute>(128);
break;
case ScreenOrientationLockLandscape:
attribute = static_cast<Qt::WidgetAttribute>(129);
break;
default:
case ScreenOrientationAuto:
attribute = static_cast<Qt::WidgetAttribute>(130);
break;
#else // QT_VERSION < 0x040702
case ScreenOrientationLockPortrait:
attribute = Qt::WA_LockPortraitOrientation;
break;
case ScreenOrientationLockLandscape:
attribute = Qt::WA_LockLandscapeOrientation;
break;
default:
case ScreenOrientationAuto:
attribute = Qt::WA_AutoOrientation;
break;
#endif // QT_VERSION < 0x040702
};
setAttribute(attribute, true);
}

void QmlApplicationViewer::showExpanded()
{
#if defined(Q_OS_SYMBIAN) || defined(MEEGO_EDITION_HARMATTAN) ||
defined(Q_WS_SIMULATOR)
d->view->showFullScreen();
#elif defined(Q_WS_MAEMO_5)
d->view->showMaximized();
#else
d->view->show();
#endif
}

QApplication *createApplication(int &argc, char **argv)
{
#ifdef HARMATTAN_BOOSTER
return MDeclarativeCache::qApplication(argc, argv);
#else
return new QApplication(argc, argv);
#endif
}



this is the main.cpp

#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"

Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());

viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer->setMainQmlFile(QLatin1String("qml/test_qml_components/main.qml"));
viewer->showExpanded();

return app->exec();
}



and main.qml:


import QtQuick 1.0
import com.nokia.android 1.1
import Qt.labs.components 1.1


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



2012/8/20 Daniel Bittencourt <danie...@gmail.com>
Reply all
Reply to author
Forward
0 new messages