Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Définir des panneaux avec onglets

Accès rapide :
Le composant SwipeView
Le composant TabBar
Lier le composant SwipeView avec le composant TabBar

Le composant SwipeView

Ce composant graphique permet d'afficher plusieurs panneaux. A un instant donné, seul un panneau est affiché, mais il est possible de passer au panneau suivant, ou précédent, d'un mouvement de doigt horizontal vers la gauche ou la droite. Ce mouvement est appelé un « swipe » (glisser en anglais).

Comment réaliser un mouvement de Swipe ?

Voici un exemple d'utilisation de ce composant (testez bien les changements de panneaux).

SwipeView {
    id: swipeView
    anchors.fill: parent

    Repeater {
        model: 3
        
        Pane {
            Text {
                text: "Panneau " + model.index
                horizontalAlignment: Qt.AlignHCenter
            }
        }
    }
}
cet exemple utilise un composant « Repeater » afin de simplifier la production des trois panneaux. Vous pouvez, bien entendu, ne pas utiliser le « Repeater » et mettre à la place trois panneaux distincts.

Le composant TabBar

Traditionnellement, le composant « SwipeView » est couplé avec un composant « TabBar ». Ce dernier afficher les onglets permettant le changement de panneau par simple appuie sur un onglet donné. Voici un exemple d'utilisation.

TabBar {
    TabButton {
        text: "Premier"
    }
    TabButton {
        text: "Second"
    }
    TabButton {
        text: "Troisième"
    }
}

Voici le résultat graphique obtenu en ajoutant le composant « TabBar » en dessous du composant « SwipeView ». Vous noterez que si vous utilisez le thème « Fusion » (c'est le thème par défaut sous Linux), le visuel ne sera pas terrible.

Un composant TabBar dessiné avec le thème Fusion.

Dans ce cas, je vous conseille de passer avec un thème adapté à une application tactile et pourquoi pas le thème « Material ». Voici le code permettant d'appliquer ce thème au démarrage de l'application.

 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
import sys

from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QUrl
# N'oubliez pas cet import, si vous souhaitez changer de style.
from PySide6.QtQuickControls2 import QQuickStyle

# On démarre l'application QML et l'engine
app = QGuiApplication([])
engine = QQmlApplicationEngine()

# On change le style utilisé par l'application
QQuickStyle.setStyle("Material")

# On charge le fichier QML à présenter
engine.load(QUrl("Tabs.qml"))

# On lance la boucle de traitement des événements
sys.exit(app.exec())

Et voici le nouveau visuel produit : pour ma part, je trouve ça beaucoup mieux.

Un composant TabBar dessiné avec le thème Material.
le fait que le texte des onglets soit ici écrit en majuscules et lié au choix du thème graphique. Sous « Fusion », cela n'était pas le cas.

Lier le composant SwipeView avec le composant TabBar

Les deux composants précédents sont prévus pour fonctionner ensemble, mais faut-il encore les lier. Si vous changez de panneau via un mouvement de « Swipe », il faudra que le « TabBar » se synchronise et inversement.

Dans les deux cas, c'est la propriété currentIndex qu'il faut lier à l'autre composant. Il faut donc aussi identifier les deux composants graphiques : dans notre exemple swipeView et tabBar. Voici le code final permettant de lier les deux composants.

import QtQuick
import QtQuick.Controls

ApplicationWindow {
    title: "Mise en oeuvre d'onglets en QML"
    width: 400
    height: 400
    visible: true

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex
    
        Repeater {
            model: 3

            Pane {
                Text {
                    text: "Panneau " + model.index
                    anchors.horizontalCenter: parent.horizontalCenter
                }
            }
        }
    }

    footer: TabBar {
        id: tabBar
        currentIndex: swipeView.currentIndex

        TabButton {
            text: "Premier"
        }
        TabButton {
            text: "Second"
        }
        TabButton {
            text: "Troisième"
        }
    }
}
le fait que les deux composants réagissent de manière réciproque sur un changement de panneau, n'est pas un problème. Le signal associé ne déclenche que s'il y a changement de valeur (et pas simplement affectation d'une valeur). Il n'y aura donc pas de déclenchement circulaire de signaux, ce qui aurait été extrêmement problématique.