Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Du 22 au 24 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Maîtrisez Qt
  3. Qt Quick
Extrait - Maîtrisez Qt Guide de développement d'applications professionnelles (3e édition)
Extraits du livre
Maîtrisez Qt Guide de développement d'applications professionnelles (3e édition)
1 avis
Revenir à la page d'achat du livre

Qt Quick

Objectifs

Le module Qt Quick contient tout un nouveau monde à explorer pour le développeur qui est habitué à développer sous Qt avec Qt Widgets et uniquement les classes C++.

Qt Quick, c’est à la fois de nouveaux paradigmes de développement, mais aussi de fonctionnement des applications, de nouvelles cibles d’exécution, comme les smartphones et les appareils embarqués, c’est également un nouveau langage de développement et un nouveau vocabulaire.

Dans ce chapitre, nous partirons à la découverte de Qt Quick, de ses modules, de ses langages de programmation et des principes de programmation et de mise en forme des interfaces graphiques qui lui sont propres.

En lisant ce chapitre, gardez bien à l’esprit que Qt Quick est destiné à la réalisation d’interfaces graphiques et que toutes ses fonctionnalités reposent plus ou moins directement sur des classes C++. Cela est important car vos programmes devront respecter la même logique pour être à la fois souples et performants.

Intégration

Le module Qt Quick est intégré à votre projet grâce à l’ajout du mot-clé « quick » dans la déclaration Qt de votre fichier .pro.

QT += quick 

Ceci étant, Quick utilise lui-même des modules dans lesquels sont stockés tous les fichiers QML et JavaScript de sa bibliothèque de composants. Cela signifie qu’il est accompagné de plusieurs bibliothèques dont il faudra disposer lorsque vous exécuterez l’application.

Si vous voulez un aperçu des modules QML, ouvrez le navigateur de fichiers de votre système et rendez-vous dans le dossier d’installation de Qt.

Vous trouverez dans ce dossier un certain nombre d’autres dossiers, dont un ou plusieurs correspondants aux versions des API que vous avez installées sur votre système, par exemple « 6.2.4 ». Dans ce répertoire, vous trouverez la liste des chaînes de compilation associées à une ou plusieurs plateformes d’exécution. Par exemple, « macOS ». Enfin, dans ce dossier vous trouverez d’autres dossiers contenant les binaires comme qmake, et un dossier nommé « qml ».

Ouvrez à présent le dossier Qt Quick et vous trouverez tous les modules de Qt Quick que vous pouvez importer dans vos projets :

images/11EP01N1.png

Dans la capture...

La terminologie de Qt Quick

Qt Quick introduit une nouvelle terminologie pour marquer ses différences avec le monde du C++. Cela est judicieux car le langage déclaratif QML ne connaît pas la notion d’instanciation de classe. De plus Qt Widgets pourrait permettre de coder toute l’application dans la seule classe de la fenêtre principale de l’application, ce qui n’est évidemment pas recommandé mais possible tout de même, une scène Qt Quick ne le permet pas, ou bien dans des cas très simples. Qt Quick est dédié aux interfaces graphiques, un point c’est tout.

Voici donc quelques notions de vocabulaire propres à Qt Quick.

Une Scène correspond à une Vue, dans le patron de conception MVC. Il s‘agit de l’objet graphique, l’interface entre l’homme et la machine, ou encore la GUI. Une Scène ne devrait contenir que le code déclaratif QML permettant de mettre en page la vue. Le fichier de la Scène porte en principe l’extension .ui.qml. Tout le reste devrait être dans un Type QML contrôleur et dans des fichiers JavaScript. En réalité, pour des applications simples il est très fréquent que tout se trouve dans le même et unique fichier .qml (sans l’extension .ui).

Un Contrôleur correspond à un objet du même nom dans le patron de conception MVC....

Le modèle objet de Qt Quick

Les API C++ de Qt reposent sur un modèle objet dont l’ancêtre commun est très souvent la classe QObject (voir le chapitre Les fondations de Qt - La classe QObject).

Les Types QML de Qt Quick suivent la même logique :

images/11EP02N1.png

