A previous post tells how to install and use pydroid. This post tells how to modify your template app (that pydroid created and deployed to Android.) It gives a series of small examples. The goal is to port a full fledged app you developed on another platform. But I want to test smaller examples first. I am worried that Qt support for Android is half-baked (there are many bug reports.)
- cd to the project directory e.g. ~/APP_NAME
- modify the app’s code e.g. edit ~/APP_NAME/app/main.py
- rebuild the project e.g. >pydroid deploy complete
After the last step, you wait while it rebuilds and deploys. On the AVD (which should be running), it reinstalls your app. Then in the AVD you can click your app icon to run it.
The default pydroid template app is a MVC, QML app
When you create a project in pydroid, it fills in a small app, a template app. The app uses a declarative GUI, i.e. QML, which is a language for specifying the form of a GUI without specifying the business logic, in the same way that, for example, you can use Glade to specify the form of a GTK GUI.
The template app also uses the Model View Controller paradigm, and provides simple classes for it.
But you can just throw that all away, or ignore it, especially while we are testing.
‘About Qt’ Example
In main.py, just in front of:
c = controller.Controller() c.start()
The new app should display the standard (built into Qt) dialog that desplays information about the Qt version being used.
I found that it does display, but is larger than fits on the screen I used, and apparently does not scroll (or I don’t know how to scroll the screen in the AVD.) The “OK” button does function, ending the display of the dialog and resuming the app.
This indicates some corners of Qt are not ready for effortless porting to mobile devices: not allowing for smaller screens.
In main.py, add this function, and a call to it.
def showWarning(app): topLevelWidgets = app.topLevelWidgets() assert len(topLevelWidgets) >= 1 anyTop = topLevelWidgets warning = QMessageBox.warning(anyTop, "Title", "test warning")
Then deploy complete again.
It did not behave as expected: after I ended the “About Qt” dialog, the app simply quit. To debug, in a terminal, enter:
adb shell “cat /sdcard/APP_NAME_log/python_log.txt”
That is, the template pydroid app includes logging to a file on the AVD’s SDCard, which you can read using ADB (Android Debugger Bridge.)
Reading the log, I found that the assertion failed. In other words, the app has no top level window until after you create the Controller.
So I moved the call to showWarning() to after the call to c.start(), and it worked as expected.
However, the title of the warning box did not appear on the AVD. That’s bad user interface. But I don’t know enough about the Android platform: whether the HIG tells how to display warnings in such a way that the user knows which activity it displaying the warning. It could be a deficiency of the Android platform, or it could be that deficiency of the port of Qt to the platform.
My app uses a QGraphicsView and a QGraphicsScene (part of the QGraphicsFramework). My app builds those procedurally. The pydroid template app uses QML to declare the view.
I tried to insert code into the pydroid template app to procedurally build a view. I could not get it to work. However, I found that QDeclarativeView ( that the pydroid template app already uses) is a subclass of QGraphicsView, specialized to read its components from QML. The pydroid template app thus demonstrates that it is possible to use a QGraphicsView on Android (I just need to adapt the view initialization from the source code for QDeclarativeView.)
So I simply edited view.py, adding an event() method to handle view events, and calling self.scale(0.9, 0.9), when an event of type QEvent.MouseButtonPress is received. It seems to work.