web-dev-qa-db-fra.com

Comment attribuer un élément QML à une propriété de composant dans QML, puis utiliser cet objet à l'intérieur du composant?

J'essaie de créer un objet QML qui agit comme un wrapper pour d'autres objets. Voici mon fichier QML (Container.qml):

Item {
    property string label
    property Item control

    Row {
        Label {
            text: label
        }

        // Not sure how to display the control assigned to the control property
    }
}

Ce que je voudrais faire (dans mon QML qui consomme ce composant) est quelque chose comme ceci:

Container {
    label: "My Label"
    control: Textbox {
        text: "My Value"
    }
}

Lorsqu'il est alimenté en QML, le résultat (dans l'interface) devrait ressembler à la sortie de ce QML:

Item {
    Row {
        Label {
            text: "My Label"
        }
        Textbox {
            text: "My Value"
        }
    }
}

Est-ce possible? Lorsque j'essaie de le faire, j'obtiens "ne peut pas affecter d'objet à la propriété" lors de l'attribution d'un élément à la propriété de contrôle. J'ai cherché sur les forums Qt et googlé sans pitié, mais sans succès. Si quelqu'un connaît la réponse, elle serait grandement appréciée.

Merci

Jack

30
Jack Benson

Vous pouvez charger dynamiquement des éléments à l'aide de l'élément Loader , puis définir la propriété 'control' comme un alias qui fait directement référence au chargeur propriété sourceComponent .

Ainsi, votre Container.qml pourrait ressembler à ceci:

Item {
    property string label
    property alias control : loader.sourceComponent

    width: 200; height: 200

    Row {
        Label { text: label }
        Loader { id: loader }
    }
}

Désormais, lorsque vous affectez un élément graphique à la propriété "contrôle", il sera automatiquement affiché par le chargeur.

31
blam

Il y a une bien meilleure solution:

/* MyObject.qml */

Rectangle {
    default property alias data /* name can be any */ : inner_space.data

    /* ... You can put other elements here ... */
    Item {
       id: inner_space

       /* ... Params ... */
    }
    /* ... You can put other elements here ... */
}

Et maintenant, nous pouvons faire tout ce que nous voulons!

/* main.qml */

Rectangle {
    MyObject {
        Button {
             /* ... */
        }
    }
}

Merci à l'utilisateur bobbaluba d'avoir suggéré d'utiliser la propriété data plutôt que children.

36
s.maks

Vous pouvez créer un conteneur pour d'autres éléments à l'aide d'une propriété personnalisée:

Item
{
    id: root

    property list<Item> rectList: [
        Rectangle
        {
            parent: root
        },
        Rectangle
        {
            parent: root
        },
        Rectangle
        {
            parent: root
        },
        Rectangle
        {
            parent: root
        }
    ]
}

Notez que le parent des éléments rectangulaires est défini manuellement afin qu'ils soient les enfants visuels du conteneur.

Vous pouvez les évaluer comme un tableau javascript

for ( var i = 0; i < root.rectList.length; i++ )
{
   var rect = root.rectList[i];
   rect.visible = true;
}

ou

rect.rectList[1].visible = false;
2
Jay

J'utilise QML depuis environ un mois maintenant, je ne sais vraiment pas comment faire, j'ai peur.

Le meilleur plan est de comprendre toutes les choses possibles que pourrait être le contrôle (Textbox dans votre exemple), de créer une instance de chaque composant de votre ligne et de définir un état correspondant sur votre Item. L'État prendrait alors soin de rendre le composant souhaité visible ou invisible selon le cas.

Modifier

J'ai juste pensé. (Je n'ai pas essayé mais essayez!) Dans le gestionnaire Component.onCompleted: De votre Item, essayez d'appeler control.createObject(rowID)rowID est un id pour votre objet Row, (dont vous voulez être le parent de control).

1
funkybro