Application mobile: Comment exposer une classe Qt C ++ avec des signaux et des emplacements à QML dans votre application mobile

Christian Feldbacher

Le développement d’applications avec QML est simple et puissant. Mais Qt C ++ peut être plus performant, offre de nombreuses fonctionnalités et est moins sujet aux erreurs. Cet article vous montre comment créer des applications qui tirent parti des deux langues.

Vous pouvez obtenir le code source complet de cet exemple d’application sur GitHub.

Il est important de choisir la bonne langue pour les différentes fonctionnalités de votre application. Intégrez des composants C ++ à QML pour faire passer le développement de votre application mobile au niveau supérieur.

V-Play Engine pour les applications et jeux mobiles basés sur Qt utilise la puissance de Qt Quick (QML + Javascript). Ce langage de script déclaratif est si puissant qu’il enregistre jusqu’à 60% de lignes de code par rapport aux autres langages de programmation.

Codage en QML a plusieurs avantages plus de développement avec C ++:

  • Le codage avec QML + JavaScript est très facile à apprendre et permet de réduire considérablement la quantité de code requise.
  • Les concepts de langage comme les états, les signaux ou les liaisons de propriétés sont un énorme gain de temps.
  • QML facilite l’ajout d’animations. Vous pouvez animer chaque propriété de vos types QML avec des composants d’animation simples.
  • QML est extensible et flexible. Par exemple, vous pouvez étendre des objets avec de nouvelles propriétés et fonctionnalités en ligne. Pas besoin de créer un nouveau type réutilisable pour les petites extensions.
  • Le moteur de rendu QML offre de grandes performances. Le moteur de rendu utilise C ++ Qt et s’appuie sur un graphique de scène accéléré par le matériel. Cela le rend assez rapide pour alimenter même des jeux de haute performance.

Le développement d’applications Qt avec C ++ présente également des avantages. Pour certains scénarios, vous avez besoin de fonctionnalités qui ne sont disponibles qu’avec Qt C ++. De plus, C ++ est rapide et sûr pour les types. Cela permet de fournir les meilleures performances possibles pour les calculs longs et gourmands en données.

Pour ces exemples, vous choisissez C ++ plutôt que QML:

  • Le code natif C ++ est le bon choix pour les opérations gourmandes en données. Il surclassera le code QML / JavaScript interprété.
  • Le code C ++ est sécurisé par type et compilé en code objet. Pour les parties où la stabilité et la sécurité sont importantes, l’utilisation de C ++ aide à rendre votre application moins sujette aux erreurs.
  • Les composants Qt C ++ offrent des fonctionnalités différentes et dans certains cas plus que les types QML. Par exemple, des fonctionnalités réseau avancées.
  • Il est également possible de mélanger C ++ avec du code natif pour Android (via JNI) ou iOS (Obj-C ou Swift). Cela permet également de fournir de telles fonctionnalités natives pour QML.

V-Play Engine étend Qt pour le développement d’applications mobiles et de jeux. Il couvre déjà des tâches telles que l’accès aux fonctionnalités natives de l’appareil – vous n’avez donc pas à vous soucier d’aller en profondeur dans C ++ ou Java et Obj-C.

Néanmoins, pour tirer le meilleur parti de votre application, vous pouvez utiliser les avantages des deux langues. L’exemple d’application complet de ce guide est également disponible sur GitHub.

Avant d’entrer dans les détails, commençons par créer un projet V-Play Apps simple avec Qt Creator. Si vous débutez avec V-Play et ne savez pas comment, veuillez consulter le didacticiel de mise en route ou la vidéo du didacticiel V-Play Designer.

Pour vous inscrire et installer V-Play, consultez la page de téléchargement du site Web de V-Play.

Remarque: L’ajout de code C ++ personnalisé n’est pas pris en charge lors des tests avec QML Live. Veuillez construire votre projet avec le bouton RUN classique pour tester les exemples ci-dessous.

  1. Après avoir créé un nouveau projet d’application, remplacez d’abord le code dans Main.qml par cette structure de base:

Il ne comprend que la fenêtre principale de l’application et une page dans NavigationStack pour afficher une barre de navigation contenant le titre de la page:

