web-dev-qa-db-fra.com

Différence entre largeur, hauteur et largeur / hauteur implicite et cas d'utilisation correspondants dans QML

Quelle est la différence entre width/height et implicitWidth/Height en QML? Quand faut-il définir les dimensions implicites au lieu du régulier? Quand faut-il demander les dimensions implicites au lieu du régulier d'un composant/article?

32
Silex

Généralement, l'utilisation de implicitHeight/Width n'a de sens que dans les composants réutilisables.

Il donne un indice de la taille naturelle de l'article sans imposer cette taille.

Prenons un Image comme exemple. La taille naturelle de l'image mapperait un pixel du fichier image à un pixel sur l'écran. Mais cela nous permet de l'étirer, donc la taille n'est pas appliquée et peut être remplacée.

Disons maintenant, nous voulons avoir une galerie avec des images de dimension inconnue, et nous ne voulons pas grandir mais seulement les rétrécir si nécessaire. Nous devons donc stocker la taille naturelle de l'image. Autrement dit, où la hauteur implicite entre en jeu.

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

Dans les composants personnalisés, vous avez le choix sur la façon de définir les tailles.

Le seul choix est, d'avoir toutes les dimensions par rapport aux composants root- node, peut-être comme ceci:

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'
    }
}

Dans ce cas, il n'y a pas de taille naturelle de l'objet. Tout fonctionne parfaitement pour chaque taille que vous définissez pour le composant.

D'un autre côté, vous pourriez avoir un objet qui a une taille naturelle - cela arrive, par exemple si vous avez des valeurs absolues

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

Dans cet exemple, vous devez fournir à l'utilisateur des informations sur la taille naturelle, où le contenu ne dépasse pas l'élément. L'utilisateur peut toujours décider de définir une taille plus petite et de gérer la saillie, par exemple en le coupant, mais il a besoin des informations sur la taille naturelle pour prendre sa décision.

Dans de nombreux cas, childrenRect.height/width est une bonne mesure pour le implcitHeight/Width, mais il existe des exemples où ce n'est pas une bonne idée. - par exemple. lorsque le contenu de l'élément a x: -500.

Un exemple réel est le Flickable qui est spécifiquement conçu pour contenir des objets plus grands que sa propre taille. Avoir la taille de Flickable pour être égale au contenu ne serait pas naturel.

Soyez également prudent lorsque vous utilisez scale dans des composants personnalisés, car childrenRect ne connaîtra pas la mise à l'échelle.

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

Et à votre commentaire: Je ne comprends tout simplement pas pourquoi il est préférable de définir implicitWidth/Height au lieu de définir la largeur/hauteur de la dimension racine d'un composant.

implicitWidht/Height ne sont pas une nécessité - QtQuick pourrait s'en passer. Ils existent par commodité et seront conventionnels.


Règle générale

Lorsque vous souhaitez définir la dimension d'un nœud racine d'un composant réutilisable, définissez implicitWidth/Height.
Dans certains cas, définissez-le pour les nœuds non root, si les nœuds sont exposés en tant que propriété.
Ne le faites que si vous avez une raison (de nombreux composants officiels sont livrés sans aucun).
Lorsque vous utilisez un composant, définissez width/height.

15
derM

Je n'ai pas la réponse définitive mais je peux vous dire ce que j'ai découvert. Tout d'abord, à partir de la documentation :

implicitWidth: réel

Définit la largeur ou la hauteur naturelle de l'élément si aucune largeur ou hauteur n'est spécifiée.

La taille implicite par défaut pour la plupart des éléments est 0x0, mais certains éléments ont une taille implicite inhérente qui ne peut pas être remplacée, par exemple, Image et Text.

mais moins informatif pour la largeur :

largeur

Définit la position et la taille de l'élément.

width et height reflètent la taille réelle de l'élément dans la scène. La taille implicite est une sorte de propriété inhérente à l'élément lui-même.1

Je les utilise comme suit: lorsque je crée un nouvel élément et qu'il peut être redimensionné, je mets une taille implicite à l'intérieur de l'objet2. Lorsque j'utilise l'objet, je règle souvent la taille réelle explicitement de l'extérieur .

La taille implicite d'un objet peut être remplacée en définissant la hauteur et la largeur.

un exemple: 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..." }
}

un exemple: 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) Pour certains éléments, comme Text, la hauteur implicite dépend de la largeur (non implicite).
2) La taille implicite dépend généralement de la taille implicite de ses enfants.

6
Georg Schölly