Dans l’extrait du diagramme de classe de Qt Quick, nous trouvons entre autres, le Type QML Rectangle, qui fournit les capacités de tracer un rectangle dans une Scène. Le Type QML Rectangle a plusieurs propriétés dont les Types sont entre autres :

  • point (coordonnées X,Y),

  • rect (coordonnées X,Y ainsi que largeur et hauteur),

  • size (largeur et hauteur),

  • color (une couleur),

  • real (un nombre décimal).

Tous ces Types sont définis dans Qt Quick. Certains ont une correspondance directe avec des classes C++ de Qt Core, comme c’est le cas pour point (QML) et QPoint (C++). Une conversion automatique est faite entre les deux lors de l’intégration entre les classes C++ et Qt Quick.

La notion d’héritage existe aussi dans Qt Quick car le Type QML Rectangle hérite du Type QML Item. Celui-ci est un conteneur graphique sans apparence, il possède des attributs de positionnement et de dimensionnement, c’est grâce à lui que les Types QML qui en héritent peuvent être positionnés dans une scène. Le Type QML Item sait également gérer les événements...

Le document QML

Une scène ou un Type QML sont décrits dans le langage QML (Qt Markup Language ou Langage déclaratif de Qt, en français).

Le langage QML est inhabituel pour ceux qui ont l’habitude de coder en C ou un de ses dérivés comme C++, Java ou JavaScript. Il l’est beaucoup moins pour ceux qui connaissent le HTML ou JSON.

Un code QML se lit de haut en bas, les objets sont déclarés les uns après les autres, et, pour chaque objet, les attributs et fonctions sont déclarés successivement.

Un Type QML portera le nom du fichier dans lequel il est déclaré. Par exemple, si le fichier s’appelle UnSuperType.qml, le nom du Type QML sera UnSuperType.

Voici un exemple typique d’un document QML et la façon dont il est organisé en sections, toutes ne sont pas obligatoires et ne se retrouvent pas dans tous les fichiers QML :

images/11EP03N1.png

Observons dans le détail les différentes sections qui composent le document d’exemple ci-dessus.

1. La déclaration pragma (optionnelle)

Il arrive parfois qu’on trouve, comme dans certains compilateurs C et C++, une déclaration pragma dans les fichiers QML.

La plupart du temps il s’agit de la déclaration « pragma Singleton ».

Cette déclaration permet à elle seule de s’assurer que le Type QML que vous êtes en train de coder sera un Singleton, et donc qu’il ne sera instancié qu’une seule fois.

Pour savoir comment connecter des signaux d’un Singleton, reportez-vous à la section L’intégration avec C++ - Méthodes alternatives dans ce chapitre.

2. Les imports

La première directive importante est import. Elle permet de rendre disponibles des composants d’une bibliothèque de Qt, une bibliothèque personnelle ou encore des composants déclarés dans notre application. Elle nécessite deux paramètres : l’identifiant de la bibliothèque ou du composant ainsi que sa version. 

import QtQuick 2.7 

Cette ligne permettra l’importation de la version 2.7 de la bibliothèque de Types QML QtQuick. Si la version disponible sur l’environnement d’exécution est inférieure à 2.7, le chargement échouera.

Pour importer le Type QML Window qui appartient à Qt Quick...

Structure d’un projet Qt Quick

Les projets Qt Quick peuvent avoir différentes structures en fonction des choix que vous faites sur la mise à disposition des ressources, notamment des fichiers QML, ainsi que sur les performances que vous recherchez.

Un projet typique aura la structure suivante :

[Racine du projet] 
  main.cpp 
  qml.qrc/ 
    main.qml 
    MonType.qml 
  js.qrc/ 
    MaLib.js 
  images.qrc/ 
    logo.png 

La séparation des fichiers JavaScript, images et qml en plusieurs ressources Qt n’est pas indispensable, c’est une façon de structurer son projet.

Comme vous le constatez, il existe un fichier main.cpp qui est le point d’entrée de l’application et qui permet :

  • d’instancier une application Qt et de créer une run-loop,

  • de préparer l’environnement d’exécution,

  • d’instancier certaines classes C++,

  • d’exposer d’autres classes C++ en Types QML,

  • de démarrer le moteur Qt Quick et de lui fournir l’URL du point d’entrée QML (main.qml dans notre exemple),

  • d’entrer dans la run-loop de l’application.