2. Cela suffit pour notre configuration QML de base. Continuons en créant une nouvelle classe C ++. Tout d’abord, faites un clic droit sur le dossier «Sources» C ++ de votre projet dans Qt Creator, sélectionnez «Ajouter un nouveau…» et choisissez le modèle «Classe C ++» dans la section C ++:

3. Définissez ensuite « MyGlobalObject ” comme Nom du cours et sélectionnez «Inclure QObject» pour inclure le QObject , car la principale exigence pour préparer notre classe pour une utilisation avec QML est de dériver de QObject.

Après avoir terminé l’assistant, votre projet contient la définition de classe myglobalobject.h dans le dossier «En-têtes» et l’implémentation myglobalobject.cpp dans le dossier «Sources» du projet.

Notez que la configuration * .pro inclut désormais également les nouveaux fichiers dans le EN-TÊTES et SOURCES configuration.

  1. Ouvert myglobalobject.h et ajouter du code à dériver de QObject – la déclaration d’inclusion requise est déjà en place:

N’oubliez pas d’ajouter également le Q_OBJECT macro de préprocesseur dans la définition de classe.

2. Maintenant que nous avons un nouveau QObject, ajoutons une méthode simple que nous appellerons plus tard à partir de QML. Pour rendre la méthode disponible dans QML, il est nécessaire de la marquer comme fente publique:

3. Pour terminer notre cours de base, ouvrez myglobalobject.cpp et ajoutez l’implémentation de la méthode pour faire quelque chose(). Nous restons simples et n’imprimons que le texte donné dans la sortie de débogage.

Une façon possible de travailler avec un objet C ++ en QML est de ajouter l’objet en tant que propriété au contexte racine de l’arbre QML. Vous pouvez choisir un nom pour la propriété, qui est ensuite globalement disponible dans votre code QML.

  1. Pour créer un nouvel objet de notre classe et l’ajouter en tant que propriété, nous étendons le code main.cpp:

Remarque: Il est possible d’utiliser pleinement l’objet également en C ++. L’exemple de code ci-dessus inclut déjà un appel de test à notre méthode doSomething.

2. Dans le Main.qml de notre projet, nous étendons notre page avec une colonne et un premier AppButton, qui appelle la méthode doSomething () lorsque vous cliquez dessus:

3. Frappons le bouton d’exécution vert dans Qt Creator pour voir comment cela fonctionne. La sortie de débogage montre l’appel de méthode initial de main.cpp et avec un clic sur le bouton un autre message apparaît:

MyGlobalObject doSomething appelé avec «TEXT FROM QML»

C’est tout ce dont nous avons besoin pour appeler les méthodes d’un objet C ++ à partir de QML. Cela permet déjà une communication simple de QML vers C ++, mais nous pouvons faire encore plus. QML prend en charge de nombreux concepts étonnants comme les écouteurs de propriétés à valeur modifiée et les liaisons de propriétés, ce qui facilite le développement. Ajoutons donc une propriété QML complète à notre classe C ++!

  1. Ouvert mylgobalobject.h et ajoutez une propriété de compteur privée avec une méthode getter et setter publique.

2. Implémentez les méthodes requises et initialisez la propriété counter dans myglobalobject.cpp

3. Semblable à d’autres propriétés de QML, nous voulons également être en mesure de réagir dynamiquement aux changements de propriétés dans notre code QML. En d’autres termes, nous voulons déclencher des fonctions en QML lorsque la propriété C ++ change. Contrairement au fentes, qui font Méthodes C ++ appelables en QML, signaux peut être utilisé pour déclencher du code QML à partir de C ++. Ainsi, le flux de données ressemble à ceci:

Ajoutons un signal counterChanged et le déclencher dans notre setCounter la mise en oeuvre:

myglobalobject.h:

myglobalobject.cpp:

4. Cette simple modification nous permet déjà d’ajouter des fonctions de gestionnaire pour counterChanged () signal en QML. Cependant, notre propriété counter est toujours une propriété C ++ normale avec une méthode getter et setter. Nous pouvons nous en occuper avec une macro de préprocesseur supplémentaire:

le Q_PROPERTY macro définit une propriété compteur et configure les méthodes de lecture et d’écriture de la propriété, ainsi que le signal qui notifie les modifications de propriété. Cette configuration est utilisée par QML pour travailler avec la propriété.

