Sur cette page

Machine à café

Une application « Qt Quick » dotée d'une interface utilisateur personnalisée basée sur les états.

Interface utilisateur d'une machine à café affichant le bouton « Commencer »

Cette application illustre une approche multiplateforme, adaptée à différentes tailles d’écran et responsive, pour la mise en œuvre d’une interface utilisateur classique destinée à la commande de produits.

Exécution de l'exemple

Vous pouvez exécuter l'exemple à partir de :

Présentation de l’interface utilisateur

Cette section vous guide à travers le parcours utilisateur type de l’application.

Sélection d’une recette

Liste des variétés de café disponibles

L'application « Machine à café » vous permet de choisir un type de café et vous indique le nombre de cafés de ce type qu'il vous reste à commander.

Personnalisation du café

Curseurs permettant de personnaliser la proportion du mélange de café

Une fois la recette sélectionnée, l'application affiche la composition du mélange de café :

  • café infusé
  • lait chaud
  • mousse de lait
  • sucre

Ces proportions peuvent être modifiées à l'aide de curseurs.

Affichage de l'état de la préparation

Inviter l'utilisateur à insérer un gobelet

Une fois que l'utilisateur a confirmé que la tasse est bien placée dans la machine, la préparation commence.

Une fois la préparation lancée, l'application affiche une animation illustrant le processus de préparation.

Le café est prêt

Une fois le processus de préparation terminé, l’application affiche pendant quelques secondes une tasse de café contenant le mélange souhaité, avant de revenir à la page d’accueil.

Fonctionnement

Nous expliquons ici comment ces fonctionnalités sont mises en œuvre.

Adaptation à la taille et à l'orientation de l'écran

L’objet racine de la fenêtre de l’application dispose de valeurs initiales pour la hauteur et la largeur, qui seront utilisées comme dimensions de la fenêtre sur les plateformes de bureau. L’ QWindow::AutomaticVisibility par défaut garantit que la fenêtre s’affichera en mode maximisé ou en plein écran sur les plateformes qui l’exigent, telles que les plateformes mobiles.