La structure des fichiers QML et JavaScript dépend de vos propres choix ou conventions, il n’existe pas de contrainte au sein d’un...

Mettre en forme une scène

La partie la plus difficile de l’apprentissage de Qt Quick réside dans la mise en forme des Scènes. Une Scène est une déclaration QML dont l’objectif est de produire une interface graphique. Elle s’appuie nécessairement sur plusieurs Types QML, dont certains sont définis dans votre projet et les autres dans les bibliothèques de composants Qt Quick.

Il existe plusieurs façons de mettre en forme une Scène : le positionnement absolu, les ancres, les layouts et les positionneurs. Le principe des ancres est utilisé dans la plupart des frameworks graphiques modernes et celui des layouts est utilisé dans les frameworks de développement d’applications en mode fenêtré, comme Qt avec Qt Widgets.

Avant d’aller plus loin dans les explications, mettez-vous bien en tête qu’une application Qt Quick a, en principe, vocation à être exécutée sur des plateformes différentes allant du smartphone au PC, ou plus précisément du petit écran de 7 pouces au grand écran de 24 pouces et même davantage. Le fait que les résolutions soient parfois plus importantes sur les smartphones que sur les écrans de PC n’y change rien, le point le plus important est la surface de l’écran, et donc la lisibilité de l’interface graphique et la capacité de l’utilisateur à cliquer ou toucher un élément de l’interface graphique plutôt qu’un autre.

Qt Quick est pensé pour répondre à ces problématiques ergonomiques et vous permettre d’offrir à vos utilisateurs une interface adaptée à l’écran dont ils disposent. 

Il existe pour cela plusieurs stratégies que vous pouvez mettre en place dans vos applications, chacune utilisera une ou plusieurs des techniques présentées plus loin. Vous choisirez en fonction de vos besoins.

Les stratégies sont les suivantes :

  • Une scène différente pour chaque type d’appareil et/ou chaque taille d’écran. Ce dernier élément n’est pas évident à obtenir du système, mais il peut être en partie déduit à partir du nom du système d’exploitation...

Vue et contrôleur

Depuis l’arrivée de Qt Quick 2 une nouvelle façon d’organiser ses projets Qt Quick a été mise en place. Celle-ci ne remplace pas l’ancienne, mais s’y ajoute.

S’appuyant sur le modèle de conception MVC, elle consiste à séparer la Vue, ce que nous avons appelé Scène QML précédemment, et le contrôleur, c’est-à-dire le code associé à la Vue qui a pour rôle de gérer les événements liés à la celle-ci et à en changer l’état le cas échéant.

Dans Qt Quick cela se traduit par une séparation entre la Vue qui sera codée dans un fichier portant l’extension .ui.qml, et un contrôleur qui sera codé dans un fichier portant l’extension .qml.

Dans le fichier .ui.qml nous ne trouverons que des déclarations relatives à la mise en forme de la Scène QML, et dans le fichier .qml nous trouverons la logique métier contrôlant l’interface graphique.

Voici un exemple :

MainForm.ui.qml 
 
import QtQuick 2.0 
import QtQuick.Controls 2.15 
 