5. Étendons notre Main.qml et utilisons notre nouvelle propriété counter. L’extrait suivant ajoute un nouveau bouton pour augmenter le compteur et un élément de texte pour afficher la valeur:

Notre propriété est utilisable comme toute autre propriété en QML. Grâce à counterChanged que nous avons préparé, le texte est même mis à jour automatiquement à chaque fois que nous changeons de compteur.

Voici à quoi ressemble le dernier exemple:

La deuxième possibilité d’utiliser des composants C ++ dans QML consiste à enregistrer la classe en tant que type QML. Cela permet de créer des objets (= instances) de votre type directement en QML au lieu de C ++. Et la meilleure chose est que les concepts avec signaux, emplacements et propriétés que nous avons utilisés dans l’exemple précédent s’appliquent toujours.

S’il n’y a qu’une seule instance d’objet avec laquelle vous souhaitez travailler dans QML, vous pouvez ajouter l’objet en tant que propriété de contexte. Lorsqu’il peut y avoir plusieurs instances de votre classe, l’enregistrer en tant que type QML et créez les objets directement dans QML là où vous en avez besoin.

  1. Pour cet exemple, nous allons créer un nouveau type que nous pouvons utiliser en QML. Commençons par ajouter une nouvelle classe C ++ nommée MyQMLType

2. Remplacez le code dans myqmltype.h avec cette implémentation:

Similaire à l’exemple précédent, ce type aura un emplacement public et une propriété complète avec une méthode getter, une méthode setter et un signal de propriété modifiée. La méthode d’incrémentation augmente une valeur entière donnée de un et la propriété message stockera une valeur de chaîne.

3. Pour terminer le cours, ajoutez le code suivant pour myqmltype.cpp:

Contrairement à l’exemple précédent, notre nouvelle classe utilise également une valeur de retour pour la tranche d’incrémentation. Aucun autre ajustement n’est nécessaire pour recevoir la valeur de retour en QML. Qt mappe automatiquement les types C ++ de base aux types QML pour tous les paramètres de méthode et les valeurs de retour.

Pour plus d’informations sur les types Qt disponibles et les types QML correspondants, consultez Conversion de types de données entre QML et C ++.

1. Dans votre main.cpp, ajoutez d’abord une instruction include pour la nouvelle classe:

#include "myqmltype.h"

2. Ensuite, utilisez qmlRegisterType pour ajouter la classe en tant que type QML.

La méthode prend plusieurs paramètres: L’identifiant et la version du module définissent l’importation QML requise pour utiliser le type. Le dernier paramètre contient le nom du type QML, qui peut être différent du nom réel de la classe C ++.

3. Ajoutez l’importation qui correspond à la configuration utilisée de qmlRegisterType à votre Main.qml:

// NOTE: the import identifier, version and QML type name are set in main.cpp at qmlRegisterType(...)import com.yourcompany.xyz 1.0

4. Pour un exemple d’utilisation de notre nouveau type QML, ajoutez l’extrait de code suivant sous le premier exemple:

Le code montre que nous pouvons maintenant utiliser MyQMLType comme tout autre élément QML. le message la propriété est initialisée en ligne avec une liaison de propriété, qui montre le résultat entier de la division myGlobalObject.counter par deux. Chaque fois que le compteur change, cette expression est réévaluée automatiquement.

De plus, lorsque le message change à son tour (toutes les 2 contre-étapes), nous utilisons onMessageChanged signal pour afficher le nouveau message dans la sortie du journal.

Semblable à d’autres éléments QML, le Component.onCompleted Le signal est disponible pour effectuer les étapes d’initialisation lorsque le moteur QML crée l’objet. Dans cet exemple, nous utilisons le incrément emplacement pour augmenter le compteur de 1.

L’AppText en bas affiche simplement la propriété du message:

