Ziemlich oft taucht im Forum die gleiche Frage bezüglich des Problems der Anzeige von Inhalten auf, die in beliebige QML-Objekte eingebettet sind.
Die häufigste Manifestation dieses Problems ist, wenn der Inhalt der ListView aus seinem Gültigkeitsbereich herausscrollt. Auf jeden Fall ist dies einer dieser häufigen Fälle, in denen Anfänger beim Einstieg in QML auf dieses Problem stoßen. Nun, oder eine andere Option, wenn ich bei der Verwendung von Rectangle-Objekten auf ein solches Problem gestoßen bin.
In der folgenden Abbildung unten sehen Sie zwei Anwendungsfenster, die dieses Problem veranschaulichen.
- Das linke Fenster zeigt, wie das Layout anfänglich aussieht
- Das rechte Fenster zeigt, dass, wenn Sie beginnen, den Inhalt der ListView zu scrollen, dieser unter den Titeltext geht, obwohl er hätte abgeschnitten werden sollen.
Beispielquellcode
So sieht der Quellcode des Programms aus.
import QtQuick 2.12 import QtQuick.Window 2.12 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Text { id: topText text: qsTr("Title") anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top } ListView { width: 180; height: 200 model: contactModel delegate: Text { text: name + ": " + number } anchors.horizontalCenter: parent.horizontalCenter anchors.top: topText.bottom } ListModel { id: contactModel ListElement { name: "Bill Smith" number: "555 3264" } ListElement { name: "John Brown" number: "555 8426" } ListElement { name: "Sam Wise" number: "555 0473" } } }
Um dieses Problem zu lösen, legen Sie einfach die Eigenschaft clip: true auf ListView fest.
ListView { clip: true /* код */ }
Und jetzt wird der Inhalt der ListView die ListView nicht verlassen
Mit rechteckigen Objekten
Clip funktioniert auf die gleiche Weise für Rectangle-Objekte. Hier ist der Programmcode, sowie ein Beispiel vor und nach dem Einbinden des Clips.
import QtQuick 2.12 import QtQuick.Window 2.12 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { x: 27 y: 31 width: 100 height: 100 color: "blue" clip: true Rectangle { x: -20 y: -20 width: 100 height: 100 color: "green" } } }
Rundung
Was bei der Verwendung eines Clips jedoch nicht funktioniert, ist das Runden, selbst wenn Sie den Rundungsradius für das übergeordnete Rectangle-Objekt festlegen.
Hier haben wir zum Beispiel einen solchen Code, der nicht das erwartete Ergebnis liefert
import QtQuick 2.12 import QtQuick.Window 2.12 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { x: 27 y: 31 width: 100 height: 100 color: "blue" radius: 30 // set rounding clip: true // enable cropping Rectangle { x: -20 y: -20 width: 100 height: 100 color: "green" } } }
Das Ergebnis
Dieses Clip-Verhalten ist Standard und wurde aus Leistungsgründen vorgenommen, da fast alle grafischen QML-Elemente vom Item-Typ erben. Dies bedeutet, dass eine zusätzliche Verarbeitung von Masken in der gesamten Anwendung überflüssig ist.
Aber das erwartete Ergebnis kann durch den folgenden Programmcode unter Verwendung des Grafting-Effekts OpacityMask erreicht werden
import QtQuick 2.12 import QtQuick.Window 2.12 import QtGraphicalEffects 1.13 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { id: rect x: 27 y: 31 width: 100 height: 100 color: "blue" layer.enabled: true layer.effect: OpacityMask { maskSource: Item { width: rect.width height: rect.height Rectangle { anchors.centerIn: parent width: rect.adapt ? rect.width : Math.min(rect.width, rect.height) height: rect.adapt ? rect.height : width radius: 30 } } } Rectangle { x: -20 y: -20 width: 100 height: 100 color: "green" } } }
Und das Ergebnis wird wie folgt sein
Fazit
Zusammenfassend ist clip eine sehr nützliche Eigenschaft, die aus Leistungsgründen standardmäßig auf false gesetzt ist. Gleichzeitig führt diese Eigenschaft nur einen einfachen Zuschnitt in Form eines Rechtecks durch, und etwas Komplexeres muss mit einer Maske beschnitten werden.
Зачем внутри OpacityMask Item, почему сразу Rectangle не вставить?
И что за rect.adapt?
Мое предложение: