Sur cette page

Qt Quick Layouts - Exemple de mise en page adaptative

Illustre comment utiliser les éléments LayoutItemProxy pour créer une interface utilisateur adaptative.

Cet exemple montre comment utiliser les LayoutProxyItems en combinaison avec des mises en page pour créer des mises en page adaptatives.

Exécution de l'exemple

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

Création d’éléments

Le type ` LayoutItemProxy ` permet d’utiliser le même élément dans différentes mises en page, bien qu’une seule mise en page puisse être visible à la fois. Cela permet de créer des mises en page réactives qui s’adaptent à la taille de la fenêtre ou de l’écran.

Deux fenêtres illustrant une mise en page adaptative : affichage étroit avec une grille compacte, affichage large avec une barre latérale

Nous devons d’abord définir tous les éléments qui doivent apparaître à un moment ou à un autre dans notre interface utilisateur. Nous utilisons un `AnnotatedRect`, qui est un simple rectangle auquel du texte a été ajouté.

Rectangle {
    id: contentItem
    Layout.fillWidth: true
    implicitHeight: grid.implicitHeight
    implicitWidth: grid.implicitWidth
    color: "#00414A"

    GridLayout {
        id: grid
        anchors {
            fill: parent
            margins: 8
        }
        columns: Math.max(1, Math.min(Math.round(width / 130), 6))
        Repeater {
            model: 60
            delegate: Rectangle {
                required property int index
                Layout.fillWidth: true
                Layout.margins: 8
                implicitWidth: 200
                implicitHeight: width
                radius: width / 10
                gradient: Gradient {
                    GradientStop { position: -0.2; color: "#2CDE85" }
                    GradientStop { position: 1.2; color: "#00414A" }
                }
                Text {
                    color: "#ffffff"
                    font.pointSize: 22
                    anchors.centerIn: parent
                    text: parent.index + 1
                }
            }
        }
    }
}

Button {
    id: a
    text: "Text"
    icon.source: "./icons/text.svg"
    Layout.fillWidth: true
    Layout.margins: 3
}

Button {
    id: b
    text: "Grid 1"
    icon.source: "./icons/grid.svg"
    Layout.fillWidth: true
    Layout.margins: 3
}

Button {
    id: c
    text: "Grid 2"
    icon.source: "./icons/grid.svg"
    Layout.fillWidth: true
    Layout.margins: 3
}

Button {
    id: d
    text: "Settings"
    icon.source: "./icons/settings.svg"
    Layout.fillWidth: true
    Layout.margins: 3
}

Création de mises en page

Nous pouvons désormais déclarer différentes mises en page à l'aide d'LayoutItemProxies, en ciblant les éléments précédemment déclarés. Une mise en page peut être définie comme suit.

ColumnLayout {
    id: smallLayout
    anchors.fill: parent

    Flickable {
        Layout.fillHeight: true
        Layout.fillWidth: true
        contentWidth: width
        contentHeight: gl.implicitHeight
        clip: true
        ScrollIndicator.vertical: ScrollIndicator { }
        LayoutItemProxy {
            id: gl
            width: parent.width
            height: implicitHeight
            target: contentItem
        }
    }

    RowLayout {
        Layout.fillHeight: false
        Layout.fillWidth: true
        Layout.margins: 5
        LayoutItemProxy{ target: a; }
        LayoutItemProxy{ target: b; }
        LayoutItemProxy{ target: c; }
    }
}

Cet extrait de code présente plusieurs façons d’utiliser l’ LayoutItemProxy. La méthode la plus simple consiste à ajouter un LayoutItemProxies à une mise en page, comme le RowLayout ici. De plus, nous définissons une propriété attachée supplémentaire, « Layout », sur le `LayoutProxyItem`, qui n’affectera l’élément cible que dans cette mise en page particulière. Par ailleurs, nous constatons que l’élément « d » n’est pas utilisé dans la première mise en page. Il est alors automatiquement masqué par le « LayoutItemProxy » dans la deuxième mise en page. Une autre façon de l’utiliser consiste à définir un « LayoutItemProxy » comme contenu d’un « Flickable ».

Une autre mise en page est déclarée comme suit.

RowLayout {
    id: largeLayout
    anchors.fill: parent
    ColumnLayout {
        Layout.minimumWidth: 100
        Layout.fillWidth: true
        Layout.margins: 2
        LayoutItemProxy{ target: a }
        LayoutItemProxy{ target: b }
        LayoutItemProxy{ target: c }
        Item { Layout.fillHeight: true }
        LayoutItemProxy{ target: d }
    }

    LayoutItemProxy {
        Layout.fillHeight: true
        Layout.fillWidth: true
        target: contentItem
    }
}

Nous montrons ici que LayoutItemProxies peut être utilisé conjointement avec de véritables Items au même niveau hiérarchique. De manière générale, LayoutItemProxy est flexible et permet des structures imbriquées d’éléments et de mises en page.

Configuration de la mise en page

Une fois les deux mises en page, « smallLayout » et « largeLayout », définies, nous pouvons poursuivre en configurant la mise en page adaptée à la taille actuelle de l'application. Nous définissons une nouvelle fonction pour ce code, que nous appelons lors de l'initialisation de la fenêtre et à chaque fois que la largeur change :

function setFittingLayout() {
    if (width < 450) {
        smallLayout.visible = true
        largeLayout.visible = false
    } else {
        smallLayout.visible = false
        largeLayout.visible = true
    }
}
onWidthChanged: setFittingLayout()
Component.onCompleted: setFittingLayout()

Au lieu d’appeler cette fonction après l’initialisation, nous pouvons masquer toutes les mises en page sauf celle correspondant à la taille initiale dans le code déclaratif.

Exemple de projet sur code.qt.io

© 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.