Comme nous l’avons déjà vu dans les exemples précédents, les propriétés, les signaux et les emplacements offrent différents types de communication entre C ++ et QML:

  • Les slots permettent la communication de QML vers C ++: Les emplacements sont utilisés pour déclencher du code C ++ à partir de QML. Vous pouvez utiliser des paramètres et renvoyer des valeurs pour transmettre des données vers et depuis C ++.
  • Les signaux permettent la communication de C ++ à QML: Les signaux sont utilisés pour exécuter du code QML lorsque certains événements se produisent en C ++. Vous pouvez passer des paramètres de C ++ à QML. Cependant, vous ne pouvez pas renvoyer de données à partir de QML.
    Contrairement aux slots, les signaux peuvent être gérés par aucun, un ou plusieurs composants. Il n’y a aucune garantie que le déclenchement d’un signal en C ++ exécutera réellement du code QML, à moins qu’un gestionnaire ne soit défini.

Les propriétés fonctionnent dans les deux sens: Les propriétés sont accessibles en lecture et en écriture à partir de C ++ et de QML. Pour prendre en charge les liaisons de propriété dans QML, assurez-vous d’ajouter un signal modifié pour la propriété et n’oubliez pas de déclencher le signal en C ++ chaque fois que la valeur change.

L’exemple ci-dessus couvre déjà entièrement les emplacements et les propriétés, mais utilise uniquement un signal dans le cadre de la configuration des propriétés. Pour terminer l’exemple, ajoutons un nouvel emplacement startCppTask(), une nouvelle méthode doCppTask() et un nouveau signal cppTaskFinished() à myqmltype.h:

Nous appellerons plus tard la fente startCppTask () de QML, qui exécute le programme interne doCppTask () méthode. Vous pouvez par exemple exécuter des calculs dans un autre thread à ce stade pour éviter de bloquer l’interface utilisateur QML lors de l’exécution de la tâche. Ceci est utile pour toute opération intense ou longue durée d’unité centrale que vous souhaitez gérer en C ++. En ajoutant l’implémentation des méthodes à myqmltype.cpp, nous avons fini avec la partie C ++.

Comme tout est préparé maintenant, nous pouvons ajouter un autre AppButton qui démarre notre tâche C ++:

Le signal onCppTaskFinished () nous avertira lorsque la partie C ++ aura terminé les calculs:

Dans cet exemple, nous remettons simplement notre compteur global à zéro lorsque le signal se déclenche, ce qui mettra également à jour la propriété de message de MyQMLType.

Voici à quoi ressemble le dernier exemple après avoir exécuté la tâche cpp:

Remarque: pour gérer des signaux personnalisés en QML lors de l’utilisation d’un propriété de contexte, Utilisez le Connexions Type QML. L’extrait de code suivant ajoute un gestionnaire à l’élément counterChanged () signal de myGlobalObject:

Dans tous les exemples utilisés, nous avons créé une classe C ++ qui étend QObject. Cependant, il existe certaines limitations aux QObjects: les QObjects n’ont pas de représentation visuelle. Cela signifie qu’ils ne peuvent contenir aucun élément enfant et que les propriétés concernant les caractéristiques visuelles telles que la taille, la position et la visibilité ne sont pas disponibles.

Un QObject contient uniquement des données et une logique que vous pouvez utiliser dans QML en tant que propriétés, signaux et emplacements. Lorsque vous enregistrez une classe QObject en tant que type pour QML, gardez cette restriction à l’esprit. Pour créer un élément QML avec C ++ qui doit prendre en charge une représentation visuelle avec toutes les propriétés par défaut, dérivez de QQuickItem au lieu.

Comme cette courte introduction ne couvre pas l’implémentation de QQuickItems, veuillez consulter la documentation Qt pour plus d’informations. La page de présentation de l’intégration de QML et C ++ se trouve ici.

Le code source complet du projet créé dans ce guide se trouve sur GitHub.

Version 2.16.1: Rechargement de code en direct avec C ++ personnalisé et code natif pour Qt

Comment créer des applications mobiles multiplateformes avec Qt – V-Play Apps

Version 2.17.1: utilisez Qt 3D avec le rechargement en direct et testez des exemples de code de plug-in à partir du navigateur

Version 2.17.0: stockage cloud Firebase, ressources téléchargeables au moment de l’exécution et accès natif aux fichiers sur toutes les plateformes

#Comment #exposer #une #classe #avec #des #signaux #des #emplacements #QML #dans #votre #application #mobile