Qt Quick Layouts Übersicht

Verwenden Sie Qt Quick Layouts, um Elemente in einer Benutzeroberfläche anzuordnen. Qt Quick Layouts ändern die Größe ihrer Elemente, was sie für größenveränderbare Benutzeroberflächen gut geeignet macht.

Hauptmerkmale

Einige der wichtigsten Funktionen von Qt Quick Layouts sind:

Darüber hinaus bietet GridLayout die folgenden Funktionen:

Erste Schritte

Um mit der Verwendung von Qt Quick Layouts zu beginnen, importieren Sie die QML-Typen in Ihre Anwendung mit der folgenden Importanweisung in Ihrer .qml Datei:

import QtQuick.Layouts

Der nächste Schritt besteht darin, ein einfaches Layout zu erstellen. Sie können auch das Qt Quick Layouts - Basic Example studieren.

Ein einfaches Layout

Die Absicht bei der Verwendung eines Layouts ist es, seine Kinder neu anzuordnen, wenn sich die Größe des Layouts ändert. Das bedeutet, dass die Anwendung sicherstellen muss, dass die Größe des Layouts angepasst wird. Im folgenden Schnipsel stellt das RowLayout dies durch die Angabe von anchors.fill: parent sicher. Sie können dies jedoch auch auf andere Weise erreichen, beispielsweise durch Angabe der Eigenschaften width und height. Im gleichen Ausschnitt hat das orangefarbene Rechteck eine feste Größe von 100 x 150 Pixeln, und das Pflaumen-Rechteck wird so erweitert, dass es den gesamten ihm zugewiesenen Platz einnimmt.

Window {
    RowLayout {
        anchors.fill: parent
        spacing: 6
        Rectangle {
            color: 'azure'
            Layout.preferredWidth: 100
            Layout.preferredHeight: 150
        }
        Rectangle {
            color: "plum"
            Layout.fillWidth: true
            Layout.fillHeight: true
        }
    }
}

Layouts sind für die Geometrie ihrer Kinder verantwortlich. Dazu gehören Eigenschaften wie width, height, x, y, anchors), usw.

Wichtig! Geben Sie in Ihrer Anwendung keine Eigenschaften an, die die Geometrie von untergeordneten Elementen beeinflussen. Das Festlegen dieser Eigenschaften auf ein untergeordnetes Element führt zu einem Interessenkonflikt, und das Ergebnis ist undefiniert. Dies gilt auch, wenn das untergeordnete Element ein Layout ist. Daher können nur Layouts, die kein übergeordnetes Layout haben, anchors.fill: parent haben.

Abstände

Wie im vorherigen Ausschnitt zu sehen, ist der Abstand für das RowLayout auf 6 gesetzt. Dadurch wird sichergestellt, dass alle Elemente im Layout einen Abstand von 6 Pixeln zueinander haben:

spacing: 6

Wenn Sie keinen Abstandswert angeben, verwendet das Layout den Standardwert von 5 Pixeln. Die Abstände sowie die implizite Breite aller untergeordneten Elemente tragen zur impliziten Breite des Layouts bei. Dies ist wichtig zu beachten, wenn Sie sich auf das Standardverhalten verlassen, da es sich auf Ihr Layoutdesign auswirken kann. Zum Beispiel setzen die beiden ColumnLayouts im folgenden Ausschnitt beide Layout.fillWidth: true gesetzt. Man könnte meinen, dass sie beide die gleiche Breite erhalten würden. Aufgrund des Standardabstands von 5 Pixeln zwischen den Elementen im inneren RowLayout wird die implizite Breite des ersten ColumnLayouts jedoch größer, wodurch weniger Platz für das zweite bleibt. Ein Beispiel:

ApplicationWindow {
    id: root
    width: 300
    height: 300
    visible: true

    RowLayout {
        anchors.fill: parent
        ColumnLayout {
            Rectangle {
                color: "tomato";
                Layout.fillWidth: true
                Layout.fillHeight: true
            }
            RowLayout {
                Rectangle {
                    color: "navajowhite"
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                }
                Rectangle {
                    color: "darkseagreen"
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                }
            }
        }
        ColumnLayout {
            Rectangle {
                color: "lightpink"
                Layout.fillWidth: true
                Layout.fillHeight: true
            }
            Rectangle {
                color: "slategray"
                Layout.fillWidth: true
                Layout.fillHeight: true
            }
            Rectangle {
                color: "lightskyblue"
                Layout.fillWidth: true
                Layout.fillHeight: true
            }
        }
    }
}