ApplicationWindow {
    visible: true
    width: 1000
    height: 600
    title: qsTr("Coffee")

    background: Rectangle {
        color: Colors.currentTheme.background
    }

À partir de là, les objets enfants de l’ ApplicationWindow récupèrent la taille de l’ ApplicationWindow e afin de déterminer leurs propres tailles en conséquence.

L’application utilise l’ GridLayout dans tous les composants de la page d’application afin de s’adapter facilement aux changements d’orientation de l’écran.

Affichage en mode paysage de la page de sélection des machines à café sur Android

{L'écran passe en mode paysage lorsque l'orientation de l'appareil Android est en mode paysage}

Page de sélection des machines à café en mode paysage sous Windows

{Le mode paysage est l’orientation par défaut sur le bureau Windows}

Remarque : sur la version bureau, la largeur doit être supérieure à la hauteur.

L'application utilise le type QML « StackView » pour afficher les différentes pages de l'application. L'StackView, qui gère les différents composants de page, est implémentée dans « ApplicationFlowForm.ui.qml ».

La navigation d’une page à l’autre déclenche un changement d’état dans ` ApplicationFlow.qml `, où les modifications de propriétés nécessaires sont gérées par le type QML ` PropertyChanges ` :

states: [
    State {
        name: "Home"
        PropertyChanges {
            target: toolbar
            backButton.opacity: 0
            backButton.enabled: false
            themeButton.opacity: 0
            themeButton.enabled: false
            logo.sourceSize.width: 70
            logo.sourceSize.height: 50
        }

Les animations qui se produisent lors de ces changements d’état sont implémentées à l’aide de Transition et de PropertyAnimation à l’intérieur du composant StackView dans ApplicationFLowForm.ui.qml.

Implémentation de la page d’accueil

L’application démarre en affichant la page Home à l’utilisateur en tant qu’élément initial dans le StackView:

StackView {
    id: stack
    anchors.top: parent.top
    anchors.bottom: parent.bottom
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.topMargin: parent.height / 20

    pushEnter: Transition {
        PropertyAnimation {
            property: "x"
            from: stack.width
            to: 0
            duration: 400
        }
    }

Le composant Home est structuré en plaçant le composant Item comme objet racine avec une machine à états et les alias de propriétés appropriés, suivi de GridLayout. Ce même type de structuration sera utilisé dans tous les composants de pages de l’application.

La page Home affiche l’image d’une tasse à café surmontée du logo Qt, le titre « Coffee Machine », une légende contenant une brève description accrocheuse de ce à quoi l’utilisateur peut s’attendre, ainsi qu’un bouton « getStartedButton ».

L’utilisateur peut passer à l’étape suivante en appuyant sur le bouton « getStartedButton » ; la fonction du bouton « onClicked » est implémentée dans ` ApplicationFlow.qml` :

getStartedbutton.onClicked: {
    applicationFlow.state = "Coffee-selection"
    applicationFlow.stack.pushItem(applicationFlow.choosingCoffee, {appFlow: applicationFlow})
}

Cela déclenchera le passage à l’état « Coffee-selection » dans ApplicationFlow.qml et affichera le composant « choosingCoffee » par-dessus le composant Home dans StackView.

Mise en œuvre de la sélection du café

La page « Sélection du café » ChoosingCoffee.qml s’affiche ; l’utilisateur y voit 4 options de café différentes parmi lesquelles choisir. Ces options sont affichées sous forme de composants CoffeeCards situés à l’intérieur du composant GridLayout sur ChoosingCoffee.qml:

GridLayout {
    id: cards
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.top: parent.top
    rowSpacing: 20
    columnSpacing: 20
    CoffeeCard {
        id: cappuccino
        coffeeName: "Cappuccino"
        ingredients: "Milk, Espresso, Foam"
        time: 2
    }
    CoffeeCard {
        id: latte
        coffeeName: "Latte"
        ingredients: "Coffee, Foam"
        time: 3
    }
    CoffeeCard {
        id: espresso
        coffeeName: "Espresso"
        ingredients: "Milk, Espresso"
        time: 2
    }
    CoffeeCard {
        id: macchiato
        coffeeName: "Macchiato"
        ingredients: "Milk foam, Espresso"
        time: 4
    }
}

L’implémentation de la carte « CoffeeCard » se trouve à l’adresse CoffeeCard.qml.

Ces cartes peuvent s’afficher sous forme de grille ou de ligne, en fonction des propriétés de largeur et de hauteur d’écran disponibles que l’objet racine « ApplicationWindow » suit et transmet à « ChoosingCoffee.qml », puis à « GridLayout » via la machine à états.

CoffeeCards varient en termes de noms, de temps de préparation, d’ingrédients et du nombre de tasses disponibles à ce moment-là.

Sur cette page, l’utilisateur peut également modifier le thème de l’application pour la première fois en appuyant sur le petit bouton en forme de soleil situé dans le coin supérieur droit de l’écran. Appuyer sur le bouton de thème appelle la fonction ` themeButton ` dans ` ApplicationFlow.qml` :

function themeButton() {
    if (Colors.currentTheme == Colors.dark) {
        Colors.currentTheme = Colors.light
    } else {
        Colors.currentTheme = Colors.dark
    }
}

Cette fonction modifie la propriété ` currentTheme ` de ` Colors.qml ` et les couleurs de l’application sont automatiquement mises à jour via les liaisons de propriétés. Toutes les couleurs utilisées dans l’application se trouvent dans ` Colors.qml`.

Si le thème passe en mode clair, l’icône de changement de thème prend la forme d’un croissant de lune.

Appuyer sur l’une des fiches de café déclenche un changement d’état au sein de ` AbstractButton ` dans ` CoffeeCard.qml `, ce qui déclenche à son tour ` NumberAnimation ` via ` Transition` :

AbstractButton {
    width: parent.width - 2
    height: parent.height - 2
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.verticalCenter: parent.verticalCenter
    id: button
    hoverEnabled: true
    checkable: true
    enabled: (root.cupsLeft != 0) ? true : false
    transitions: Transition {
        NumberAnimation {
            properties: "scale"
            duration: 50
            easing.type: Easing.InOutQuad
        }
    }

Cela réduit la taille de la carte de café sélectionnée et colore ses bords en vert, indiquant ainsi à l’utilisateur que le café a bien été sélectionné.

La propriété « button » de chaque carte de café, alias de la fonction onClicked, est liée à une fonction située dans ApplicationFlow.qml. Lorsque l’utilisateur clique sur l’une des cartes de café, la fonction dont le nom correspond à l’option de café choisie est appelée. La fonction définit l’état de ApplicationFlow.qml sur Settings, ajoute un nouveau composant à la StackView et définit les propriétés des ingrédients en conséquence.

Mise en œuvre des paramètres de café

Sur cette page, l’utilisateur peut personnaliser son café selon ses préférences en ajustant les types QML personnalisés Slider. La modification de la valeur des curseurs affectera les niveaux de liquide visibles à l’intérieur de la tasse à café ; cela est rendu possible grâce à la liaison de la hauteur des images de liquide dans Cup.qml aux valeurs des curseurs correspondants.

Les valeurs des curseurs de la page Settings sont stockées dans CoffeeConfig en vue d’une utilisation ultérieure à l’aide du type QML Synchronizer.

Synchronizer {
     sourceObject: settingsForm.coffeeConfig
     sourceProperty: "sugarAmount"
     targetObject: settingsForm.sugarSlider
     targetProperty: "value"
}

Un clic sur le bouton « Démarrer » fait passer l’état de ApplicationFlow.qml à « Insérer », et l’application affiche Insert.qml.

Mise en œuvre de l’insertion de la tasse

Sur cette page, l’utilisateur est invité à placer sa tasse sur la machine avant que le processus d’infusion puisse commencer.

Appuyer sur le bouton « Continue » (Insérer la tasse) redirige l’application vers la page « Progress » (Insérer la tasse).

Mise en œuvre de la préparation du café

La page de progression affiche une tasse à café et une barre de progression qui, chacune à leur manière, indiquent en temps réel l’avancement du processus d’infusion.

Une fois remplie, la tasse de café affichera exactement la même configuration que celle sélectionnée par l’utilisateur sur la page Settings. Ceci est assuré en liant les variables de propriété Cup aux valeurs correspondantes enregistrées dans ApplicationFlow.qml.

L’animation de remplissage de la tasse de café est gérée par les moteurs d’état Transition et SmoothedAnimation.

Cup {
    id: cup
    Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
    state: "0"
}

L'animation de la barre de progression est mise en œuvre à l'aide de Behavior.

Behavior on greenBar.width {
    SmoothedAnimation {
        easing.type: Easing.Linear
        velocity: (progressForm.contentItem.width / progressForm.brewTime) * 1000
    }
}

Timer se chargera de mettre à jour l'état de l'application une fois l'infusion terminée.

Timer {
    id: timer
    interval: progressForm.brewTime
    running: true
    onTriggered: {
        progressForm.appFlow.onFinished()
    }
}
Implémentation de la page « Café prêt »

La page « Prêt » affiche une tasse de café remplie selon la configuration choisie par l'utilisateur, accompagnée du texte « Votre café est prêt » et d'une icône en forme de coche.

Lorsque cette page s’affiche, une fonction Timer se lance et, une fois l’intervalle défini écoulé, l’utilisateur est redirigé vers Home.qml.

Fichiers source

Tests d’interface graphique avec Squish

Cette application est fournie avec des tests d'interface graphique Squish destinés à Qt pour Android. Les tests sont réalisés avec Squish pour Qt, écrits en Python et se trouvent dans le répertoire de test de l'application.

Lorsque vous utilisez Squish pour Qt sur Android, veillez à utiliser le hook intégré à Qt et à rediriger le port Squish via adb. Si vous obtenez l’erreur « Impossible de charger la bibliothèque » et que l’ dlopen échoue, désactivez QT_USE_TARGET_ANDROID_BUILD_DIR dans la configuration CMake, ou supprimez-le de Projects->Build Settings->CMake->Current Configuration dans Qt Creator.

Si vous ne disposez pas d’une licence Squish, vous pouvez bénéficier d’un essai gratuit.

Exemple de projet sur code.qt.io

Voir également Tous les exemples Qt.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.