Qt Quick Controls sur Android

Plusieurs personnes ont signalé un problème avec l’utilisation de Qt Quick Controls de Qt 5.1 sur Android. Voir les commentaires de l’article Développez en natif pour Android avec Qt 5.1.

L’origine du problème est simple : les Qt Quick Controls sont en fait un binding pour exporter les widgets de Qt Widgets dans Qt Quick 2. La conséquence est qu’il faut ajouter le module Qt Widgets dans la liste des bibliothèques à empaqueter.

Pour illustrer la démarche, je vais partir du code d’exemple « controls-3 » donné dans l’article Qt Quick Controls dans Qt 5.1.

Créer un nouveau projet

Pour commencer, il faut créer un nouveau projet « Application Qt Quick 2 (éléments de base) » dans Qt Creator. Copiez le code d’exemple QML dans le fichier /QML/qml-nom_application/main.qml puis lancez l’exécution avec le kit Desktop pour tester que l’application fonctionne.

Pour Android, allez dans le mode « Projets » et sélectionnez le kit Android (la liste des kits configurés est située à droite du bouton « Ajouter un kit » ; si le kit Android n’est pas présent, cliquez sur ce bouton pour l’ajouter). Dans le kit, affichez les paramètres d’exécution en cliquant sur le bouton « Exécuter ». Il faut modifier deux choses :

La configuration de paquet

En cliquant sur « Détails », vous affichez une page avec plusieurs onglets : « Fichier manifest », « Application », « Permissions », « Bibliothèques » et « Signature du paquet ». Il s’agit de la configuration de paquet Android, je n’entre pas dans les détails, voir la documentation Android pour les explications (et les noms sont globalement clairs).

L’onglet qui nous intéresse est « Bibliothèques », qui comme vous l’aurez compris permet d’indiquer les modules Qt à inclure dans le paquet. Par défaut, vous avez gnustl_shared (la bibliothèque STL C++), Qt5Core et Qt5Gui (les modules de base pour le core et le graphisme), Qt5Quick, Qt5Qml et Qt5V8 (les modules Qt Quick, QML et le moteur JavaScript V8) et Qt5Network (aucune idée pourquoi il est inclus par défaut, vous pouvez le désactiver pour le code d’exemple controls-3).

Pour utiliser les Qt Quick Controls, il faut donc ajouter le module Qt Widgets dans la liste.

controls-config

Configuration de paquet pour les Qt Quick Controls pour Android

La configuration de déploiement

Vous pouvez choisir à ce niveau comment sera inclus Qt : dans le périphérique, en local ou avec Ministro. J’utilise « en local ».

Compiler et déployer

La configuration est terminée, vous pouvez lancer l’application. Comme vous pouvez le voir sur l’image suivante, la taille de la police par défaut est différente de la version Desktop et le rendu est problématique. Peu importe ici, ce n’est pas le propos, mais cela signifie que le portage direct d’une interface utilisant des Controls sur Android pourra poser problème.

Application d'exemple controls-3 sur Android

Application d’exemple controls-3 sur Android

Pour controls-2, pas de problème non plus sur Android.

Application d'exemple controls-2 sur Android

Application d’exemple controls-2 sur Android

Utilisation de QtQuick.Window

Lorsque l’on utilise les QtQuick.Window avec le qmlscene (par exemple en créant un projet « Qt Quick 2 Ui with Controls »), l’interface s’affiche sans problème. Mais si l’on crée un projet « Application QtQuick 2 (éléments de base) » pour exécuter le code d’exemple controls-1, le message d’erreur suivant apparaît :

QQuickView only supports loading of root objects that derive from
QQuickItem.
If your example is using QML 2, (such as qmlscene) and the .qml 
file you loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this
error will occur.
To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use 
the QDeclarativeView class in the Qt Quick 1 module.

L’erreur provient du fait que l’on essaie de créer une fenêtre (ApplicationWindow) dans une autre fenêtre (QQuickView). Pour utiliser les QtQuick.Window, il va donc falloir modifier la fonction main pour utiliser directement le QML Engine. Voici un exemple de fichier main.cpp simplifié :

#include <QtGui>
#include <QtQml>
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlEngine engine;
    QQmlComponent component(&engine);
    component.loadUrl(QStringLiteral(
        "qml/test-controls/main.qml"));
    component.create();
    return app.exec();
}

Une autre solution (plus propre) consiste à créer une classe QtQuick2ApplicationEngine similaire à QtQuick2ApplicationViewer, basée sur QQmlEngine et proposant la gestion des erreurs et des spécificités de différentes plateformes. Vous trouverez un exemple d’implémentation dans le fichier suivant : qtquick2applicationengine.

Programme d'exemple controls-1 dans le simulateur Android

Programme d’exemple controls-1 dans le simulateur Android

Programme d'exemple controls-1 dans le simulateur Android

Programme d’exemple controls-1 dans le simulateur Android

Remerciements et mise à jour

Comme d’habitude, merci à WinJérôme pour la relecture orthographique de mes articles, ils en ont souvent (toujours…) besoin.

Mises à jour :

  • 19 juillet 2013 : création du tutoriel
  • 08 août 2013 : corrections pour l’utilisation des QtQuick.Windows
Advertisements

4 commentaires sur « Qt Quick Controls sur Android »

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s