Dieses Snippet erzeugt ein Layout, das wie folgt aussieht:

"A QML layout with default spacing"

Um die gleiche Größe der beiden Spalten zu gewährleisten, können Sie entweder

  1. den Abstand des RowLayout auf 0 setzen, oder
  2. preferredWidth auf gleiche Werte für beide ColumnLayouts.

Angeben der bevorzugten Größe

Für jedes Element kann die effektive bevorzugte Größe aus einer von mehreren Kandidateneigenschaften stammen. Zur Bestimmung der effektiven bevorzugten Größe fragt ein Artikel diese Kandidateneigenschaften in der folgenden Reihenfolge ab und verwendet den ersten Kandidaten mit einer gültigen Breite oder Höhe.

KandidateneigenschaftenBeschreibung
Layout.preferredWidth oder Layout.preferredHeightDiese Eigenschaften sollen von der Anwendung geändert werden, wenn die standardmäßige implizite Größe nicht die optimale Anordnung ergibt.
implicitWidth oder implicitHeight.Diese Eigenschaften sollten von jedem Element angegeben werden, um eine sinnvolle ideale Größe zu erhalten. Zum Beispiel die Größe, die benötigt wird, um den gesamten Inhalt eines Typs Text anzuzeigen. Eine implizite Breite oder Höhe von 0 wird als ungültig interpretiert.

Ein Element kann Layout.preferredWidth angeben, ohne dass Layout.preferredHeight angegeben werden muss. In solchen Fällen wird die effektive Vorzugshöhe aus der Angabe implicitHeight ermittelt.

Hinweis: Wenn Sie weder preferredWidth noch implicitWidth angeben, wird das Layout width als endgültigen Wert für die effektive bevorzugte Breite abfragen. Sie sollten sich jedoch nicht auf width als Quelle für die effektive bevorzugte Breite verlassen, da dies zu unerwartetem Verhalten führen kann. So wird beispielsweise eine Änderung der Eigenschaften width oder height keine Neuanordnung des Layouts auslösen, oder das Layout könnte die tatsächliche Breite und Höhe verwenden - und nicht die in Ihrer QML-Datei angegebene Breite und Höhe -, wenn es gezwungen ist, einen vollständigen Neuaufbau durchzuführen.

Größenbeschränkungen

Da die Größe eines Elements durch sein Layout geändert werden kann, muss das Layout die Größen minimum, preferred und maximum aller Elemente kennen, bei denen Layout.fillWidth oder Layout.fillHeight auf true gesetzt ist.

Die preferred Breite und Höhe ist die tatsächliche Breite und Höhe eines Objekts, wenn das Layout selbst nicht an eine bestimmte Größe gebunden ist. Wenn das Layout auf eine bestimmte Größe festgelegt ist, verteilt es zusätzlichen Platz auf der Grundlage des Verhältnisses der bevorzugten Größen seiner Elemente, wobei die Mindest- und Höchstgrößen berücksichtigt werden. Die bevorzugten und impliziten Größen fungieren als Verhältnisse und Gewichte, wenn alle Elemente fillWidth und fillHeight setzen.

Das folgende Beispiel erzeugt ein Layout mit zwei nebeneinander liegenden Rechtecken, die sich horizontal ausdehnen. Das orangefarbene Rechteck kann von 50x150 auf 300x150 und das pflaumenfarbene Rechteck von 100x100 auf ∞x100 verkleinert werden. Solange die minimale und maximale Breite der einzelnen Elemente nicht überschritten wird, ist das Pflaumenrechteck doppelt so breit wie das orangefarbene.

RowLayout {
    id: layout
    anchors.fill: parent
    spacing: 6
    Rectangle {
        color: 'orange'
        Layout.fillWidth: true
        Layout.minimumWidth: 50
        Layout.preferredWidth: 100
        Layout.maximumWidth: 300
        Layout.minimumHeight: 150
        Text {
            anchors.centerIn: parent
            text: parent.width + 'x' + parent.height
        }
    }
    Rectangle {
        color: 'plum'
        Layout.fillWidth: true
        Layout.minimumWidth: 100
        Layout.preferredWidth: 200
        Layout.preferredHeight: 100
        Text {
            anchors.centerIn: parent
            text: parent.width + 'x' + parent.height
        }
    }
}

