web-dev-qa-db-de.com

Unterschied zwischen width, height und implicitWidth / Height und den entsprechenden Anwendungsfällen in QML

Was ist der Unterschied zwischen width/height und implicitWidth/Height in QML? Wann sollte man die impliziten Dimensionen anstelle der regulären festlegen? Wann sollte man die impliziten Dimensionen anstelle der regulären von einer Komponente/einem Gegenstand abfragen?

32
Silex

Im Allgemeinen wird implicitHeight/Width macht nur innerhalb wiederverwendbarer Komponenten Sinn.

Es gibt einen Hinweis auf die natürliche Größe des Artikels, ohne diese Größe zu erzwingen.

Nehmen wir als Beispiel Image. Die natürliche Größe des Bildes würde ein Pixel aus der Bilddatei auf ein Pixel auf dem Bildschirm abbilden. Aber es erlaubt uns, es zu dehnen, so dass die Größe nicht erzwungen wird und überschrieben werden kann.

Nehmen wir jetzt an, wir wollen eine Galerie mit Bildern unbekannter Größe, und wir wollen sie nicht vergrößern, sondern nur bei Bedarf verkleinern. Wir müssen also die natürliche Größe des Bildes speichern. Hier kommt die implizite Höhe ins Spiel.

Image {
    width: Math.max(150, implicitWidth)
    height: Math.max(150, implicitHeight)
}

In benutzerdefinierten Komponenten können Sie festlegen, wie die Größen definiert werden sollen.

Die eine Möglichkeit besteht darin, alle Dimensionen in Bezug auf den Komponentenknoten root zu haben.

Item {
    id: root
    Rectangle {
        width: root.width * 0.2
        height: root.height * 0.2
        color: 'red'
    }
    Rectangle {
        x: 0.2 * root.width
        y: 0.2 * root.height
        width: root.width * 0.8
        height: root.height * 0.8
        color: 'green'
    }
}

In diesem Fall gibt es keine natürliche Größe des Objekts. Für jede Größe, die Sie für die Komponente festlegen, funktioniert alles perfekt.

Auf der anderen Seite könnten Sie ein Objekt haben, das eine natürliche Größe hat - das passiert, z. wenn Sie absolute Werte haben

Item {
    id: root
    property alias model: repeater.model
    Repeater {
        id: repeater
        delegate: Rectangle {
            width: 100
            height: 100
            x: 102 * index
            y: 102 * index
        }
    }
}

In diesem Beispiel sollten Sie dem Benutzer Informationen zur natürlichen Größe bereitstellen, bei der der Inhalt das Objekt nicht schützt. Der Benutzer könnte sich immer noch dafür entscheiden, eine kleinere Größe einzustellen und sich mit dem Vorsprung zu befassen, z. indem er es beschneidet, braucht er aber die Information über die natürliche Größe, um seine Entscheidung zu treffen.

In vielen Fällen, childrenRect.height/width ist ein gutes Maß für die implcitHeight/Width, aber es gibt Beispiele, bei denen dies keine gute Idee ist. - z.B. wenn der Inhalt des Gegenstandes x: -500.

Ein Beispiel aus dem wirklichen Leben ist Flickable, das speziell entwickelt wurde, um größere Objekte als die eigene Größe zu enthalten. Es wäre nicht natürlich, wenn die Größe von Flickable gleich dem Inhalt wäre.

Seien Sie auch vorsichtig, wenn Sie scale in benutzerdefinierten Komponenten verwenden, da childrenRect nichts über die Skalierung weiß.

Item {
    id: root
    implicitWidth: child.width * child.scale
    implicitHeight: child.height * child.scale
    Rectangle {
        id: child
        width: 100
        height: 100
        scale: 3
        color: 'red'
    }
}

Und zu Ihrem Kommentar: Ich verstehe nur nicht, warum es besser ist, implicitWidth/Height festzulegen, als width/height der Stammdimension einer Komponente.

implicitWidht/Height sind keine Notwendigkeit - QtQuick könnte ohne sie auskommen. Sie existieren aus Bequemlichkeitsgründen und sind Konventionen.


Faustregel

Wenn Sie die Dimension eines Stammknotens einer wiederverwendbaren Komponente festlegen möchten, legen Sie implicitWidth/Height.
In einigen Fällen legen Sie dies für Nicht-Root-Knoten fest, wenn die Knoten als Eigenschaft verfügbar gemacht werden.
Tun Sie dies nur, wenn Sie einen Grund dafür haben (viele offizielle Komponenten kommen ohne).
Wenn Sie eine Komponente verwenden, legen Sie width/height.

15
derM

Ich habe keine endgültige Antwort, aber ich kann Ihnen sagen, was ich herausgefunden habe. Erstens aus der Dokumentation :

implicitWidth: real

Definiert die natürliche Breite oder Höhe des Elements, wenn keine Breite oder Höhe angegeben ist.

Die implizite Standardgröße für die meisten Elemente ist 0x0. Einige Elemente haben jedoch eine implizite Größe, die nicht überschrieben werden kann, z. B. Image und Text.

aber weniger informativ für die Breite :

breite

Definiert die Position und Größe des Artikels.

Die Zeichen width und height geben die tatsächliche Größe des Elements in der Szene wieder. Die implizite Größe ist eine Art inhärente Eigenschaft des Elements selbst.1

Ich benutze sie wie folgt: Wenn ich ein neues Element erstelle und dessen Größe geändert werden kann, setze ich eine implizite Größe innerhalb des Objekts2. Wenn ich das Objekt verwende, stelle ich die tatsächliche Größe oft explizit von außen ein .

Die implizite Größe eines Objekts kann durch Festlegen von Höhe und Breite überschrieben werden.

ein Beispiel: TextWithBackground.qml

Item {
    implicitWidth: text.implicitWidth
    implicitHeight: text.implicitHeight
    // the rectangle will expand to the real size of the item
    Rectangle { anchors.fill: parent; color: "yellow" }
    Text { id: text; text: "Lorem ipsum dolor..." }
}

ein Beispiel: MyWindow.qml

Item {
    width: 400
    height: 300
    TextWithBackground {
         // half of the scene, but never smaller than its implicitWidth
         width: Math.max(parent.width / 2, implicitWidth)
         // the height of the element is equal to implicitHeight
         // because height is not explicitly set
    }
}

1) Bei einigen Elementen, wie z. B. Text, hängt die implizite Höhe von der (nicht impliziten) Breite ab.
2) Die implizite Größe hängt normalerweise von der impliziten Größe seiner Kinder ab.

6
Georg Schölly