Подтвердить что ты не робот

Как назначить QML-элемент для свойства компонента в QML, а затем использовать этот объект внутри компонента?

Я пытаюсь создать объект QML, который действует как оболочка для других объектов. Вот мой 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
    }
}

То, что я хотел бы сделать (в моем QML, который потребляет этот компонент), выглядит примерно так:

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

При подаче этого QML результат (в интерфейсе) должен быть чем-то похожим на результат из этого QML:

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

Возможно ли это? Когда я пытаюсь это сделать, я получаю "не могу назначить объект для свойства" при назначении элемента элементу управления. Я искал форумы Qt и безжалостно искал эту игру, но ничего не добился. Если кто-нибудь знает ответ, мы будем очень благодарны.

Спасибо

Джек

4b9b3361

Ответ 1

Вы можете динамически загружать элементы с помощью элемента Loader, а затем установить свойство 'control' как alias, который напрямую ссылается на свойство loadComponent загрузчика.

Итак, ваш Container.qml может выглядеть так:

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

    width: 200; height: 200

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

Теперь, когда вы назначаете графический элемент свойству "control", он будет автоматически отображаться загрузчиком.

Ответ 2

Существует гораздо лучшее решение:

/* MyObject.qml */

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

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

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

И теперь мы можем делать все, что хотим!

/* main.qml */

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

ОБНОВЛЕНИЕ: Как уже упоминалось пользователем bobbaluba, лучше использовать элемент данных, а не дочерний элемент, поэтому 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 ... */
}

Ответ 3

Использую QML около месяца, не знаю, как это сделать, я боюсь.

Лучший план состоит в том, чтобы выяснить все возможные вещи, которые может быть в элементе управления (Textbox в вашем примере), создать экземпляр каждого компонента в вашей строке и установить соответствующее состояние на Item. Затем государство будет заботиться о том, чтобы желаемый компонент был видимым или невидимым в зависимости от ситуации.

Edit

Просто подумал. (Не пробовал, но дайте ему поработать!) В вашем обработчике Item Component.onCompleted: попробуйте позвонить control.createObject(rowID), где rowID является id для вашего объекта Row (который вы хотите родительский элемент control).

Ответ 4

Вы можете создать контейнер для других элементов с помощью настраиваемого свойства:

Item
{
    id: root

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

Обратите внимание, что родительский элемент Rectangle Items устанавливается вручную, чтобы они были визуальными дочерними элементами контейнера.

Вы можете оценить их как массив javascript

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

или

rect.rectList[1].visible = false;