"RowLayout at its minimum"

Durch die Kombination der Beschränkungen der einzelnen Elemente ergeben sich diese impliziten Beschränkungen für das Layout-Element:

Minimumbevorzugtmaximal
implizite Beschränkungen (Breite)156306∞ (Number.POSITIVE_INFINITY)
implizite Beschränkungen (Höhe)150150150

Das Layout kann also weder schmaler als 156 noch höher oder kürzer als 150 sein, ohne eine der Beschränkungen seiner untergeordneten Elemente zu verletzen.

Verbinden von Fenstern und Layouts

Sie können normale Verankerungskonzepte verwenden, um sicherzustellen, dass Ihr Layout der Größenänderung des Fensters folgt.

RowLayout {
    id: layout
    anchors.fill: parent

Sie können sich auf die Größenbeschränkungen von Layouts verlassen, um sicherzustellen, dass die Größe des Fensters nicht über die Layoutbeschränkungen hinaus verändert werden kann. Sie können die Größenbeschränkungen aus dem Layout übernehmen und diese Beschränkungen auf minimumWidth, minimumHeight, maximumWidth und maximumHeight des Elements Window setzen. Der folgende Code stellt sicher, dass die Größe des Fensters nicht über die Beschränkungen des Layouts hinaus geändert werden kann:

minimumWidth: layout.Layout.minimumWidth
minimumHeight: layout.Layout.minimumHeight
maximumWidth: 1000
maximumHeight: layout.Layout.maximumHeight

Hinweis: Da layout.Layout.maximumWidth in diesem Fall unendlich ist, können wir dies nicht an die Eigenschaft maximumWidth von Window binden, da es sich um eine ganze Zahl handelt. Daher wird die maximale Breite auf einen festen Wert von 1000 gesetzt.

Legen Sie schließlich die Anfangsgröße des Fensters auf die implizite Größe des Layouts fest:

width: layout.implicitWidth
height: layout.implicitHeight

Spannen und Dehnen von Elementen

Verwenden Sie spans in einem GridLayout, damit untergeordnete Elemente mehr als eine Zelle belegen. Ein Beispiel: Sie haben eine GridLayout mit sechs Zellen in zwei Zeilen. Die obere Zeile enthält die Elementeitem1, item2 und item3. Die untere Zeile enthält das Item item4, das columnSpan: 3 und alignment: Qt.AlignHCenter. Dadurch wird item4 in der Mitte der drei Zellen platziert, aus denen die untere Zeile besteht. Das folgende Snippet dient als Beispiel:

ApplicationWindow {
    id: root
    width: 300
    height: 300
    visible: true

    GridLayout {
       rows: 2
       columns: 3
       Rectangle {
           color: 'cyan'
           implicitWidth: 50
           implicitHeight: 50
       }
       Rectangle {
           color: 'magenta'
           implicitWidth: 50
           implicitHeight: 50
       }
       Rectangle {
           color: 'yellow'
           implicitWidth: 50
           implicitHeight: 50
       }
       Rectangle {
           color: 'black'
           implicitWidth: 50
           implicitHeight: 50
           Layout.columnSpan: 3
           Layout.alignment: Qt.AlignHCenter
       }
    }
}

Die Größe von Zeilen und Spalten wird implizit durch ihren Inhalt bestimmt. Eine Schaltfläche kann sich beispielsweise auf die Breite der Spalte auswirken, in der sie sich befindet, oder auf die Höhe der Zeile, in der sie sich befindet. Das bedeutet, dass GridLayout keine gleichmäßige Verteilung hat. Aus diesem Grund können Sie keine Spannweite verwenden, um ein Layout zu dehnen. Um die Ausdehnung eines Elements oder Layouts zu beeinflussen, verwenden Sie stattdessen stretchFactors und/oder Größenhinweise.

Hinweis: Wenn Sie implizite oder bevorzugte Größen festlegen, binden Sie die entsprechenden Eigenschaften nicht an die Breite oder Höhe des Layouts selbst oder an Elemente, von denen es für seine Größenberechnungen abhängt, da dies zu zyklischen Abhängigkeiten führen kann, die schwer aufzuspüren sind.

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