środa, 18 listopada 2015

Story of porting complex Qt application to Android - part II

First part of the story is here

7. Scrolling

Unfortunately, with "Fusion" Qt style all scroll bars look the same like on desktop, but with "android" style they are big enough to be touched and it is looking... ugly (It is only my personal opinion)
...and Have you seen such bars in Android applications?
My solution is to get rid of them at all. Another idea is to stylizing them to be just thin - similar to native Android bars.
Anyway, both solutions take away the possibility to scroll - when bars are invisible or impossible to touch.

To have nice, single finger scrolling - as befits Android app - we need QScrollArea wrapped by QScroller -
for any window, tab, stacked widget page or so, whitch is going to be bigger than available screen space.
Also for QListWidget or QListView or QTextEdit or any widget inherits from QAbstactScrollArea we may use QScroller
QScroller::grabGesture(any_Scrolable_Widget->viewport(), QScroller::LeftMouseButtonGesture);
Yes, We do not need any fancy touch gesture, QScroller::LeftMouseButtonGesture is far enough to work with mouse button and finger touch.

So, what about not scrolable widgets. In Nootka there are a lot of config and creators widgets. All of them are deriving from simple class made of QScrollArea

Then we use TtouchArea as an ordinary widget, adding it to any widget container classes.


8. Quicker deploying

It could be very absorbing to watch all communicates when Qt Creator is building an application and deploying it into Android device. But only a few times at the beginning. Later on, when one realize how much time it takes, it is simply annoying.
So what can we do to short this process.

- Using adb to push a part of apk package

All hints below require rooted device, but every emulated ones are rooted by default.
In Android world our Qt application is just a library, so instead of creating apk package and deploying it once more time, we may copy it directly to location where it has been installed already:
$adb push build/path/libOurApplication.so /data/data/app.our.of.domain/lib/
Just after that we may launch the fresh built of the app directly in emulator or from Qt Creator.

- Dividing the app library

Sending megabytes of data through adb takes time, so above solution may be still not enough due to big size of our app library in debug mode.
It can be one more reason why we should divide our code on libraries.
Then, after small change in the code, which affects only one of the libraries we are coping only that one.
Also rich resources of our application (icons, audio files and so) included to the lib by qrc system increases its size much.
All of that can be packed into separate library.
Another way is to use assets instead of qrc. In Nootka there are a few ogg files with samples for different kinds of guitars and only one of them is used (depends on user settings) and it is loaded once, during launching. Using assets is much suitable for this purpose. The same is used for translations (qm files)

9. Debugging trick

It is very usable to run an application in terminal and to see some debug messages. We may run our app in Qt Creator and watching messages but we also may se what our app says by grabbing messages into log file. To achieve that a function i.e. myMessageOutput has to be created before main() in main.cpp


Then it has to be installed by qInstallMessageHandler (usually in main)

This way, in device memory a file myApp-log.txt is created for every run with all messages of our app.

10. File dialog

On desktop one uses to call
QFileDialog::getOpenFileName()
to get native file dialog and file name then. But there is no Android native file dialog, so ordinary Qt file dialog will appear.
Under mobile system such a dialog is completely not suitable for it, even worst - it is dangerous, because if one want to scroll listed context of some directory with one finger, some directory under the finger may be dragged into another one.
The simplest way I found to get a file name is to invoke external Android application related to file manager through JNI.
Here is a post about it:
http://stackoverflow.com/questions/15079406/qt-necessitas-reasonable-qfiledialog-replacement-skin

But it is really not difficult task to implement own file dialog. Here is what Nootka has:

Only thing to get it is to have some dialog with QListView and set its model to QFileSystemModel
listView = new QListView(this);
fileModel = new QFileSystemModel(this);
listView->setModel(fileModel);
Rest of the dialog depends on our needs.
Here is Nootka's implementation of file dialog:
https://github.com/SeeLook/nootka/blob/master/src/libs/core/widgets/tfiledialog.h
https://github.com/SeeLook/nootka/blob/master/src/libs/core/widgets/tfiledialog.cpp


11. Color dialog

A dialog window available by calling
QColorDialog::getColor()
is not suitable for touch screens at all. QML has better optimized color dialog but how to get this under QtWidgets?
There is a project with alternative implementation of color dialogues for Qt:
https://github.com/mbasaglia/Qt-Color-Widgets

With a few changes I get such a result on Android:


Here is a code:
https://github.com/SeeLook/nootka/blob/master/src/plugins/settings/tcolordialog.h
https://github.com/SeeLook/nootka/blob/master/src/plugins/settings/tcolordialog.cpp

It uses color wheel of Qt-Color-Widgets:
https://github.com/SeeLook/nootka/blob/master/src/plugins/settings/color_wheel.hpp
https://github.com/SeeLook/nootka/blob/master/src/plugins/settings/color_wheel.cpp




Brak komentarzy:

Prześlij komentarz