Tutoriel Qt Quick : module 2  les composants

| Traducteur : Louis du Verdier | Qt Developer Network |

Dans la partie précédente ont été faits les premiers pas avec QML (Qt Meta-object Language). Lors de cette deuxième étape dans la découverte de ce langage, on étudiera les composants personnalisés, les alias et les id, afin de rassembler suffisamment de connaissances pour pouvoir créer une première application QML.

- Titre : Tutoriel Qt Quick : module 2  les composants

- Auteurs : Traducteur : Louis du Verdier, Qt Developer Network

- Parution : 28 juillet 2011

- Mise à jour : 1 août 2011

- Licence : Copyright ® 2011 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Création d'un composant personnalisé

- II. Les alias et les id de propriétés

- III. Divers

I - Création d'un composant personnalisé

Un composant est toujours défini dans un fichier qui a pour nom de base le nom du composant et l'extension .qml. Par exemple, le composant Photo sera défini dans le fichier Photo.qml. Un nom de composant commence toujours par une lettre majuscule, à laquelle s'ajoutent zéro ou plusieurs lettres (majuscules ou minuscules), nombres et tirets bas.

On effectue les étapes suivantes pour créer le composant Photo :

- copie du contenu du fichier QML BasicSteps 4.qml dans le fichier Components.qml ;

- création d'un nouveau fichier QML Photo.qml dans le même répertoire que Components.qml ;

- copie du Rectangle de la première photo dans Photo.qml.

On est assez proche du composant Photo final : on doit juste introduire des propriétés pour les paramètres du composant Photo, comme la position x, le fichier image et le titre de l'image. On va assigner des valeurs concrètes à ces propriétés dans l'instanciation du composant Photo dans Components.qml.

On n'a rien à effectuer pour la position x parce qu'un Rectangle a déjà la propriété x. On retire seulement le fragment de code x: 0;. Tant qu'on y est, on retire également le fragment de code y: 0 parce que la valeur par défaut de la position y est, de toute façon, 0.

Pour le fichier image et le titre, on introduit deux propriétés, imageFile et imageTitle, au début du Rectangle. Finalement, on remplace la valeur de source dans Image par imageFile et la valeur de text dans Text par imageTitle. Avec tous ces changements, le composant Photo ressemble à ceci :

// File: Photo.qml
import Qt 4.7

Rectangle {
property url imageFile
property string imageTitle

width: frameSize; height: frameSize
color: frameColor

Image {
x: leftMargin; y: topMargin
source: imageFile
}

Text {
x: 0; y: frameSize - bottomMargin
text: imageTitle
font.pixelSize: fontSize
width: frameSize; horizontalAlignment: Text.AlignHCenter
height: bottomMargin; verticalAlignment: Text.AlignVCenter
}
}

On peut désormais utiliser le nouveau composant Photo dans le document QML principal, Components.qml (anciennement BasicSteps_4.qml), qui affiche trois photos côte à côte. Le code résultant ressemble à cela :

// File: Components.qml
import Qt 4.7

Rectangle {
property int frameSize: 300
property int leftMargin: 10
property int topMargin: 25
property int bottomMargin: 65
property int fontSize: 20
property color frameColor: "#FFF8DC"  // cornsilk

width: 3 * frameSize; height: frameSize

Photo {
x: 0
imageFile: "voringsfossen1.jpg"
imageTitle: "Voringsfossen"
}

Photo {
x: frameSize
imageFile: "bergen.jpg"
imageTitle: "Bergen"
}

Photo {
x: 2 * frameSize
imageFile: "cotton_grass.jpg"
imageTitle: "Cotton Grass"
}
}

Dans les trois instances du composant Photo, on assigne uniquement des valeurs à trois paramètres : la position x, le fichier image et le titre de l'image. Les valeurs des autres propriétés telles que frameSize ou leftMargin sont propagées depuis l'instance racine de Rectangle jusqu'aux instances de Photo et leurs instances enfants, Image et Text.

On peut dès lors admirer notre travail en lançant la visionneuse QML dans le répertoire de Components.qml et de Photo.qml :

qmlviewer Components.qml &amp;

Comment la visionneuse QML sait-elle où trouver le composant Photo ? Par défaut, elle cherche un fichier QML d'extension .qml avec le même nom de base que le composant dans le répertoire où elle est lancée. Dans ce cas, elle trouve le fichier Photo.qml. On montrera dans le module Modules comment placer les composants dans d'autres répertoires que celui-ci.

II - Les alias et les id de propriétés

On peut toujours améliorer un petit peu le composant Photo. L'URL du fichier image et le titre de l'image sont stockés en deux endroits pour chacun. Le fichier image est stocké dans la propriété imageFile, tout juste introduite, et dans la propriété source de Image. De même, le titre de l'image est stocké dans imageTitle et dans text de Text. Cela signifie que la mémoire est allouée deux fois pour le fichier image et deux fois pour le titre de l'image. Ce n'est pas un gros problème pour cet exemple. Si, cependant, les objets dupliqués étaient plus gros, cela deviendrait problématique. Un autre souci que l'on a est que l'on doit garantir que les deux occurrences du fichier image et du titre de l'image soient synchronisées. De même, c'est peu gênant pour ce petit programme, mais cela devient délicat pour des programmes plus gros.

Heureusement, les alias de propriété viennent à notre secours. Un alias de propriété dit que deux propriétés partagent la même valeur et la stockent dans un seul espace en mémoire. L'équivalent C++ serait une référence à une variable existante. La syntaxe d'un alias de propriété est :

property alias property1: property2

où property1 est l'alias venant d'être introduit et property2, la propriété existante sur laquelle on souhaite faire l'alias.

Dans le composant Photo, on veut définir imageFile en tant qu'alias de la propriété source de Image et imageTitle en tant qu'alias de la propriété text de Text. Il subsiste un tout petit problème : comment peut-on aborder en une unique fois le problème des propriétés source et text ? S'il y avait plusieurs composants Image ou Text dans le composant Photo (un scénario assez commun, d'ailleurs), on n'aurait aucun moyen de les distinguer.

La propriété spéciale QML id résout ce problème. La propriété id est le nom ou identificateur unique d'une instance d'un composant. En utilisant la notation instName.propName, on peut accéder à la propriété propertyName de l'instance dont la propriété id est de valeur instName.

Dès lors, on peut enfin introduire les deux alias de propriété et les utiliser. Dans Photo.qml, on remplace les deux définitions de propriété des lignes 5 et 6 par :

property alias imageFile: photo.source
property alias imageTitle: title.text

On assigne l'identificateur photo au composant Image et retire la ligne pour la propriété source. Ainsi, Image ressemble à ceci :

Image {
id: photo
x: leftMargin; y: topMargin
}

De même, on assigne les identificateurs title au composant Text et retire la ligne pour la propriété text. Ainsi, Text ressemble à ceci :

Text {
id: title
x: 0; y: frameSize - bottomMargin
font.pixelSize: fontSize
width: frameSize; horizontalAlignment: Text.AlignHCenter
height: bottomMargin; verticalAlignment: Text.AlignVCenter
}

Le code complet du composant Photo modifié peut être trouvé dans Photo.qml.

Il est important de noter que la valeur de id n'est pas enfermée par des guillemets. Elle n'est tout simplement pas mise sous forme de citation.

III - Divers

- Module 1  les bases

- Accueil du tutoriel

Merci à Thibaut Cuvelier et Claude Leloup pour leur relecture !