Можно ли поместить виджет QML в дочерний элемент импортированного файла QML?

#qt #qml

Вопрос:

Допустим, у меня есть следующий код в файле под названием NestedCircle.qml :

 import QtQuick 2.12

Rectangle {
    color: "blue"
    radius: Math.min(width, height)
    property Rectangle innerCircle: Rectangle {
        radius: Math.min(width, height)
        x: 10
        y: 10
        width: parent.width - 20
        height: parent.height - 20
        color: "yellow"
    }
}
 

Затем в main.qml :

 import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    title: "Three circles"
    NestedCircle {
        // the line below fails with a syntax error, Expected token `:'
        property NestedCircle innerCircle.innerCircle: NestedCircle {
            color: "red"
        }
    }
}
 

Итак, предполагая, что мне нужно использовать NestedCircle.qml и не может его редактировать (это минимальный пример, а не реальное приложение), есть ли способ поместить что-то внутри внутреннего круга без его повторного создания?

Комментарии:

1. попробуйте с: innerCircle: NestedCircle { color: "red" }

2. Это заменит внутренний круг, а не создаст внутри него еще один вложенный круг.

3. Кроме того, я чувствую, что этому qt тегу здесь не место, так как он связан исключительно с языком QML.

4. 1) Я просто понимаю ваши требования, 2) QML является частью мира Qt, так что тег релевантен.

Ответ №1:

Здесь нет необходимости в создании динамических объектов, вы можете сделать это чисто декларативно. На самом деле вот 4 способа сделать это, в зависимости от ваших потребностей и желаемого API:

 // NestedCircle.qml
import QtQuick 2.12

Rectangle {
    color: "blue"
    radius: Math.min(width, height)
    default property alias innerCircleData: innerCircle.data
    property alias innerCircle: innerCircle
    Rectangle {
        id: innerCircle
        radius: Math.min(width, height)
        anchors.centerIn: parent
        width: parent.width - 20
        height: parent.height - 20
        color: "yellow"
    }
}
 
 // main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 800
    height: 640
    title: "Three circles"

    Row {
        anchors.centerIn: parent
        spacing: 30
        NestedCircle { // setting parent in the nested circle
            id: rootCircle
            width: 100
            height: 100
            NestedCircle {
                parent: rootCircle.innerCircle
                width: 50
                height: 50
                anchors.centerIn: parent
            }
        }
        NestedCircle { // assigning to the inner circle's children in the outer circle
            width: 100
            height: 100
            innerCircle.children: NestedCircle {
                width: 50
                height: 50
                anchors.centerIn: parent
            }
        }
        NestedCircle { // using an alias to the innerCircle.data
            width: 100
            height: 100
            innerCircleData: NestedCircle {
                width: 50
                height: 50
                anchors.centerIn: parent
            }
        }
        NestedCircle { // using an alias to the innerCircle.data as a default property
            width: 100
            height: 100
            NestedCircle {
                width: 50
                height: 50
                anchors.centerIn: parent
            }
        }
    }
}
 

Комментарии:

1. Это было то, что я искал. Спасибо!

Ответ №2:

Если вы хотите добавить элемент, который находится внутри другого, возможное решение состоит в том, чтобы первый элемент был дочерним по отношению ко второму. Вложенный круг.qml

 import QtQuick 2.12

Rectangle {
    color: "blue"
    radius: Math.min(width, height)
    property Rectangle innerCircle: inner

    Rectangle {
        id: inner
        radius: Math.min(width, height)
        x: 10
        y: 10
        width: parent.width - 20
        height: parent.height - 20
        color: "yellow"
    }
}
 

main.qml

 import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    title: "Three circles"
    Component{
        id: provider
        NestedCircle{

        }
    }
    NestedCircle {
        width: 100
        height: 100
        Component.onCompleted: {
            var obj = provider.createObject(innerCircle, {width: 50, height: 50})
            obj.anchors.centerIn = innerCircle
        }
    }
}
 

введите описание изображения здесь