What Exif Lib How to Use from a Qt Program (On Embedded Linux)

What EXIF lib can I use from a Qt program (on embedded linux)?

Even if it is not Qt-related, probably your best option is the libexif C EXIF library. It is a GNOME core library (thus is widely deployed, tested and documented), still it is completely toolkit-agnostic, has no dependences and is LGPL licensed. It is a C library, thus its API is not idiomatic of Qt, nonetheless it is powerful and easy to use.

I've seen a lot of Qt-based software that prefer to use the exiv2 library, which is written in C++, but exiv2 is GPL (with option to buy a commercial license) and offers more or less the same functionality of libexif. My suggestion is to try libexif and, only if it does not satisfy your requirements, try exiv2.

How to locate and use fonts in Qt for Embedded Linux?


What is the fontdir file for, do I need it and how do I create it?

This file is only required when QPF fonts should be used which is a Qt specific "light-weight" format. The Qt tool makeqpf uses the file (as far as I understood that).

What do I have to do so that Qt finds all my installed fonts?

If Qt is compiled with -no-freetype then no TTF fonts can be used and are therefore not found by QFontDatabase. To enable the TTF support one has to compile Qt without this compile config flag. I have re-compiled it and all fonts inside /usr/local/Trolltech/QtEmbedded-4.8.6-x86-dbg/lib/fonts were found.

Is there a way to simply use a copy of my font of interest and put it
into a sub-directory of my application to treat it like an icon so
that I don't have to mess around with all the system locations?

Yes. One can simply use QFontDatabase::addApplicationFont which should not fail for supported font formats.

Note that I decided to re-compile Qt because I didn't want to mess with the makeqpf tool from Qt which could be used to convert TTF fonts to the QPF format.

QT Applications - Replacing embedded resources

This answer is specific for Qt's resource system (.qrc, rcc).

From the docs:

Currently, Qt always stores the data directly in the executable, even on Windows, macOS, and iOS, where the operating system provides native support for resources. This might change in a future Qt release.

So yes, the Qt resources are contained in the binary.

rcc'ing a .qrc file yields a .cpp file containing (mainly) simple char arrays which represent resource data, the resource names and some other metadata.

Compiling such a .cpp file creates byte fields in the binary.

You can alter such resources within a binary, but only in very limited ways.

  • For starters, if the binary contains any kind of self-check (like hashing the data section and comparing it to some pre-calculated hash), you will not be able to change the data in a reasonable way.

  • If your data doesn't have the same byte length as the original data, you can't simply replace it because it would alter the internal layout of the binary and invalidate relative addresses.

  • In case of replacing with shorter strings you might get away with zero-padding at the end.

Resources are compressed by default (in the ZIP format). It is possible to turn off compression.

  • If compression was turned on during compilation (which you don't control, as it seems), you'd need to create new data which compresses to the same length as the original.

What UI lib or something can i use to simulate traffic conditions with moving stuff with C++?

Here is a quick start for you:

http://qt-project.org/doc/qt-4.8/graphicsview-collidingmice.html

Study the example and figure out what is going on.

Change the mice into cars. Create boundary conditions for how they navigate. Maybe swap the subclass to a QGraphicsPixmapItem, or a QGraphicsRectItem.

Change what they do as they approach or intersect with another car.

Then when you are ready, add in traffic light representation, and have the cars detect the upcoming traffic light.

Instead of just detecting collisions at the time of drawing, you can have a QTimer event that recalculates the "driving decision" of the car based on the nearby cars and what they were doing.

Use QPropertyAnimations.

http://qt-project.org/doc/qt-4.8/animation-animatedtiles.html

Hope that helps.

QImage loads with wrong orientation for certain images

You might need to use a library like libexif to determine the photo orientation and then rotate the QImage accordingly

How do I install a Qt app as a system app on Android?

My mistake was moving the libraries to /system/lib. I believe I may have blindly copied all the steps of a previous answer where that was necessary, and some changes in Qt and/or Android may've have happened since then that lead to my issue.

For my purposes, it was sufficient to simply move the directory altogether as-is from /data/app/ to /system/priv-app, keeping the library subdirectory.

adb install appname.apk
adb remount
adb shell
cd /data/app
mv appname* /system/priv-app
reboot

The QtLoader is able to load up some of the shared libraries from /system/lib enough to get to the next step. But the next step needs to have the libraries in the first place it looks, at /system/priv-app/org.qtproject.example.QMLhello-LpZtuoO0ejyQPg_I-8pWnQ==/lib/x86 (at least in the case of the x86 emulator - substitute other arch as needed)

Otherwise, there is a chance it will run into a NullPointerException and fail to launch.

Potential workaround

Add some <meta-data> directly under <application> in AndroidManifest.xml

Details

Here is a snippet of the QtNative.java code, lines 489-497 as of the 5.15.2 release (line numbers added)

// ...
/* 489 */ File f = new File(nativeLibraryDir + mainLibNameTemplate);
/* 490 */ if (!f.exists()) {
/* 491 */ try {
/* 492 */ ApplicationInfo info = getContext().getApplicationContext().getPackageManager()
/* 493 */ .getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
/* 494 */ String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir;
/* 495 */ if (info.metaData.containsKey("android.app.system_libs_prefix"))
/* 496 */ systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix");
/* 497 */ f = new File(systemLibraryDir + mainLibNameTemplate);
// ...

489: When QtNative.java goes to load the main application library, it first checks in that ./lib/x86 subfolder, in this case.

492-493: When it fails to find that, it's looking for some metadata in the application manifest to see if the application is telling it where to look. When there is no metadata at the application level, however, the metaData member of the object is null.


  1. Not checking for null, thus a NullPointerException gets thrown

How did a null pointer happen in the first place?

The AndroidManifest.xml generated by Qt by default for this project (attached below) does not contain any <meta-data> tags directly under the <application> level--they are instead contained in <activity>. The loadMainLibrary function should be looking at the activityInfo instead of (or in addition to) applicationInfo, as well as checking for null beforehand.

This seems like a bug in Qt and I'll report accordingly, but 5.15.x won't be getting any more updates for open source.

<?xml version="1.0"?>
<manifest package="org.qtproject.example.QMLhello" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->


<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="QMLhello" android:extractNativeLibs="true">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="QMLhello" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<!-- Application arguments -->
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
<!-- Application arguments -->

<meta-data android:name="android.app.lib_name" android:value="QMLhello"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>

<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidBearer.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value=""/>
<!-- Used to specify custom system library path to run with local system libs -->
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<meta-data android:value="@string/unsupported_android_version" android:name="android.app.unsupported_android_version"/>
<!-- Messages maps -->

<!-- Splash screen -->
<!-- Orientation-specific (portrait/landscape) data is checked first. If not available for current orientation,
then android.app.splash_screen_drawable. For best results, use together with splash_screen_sticky and
use hideSplashScreen() with a fade-out animation from Qt Android Extras to hide the splash screen when you
are done populating your window with content. -->
<!-- meta-data android:name="android.app.splash_screen_drawable_portrait" android:resource="@drawable/logo_portrait" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable_landscape" android:resource="@drawable/logo_landscape" / -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen -->

<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running -->

<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor -->

<!-- extract android style -->
<!-- available android:values :
* default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
* full - useful QWidget & Quick Controls 1 apps
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
* none - useful for apps that don't use any of the above Qt modules
-->
<meta-data android:name="android.app.extract_android_style" android:value="default"/>
<!-- extract android style -->
</activity>

<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->

</application>

</manifest>


Related Topics



Leave a reply



Submit