Item {  
  property alias valider: valider 
  property alias libelle: libelle 
 
  Button {  
    id: valider 
    x:...

États et transitions

Une des forces de Qt Quick est sa gestion des états. Les états d’une Scène QML sont gérés par le Type QML Item au travers des propriétés states qui contient la liste des états de la Vue, et state qui contient le nom de l’état courant.

Toute Scène QML a un « état de base » selon la terminologie Qt, c’est-à-dire l’état initial, nommé "" (chaîne vide).

L’état de base correspond strictement à la définition initiale des éléments de la scène QML. Par exemple :

MaVue.ui.qml 
 
Item { 
  Button { 
    id: bouton 
    x: 0 
    y: 0 
    text: "Etat suivant" 
  } 
  Text { 
    anchors.top: bouton.bottom 
    text: "Un libellé"  
    visible: false 
  } 
} 

L’exemple ci-dessus correspond à l’état de base de la Scène QML.

Déclarons maintenant un second état qui correspondra à un déplacement du bouton et l’apparition du champ de texte :

MaVue.ui.qml 
 
Item { ...

Animations et effets

Qt Quick est fortement orienté graphismes et encore davantage depuis la version 6 dont le moteur graphique 2D et 3D a été entièrement refait pour offrir les meilleures performances sur chaque plateforme d’exécution en utilisant les API propres à chaque système d’exploitation.

Cette inclination pour les graphismes se retrouve dans les API d’animation des objets intégrés aux scènes QML.

Il existe plusieurs façons de réaliser des animations permettant de déplacer ou redimensionner des objets, modifier les couleurs, et différentes propriétés « animables ».

Le principe d’une animation est de combler l’espace entre deux valeurs d’une propriété. Si une propriété a une valeur initiale de 0 et un autre état avec une valeur de 100, vous pouvez souhaiter passer de l’une à l’autre non pas d’un seul coup, mais progressivement. Pour vous épargner le code nécessaire à la modification progressive de la propriété, Qt Quick vous propose le mécanisme des animations.

Commençons avec un exemple... Comment réaliser un fondu vers le blanc d’un rectangle noir en deux secondes tout en passant la couleur d’un cercle progressivement du rouge au vert sur une durée de 580 millisecondes ?

La réponse tient en deux fois trois lignes de code...

Rectangle { 
  id: rect 
  color: "black" ; width: 200 ; height: 200 
 
  SequentialAnimation on color { 
    PropertyAnimation { duration: 2000 ; to: "white" } 
  } 
}  
  
Rectangle { 
  id: cercle 
  color: "red" ; width: 200 ; height: 200 ; radius: width/2  
  
  anchors { left: rect.right } 
  
  SequentialAnimation on color { //Animation portant 
                                   sur...

Dessin 2D avec le Canvas

Il est possible de dessiner directement en 2D dans une scène QML. Pour cela il faut utiliser l’objet Canvas et, littéralement, des fonctions de peinture.

Nous n’entrerons pas dans le détail de toutes les fonctions du Type QML Canvas mais illustrerons son fonctionnement au travers d’un exemple.

Dans notre exemple, nous dessinerons la célèbre fractale « le pou » de Mandelbrot pour illustrer le fonctionnement du Canvas.

images/11EP24N1.png

Voici tout d’abord le code source du fichier JavaScript qui permet de calculer la couleur d’un pixel :

mandelbrot.js 
//Constantes de base de l'algorithme de Mandelbrot 
const x_1       = -2.1 
const x_2       = 0.6 
const y_1       = -1.2 
const y_2       = 1.2 
const N_COLORS  = 3*256 
//Cette fonction calcule la couleur d'un pixel en fonction de ses coordonnées 
function calculeCouleurPixel(posX, posY, zoom, iterations_max) { 
  var c_r=posX/zoom+x_1 
  var c_i=posY/zoom+y_1 
  var z_r=0, z_i=0, i=0, tmp=0 
 
  do { //Calcul de la couleur de chacun des pixels
    tmp=z_r; 
    z_r=z_r*z_r-z_i*z_i+c_r; //y 
    z_i=2*z_i*tmp+c_i; //x 
    ++i; 
  } while(z_r*z_r+z_i*z_i<4&&i<iterations_max); ...

Contrôles riches

Si l’on admet l’hypothèse que Qt Quick est fortement orienté graphismes et que le développeur va privilégier ces API pour des applications éloignées du mode fenêtré classique, il faut tout de même observer que Qt Quick fournit également des Types QML inspirés des interfaces graphiques en mode fenêtré.

Le site web de Qt indique même que des travaux sont en cours pour procurer aux interfaces graphiques développées avec les API Qt Quick un aspect plus proche de l’apparence native des systèmes d’exploitation.

Ces Types QML sont regroupés dans l’API Qt Quick Controls et l’on y trouve notamment :

  • ApplicationWindow, une fenêtre décorée qui comprend également un en-tête et un pied de page, à la manière d’une fenêtre d’application Qt Widgets.

  • BusyIndicator, un composant du type sablier indique qu’un traitement est en cours.

  • Button et RoundButton, un bouton cliquable ou touchable.

  • Calendar, un calendrier annuel.

  • Checkbox, une case à cocher.

  • ComboBox, un menu déroulant.

  • DelayButton, un bouton qui réagit uniquement à un clic ou toucher prolongé. 

  • Dial, un bouton de sélection circulaire.

  • Dialog, une boîte de dialogue surgissante.

  • Drawer, un panneau qui peut être affiché...

Utiliser les styles graphiques

Voici déjà plusieurs années que les systèmes d’exploitation mobiles pour smartphones et tablettes ont permis aux développeurs du monde entier de créer des applications variées à l’aspect moderne. Beaucoup d’entre elles utilisent des composants riches tels que les boutons, listes déroulantes et autres cases à cocher.

Chaque système d’exploitation, iOS, Android et Windows pour ne citer que les plus célèbres a défini ses propres guidelines graphiques. Le principe des guidelines a probablement été poussé initialement par Apple dans une volonté farouche de son patron d’alors d’offrir aux utilisateurs une grande homogénéité dans l’expérience d’utilisation.

Durant un temps, les développeurs d’applications mobiles s’affrontaient à la machine à café pour savoir si c’était une bonne ou une mauvaise chose d’avoir des applications toutes identiques graphiquement ; et les développeurs d’applications Android se targuaient de pouvoir faire ce qu’ils voulaient avec leurs applications.

La morale de l’histoire est que c’est l’ergonomie qui a gagné la partie et que les guidelines graphiques se sont imposées aux développeurs d’applications, sur tous les systèmes d’exploitation mobiles....

Formes graphiques

Initialement, Qt Quick ne contenait qu’une seule forme primitive : le Rectangle, qui existe toujours et qui est également utilisé pour tracer des cercles. Les autres composants basiques sont Image et le libellé de texte (Text).

Nous avons vu dans une précédente section qu’il est possible de dessiner des formes géométriques grâce au Type QML Canvas2D.

Effets graphiques

Qt Quick est particulièrement performant lorsqu’il s’agit de réaliser, simplement, des animations et des effets graphiques. Il s’appuie pour cela sur un jeu d’API très bien structuré et les moteurs graphiques natifs des systèmes d’exploitation. 

Les API d’effets de Qt Quick viennent d’être réécrites pour correspondre à la nouvelle architecture d’abstraction graphique de Qt 6. Par conséquent, l’ancien module QtGraphicalEffects de Qt 5 est devenu obsolète. Les API sont toujours accessibles au travers du module Qt5Compat.GraphicalEffets. Si vous avez d’anciens projets qui utilisent ce module, vous devriez commencer à migrer vers les nouvelles API de Qt 6. Si vous démarrez un nouveau projet, lisez ce qui suit.

Nous allons reproduire le graphique 2D que nous avons fait précédemment, uniquement avec des Types QML et non plus en JavaScript.

La petite subtilité de ces composants est que le système de coordonnées est différent, la référence est au centre de la forme : (x,y) = (0,0) = (largeur/2,hauteur/2).

Voici le code QML :

import QtQuick 
import QtQuick.Shapes 
import QtQuick.Controls 
 
Window { 
  title: qsTr("Formes géométriques") 
  width: 400; height: 400;visible:...

Types globaux de Qt Quick

Les types de base que vous pouvez utiliser dans vos Types QML servent également de pont entre C++ et JavaScript.

Le langage QML propose les types classiques que sont bool, double, real, int et string qui trouvent leur équivalent dans tous les langages.

Les types suivants sont moins fréquents :

enumeration

Ce type est l’équivalent du type enum du langage C. Il est possible de déclarer des enumeration en QML :

QtObject { 
  enum MonEnum { 
    Ok, 
    PasOk, 
    PtetBien 
  } 
} 

list

Ce type correspond à une liste d’objets QML. Elle peut être accédée en JavaScript grâce aux crochets [] et un index entier commençant par 0. Toujours en JavaScript, la propriété length fournit le nombre d’éléments dans la liste. Pour ajouter une valeur à la liste dans ce même langage il suffit d’utiliser les crochets sans index :

maliste[] = UnObjetQML 

Une liste QML ne peut contenir que des objets QML, pas de types basiques QML ou JavaScript.

url

Ce type correspond à une URL (Uniform Resource Locator) qui permet de désigner l’emplacement d’une ressource comme un fichier sur le disque, dans une ressource Qt, ou encore un fichier sur un serveur web.

Les instances de la classe C++ QUrl sont automatiquement converties en objet du type url quand elles sont transmises à Qt Quick.

Une URL est convertie depuis une chaîne de caractère ou créée avec l’opérateur new en JavaScript :

QML : 
 
Image { 
  source: ":/images/logo" 
} 
 
Javascript : 
var monImage = new URL(":/images/logo") 

var

Ce type générique est assimilable à un variant (à ne pas confondre avec la classe C++ QVariant). En JavaScript il porte le même nom. On peut affecter n’importe quel autre type de valeur à une variable de ce type.

D’autres Types QML fréquemment utilisés sont définis par des modules de QML de Qt Quick. Parmi ceux-ci on trouve les types color, date, font, point, rect, size pour ne citer que les principaux.

Le type color peut se voir affecter une valeur directement...

Créer ses propres Types QML

Pour créer vos propres Types QML vous pourrez soit créer de nouveaux fichiers QML dans votre projet et utiliser ces nouveaux Types dans vos déclarations QML, soit créer un Type Qt en C++ et l’exposer à Qt Quick. Nous verrons cette technique dans la prochaine section.

Intéressons-nous à la création de Types QML sans classe C++.

Supposons que nous souhaitions créer un bouton rond qui peut afficher soit une image, soit du texte. Nous appellerons ce Type BoutonRond et l’utiliserons dans une scène QML.

Pour créer un nouveau Type appelé BoutonRond, nous devons créer un fichier nommé BoutonRond.qml. Comme c’est un composant réutilisable, nous ne séparons pas la vue et le contrôleur dans des fichiers séparés, cette architecture est réservée aux vues métier.

Rappel : le nom du Type QML est déterminé par le nom du fichier. Il n’y a aucun moyen de définir un nom pour le Type dans la déclaration QML. Il ne faut pas non plus confondre le nom du Type QML qui sera utilisé pour une déclaration dans un autre Type, et son identifiant qui est défini par la propriété id.

MonProjet/objets/BoutonRond.qml 
 
import QtQuick 
Item { 
  id: root 
  property string label:...

L’intégration avec C++

Il est important de comprendre que Qt Quick est, par essence, une technologie de création d’interfaces graphiques. Il faut donc la comparer à Qt Widgets. Ces deux technologies s’appuient sur les mêmes API : dessin 2D et 3D, réseau, animations, QObject, etc.

La partie métier d’une application peut être codée soit en JavaScript dans la vue QML, soit en C++ dans des classes Qt. La différence entre les deux se situe en particulier au niveau des performances : une application codée en C++ est toujours plus performante que si elle était codée en JavaScript dans un Type QML.

De plus, certaines API ne sont tout simplement pas accessibles en QML, c’est le cas d’une grande partie des API de bases de données (même si nous le verrons dans la section Stocker des données, il est possible de connecter un Type QML à une base de données), des API réseau et, surtout, à vos propres bibliothèques C++ ou des bibliothèques C++ développées par des tiers et dont vous avez besoin dans vos programmes.

Dans cette section, nous nous intéresserons à deux cas de figure : une application métier « standard » avec des classes C++ exposées et consommées en QML, ainsi que l’intégration de bibliothèques C dans une application Qt Quick.

1. Exposer des classes C++ en QML

Si un Type QML n’est pas créé directement en QML comme nous l’avons vu dans la section précédente, il doit être créé en C++. Le point le plus important est qu’il doit être utilisable par le MétaObjet comme un Type Qt.

Pour bien comprendre la notion de Type Qt, reportez-vous au chapitre Les fondations de Qt - Les Types Qt, ainsi que la section Les propriétés dans le même chapitre.

Résumons rapidement les caractéristiques clé d’un Type QML :

  • Il doit pouvoir être déclaré, cela suppose un constructeur par défaut.

  • Ses variables membres doivent pouvoir être affectées grâce à des propriétés.

  • Il peut envoyer des signaux.

  • Il peut recevoir des signaux, donc avoir un ou plusieurs slots.

  • On peut appeler des fonctions simples....

Stocker des données

Il existe plusieurs cas d’usage liés au stockage de données au sein d’une application : les données métier qui sont souvent stockées dans une base de données, les données de configuration pour lesquelles Qt fournit une classe QSettings qui s’intègre parfaitement avec le système d’exploitation, et des données contextuelles qui n’entrent dans aucune des deux catégories précédentes, par exemple les dimensions et la position des fenêtres de l’application.

En QML, il existe différents moyens de répondre à ces besoins.

1. Le Type QML Settings

Le Type QML Settings correspond à la classe QSettings en C++. Il permet d’enregistrer et d’obtenir des valeurs correspondant à des réglages utilisateurs et toutes sortes d’informations nécessaires au fonctionnement de l’application.

Les réglages sont stockés différemment d’un système d’exploitation à un autre. Par exemple, sous macOS, ils sont enregistrés dans un fichier .plist dans le répertoire des préférences de l’utilisateur ($HOME/Library/Preferences). Sous Windows, il s’agit d’une entrée dans la base de registre dans la racine HKEY_CURRENT_USER.

Le chemin d’accès, et parfois le nom de fichier des réglages, dépend de la configuration appliquée sur l’objet QCoreApplication. Trois fonctions permettent d’influencer ce nommage, comme dans l’exemple ci-dessous :

QCoreApplication::setApplicationName("Mon application"); 
QCoreApplication::setOrganizationName("Alefbet"); 
QCoreApplication::setOrganizationDomain("net.alefbet"); 

Grâce à ces appels...

Créer des requêtes réseau

Il n’existe pas dans Qt Quick de composants riches pour réaliser des requêtes réseau mais il est tout à fait possible de créer des contrôleurs en C++, de les exposer en QML et de les utiliser ensuite dans Qt Quick.

Cependant, Qt Quick offre un certain nombre d’API qui permettent de réaliser des choses puissantes au travers du réseau. Observons quelques exemples.

1. Utiliser des composants QML distants

Dans une approche fortement orientée client léger, et pour faciliter la mise à jour de vos applications, vous pourriez choisir de disposer une partie des fichiers QML de vos applications sur un serveur web. Ainsi, une partie de l’application sera chargée à la volée depuis le réseau, éventuellement depuis Internet.

Supposons que vous ayez un fichier nommé FenetreControle.qml sur un serveur web. L’URL de chargement de ce fichier pourrait être https://serveur/composants/FenetreControle.qml.

Dans un premier temps, pour tester le chargement et le fonctionnement du composant, vous pouvez utiliser le programme nommé qml. Il est disponible sur tout appareil ayant installé la suite d’outils Qt. Pour tester le composant distant, tapez ceci :

qml http://serveur/composants/FenetreControle.qml 

L’intégration dans l’application Qt Quick passe par un Type QML spécifique nommé Loader. Il s’utilise comme un type dérivant du Type Item, il n’a pas d’apparence, ni de métier propre, il prendra l’apparence et le métier...

Autres API

Qt Quick comprend beaucoup d’autres composants QML et nous ne pouvons pas tous les décrire, cependant nous en verrons et utiliserons d’autres dans les pages de ce livre.

Enfin, le chapitre de ce livre intitulé Application de A à Z présente un projet complet comprenant des classes C++ et des Types QML dont certains n’ont pas été abordés dans ces pages.

Qt Design Studio

Avec l’arrivée de Qt 6, l’édition des Vues Qt Quick a été séparée dans un outil dédié nommé « Qt Design Studio ». Il n’est désormais plus possible de créer graphiquement des vues QML dans Qt Creator comme on le fait pour les Vues Qt Widgets.

Cela implique de prendre en main un nouvel outil qui a beaucoup de points communs avec Qt Creator, mais également quelques singularités que nous vous proposons de découvrir dans cette section.

Qt Design Studio a été pensé, et est vendu, comme un outil de conception assistée pour une équipe réunissant des développeurs et des concepteurs d’interfaces graphiques.

L’idée maîtresse est la suivante : partant du constat pertinent que les échanges entre un concepteur d’interface graphique et un développeur sont sujets à de nombreuses itérations et malentendus, l’outil doit leur permettre de travailler avec des supports communs en gestion de code source pour maîtriser au mieux ces allers-retours.

Comparons, un peu grossièrement, deux situations identiques, l’une avec Qt Creator uniquement et l’autre avec Qt Design Studio.

Le scénario implique quatre acteurs : le client qui a un besoin, l’architecte qui analyse le besoin et formalise les spécifications, le développeur qui code l’application et le concepteur des interfaces graphiques qui réalise les maquettes et la charte graphique de l’interface utilisateur.

Le client et l’architecte échangent finement sur le besoin et l’architecte formule les spécifications dans un langage intermédiaire entre le langage commun employé par le client, et le langage technique utilisé par les experts.

Durant la phase de réalisation, le travail est organisé en plusieurs phases :

  • Le développeur commence à coder l’application, il réalise tout d’abord les objets métier, les bases de données et les contrôleurs.

  • En parallèle, le concepteur d’interfaces graphique dessine des vues dans son outil de conception favori. Notez que la suite d’outils de Qt n’inclue aucun outil de conception d’interface...

Convertir un projet d’interface graphique en application

Avec Qt Design Studio nous avons créé la partie graphique de l’application, à savoir les Vues.

En principe, dans la mesure où Qt Design Studio utilise CMake pour la gestion des projets, et que Qt Creator utilise également cet outil, l’importation dans Qt Creator est très simple : il suffit d’ouvrir le fichier CMakeLists.txt.

Pour cela, ouvrez Qt Creator et cliquez sur le menu Fichier - Ouvrir un fichier ou un projet....

Sélectionnez ensuite le fichier CMakeFiles.txt dans le navigateur de fichiers et le projet va s’ouvrir dans Qt Creator.

Lorsque vous exécutez le programme, une compilation est déclenchée et, à la fin, c’est le programme compilé qui est exécuté.

Si vous sélectionnez le fichier .qmlproject au lieu du fichier CMakeFiles.txt vous ouvrirez le projet en mode édition d’interface graphique et ne pourrez accéder qu’au contenu graphique. Lorsque vous exécuterez le programme, celui-ci ne sera pas compilé mais c’est l’utilitaire qml qui sera exécuté et vous donnera un simple aperçu de l’interface graphique, comme dans Qt Design Studio.

Créer les contrôleurs et tester l’application

La suite des opérations se déroule dans Qt Creator, veillez à ne pas confondre les deux applications.

1. Le contrôleur

Le Contrôleur de la Vue Screen01.ui.qml correspond au fichier Screen01.qml. Ce fichier, contrairement au précédent, ne contient aucun code QML déclaratif. Il contient uniquement du code JavaScript qui va permettre d’interagir avec la scène et l’environnement.

Ce fichier n’existe pas encore car Qt Design Studio ne s’occupe que des Vues. Nous allons maintenant créer ce Contrôleur. Pour cela, dépliez le dossier de l’application, puis le dossier Content, puis faites un clic droit sur le dossier Content situé à l’intérieur :

images/11EP54N1.png

 Dans le menu déroulant qui apparaît, choisissez Nouveau... puis Nouveau fichier....

images/11EP55N1.png

 Sélectionnez Qt et QML File (QtQuick 2).

 Donnez ensuite le nom Screen01Controleur.qml à votre fichier et validez le formulaire.

Ce fichier correspond donc au Contrôleur de la Vue créée dans Qt Design Studio. Nous allons maintenant pouvoir saisir du code métier.

Pour intégrer ce nouveau fichier à votre application, il vous faut modifier quelques fichiers :

content/App.qml : remplacer Screen01 par Screen01Controleur de cette façon :

Window { 
  width: mainScreen.width 
  height: mainScreen.height 
  visible: true 
  title: "QtDesignStudio2" 
 
  Screen01Controleur { 
    id: mainScreen 
  } 
} 

content/CmakeLists.txt : ajouter Screen01Controleur.qml à la liste :

qt_add_library(content STATIC) 
qt6_add_qml_module(content 
   URI "content" 
   VERSION 1.0 
   QML_FILES 
      App.qml 
      Screen01.ui.qml  
      Screen01Controleur.qml 
   RESOURCES 
      fonts/fonts.txt 
) 

Initialisation de l’application

Nous allons maintenant implémenter le code JavaScript qui va nous permettre de peupler notre liste déroulante....