#qt #qml
Вопрос:
Я контролирую положение некоторых элементов моей сцены, используя свойства псевдонима, например : Если у меня есть файл Foo.qml
, содержащий
Item {
property alias myprop1: id1
property alias myprop2: id2
Node {id:id1,...}
Node {id:id2,...}
По моему основному, я могу позвонить
Slider{
id:myslider
}
foo{
myprop1.x: myslider.value
}
Теперь, если мой файл Foo.qml содержит неизвестное количество свойств (допустим, все они называются mypropX
). Если у меня есть 10 свойств, я хочу создать 10 ползунков, по одному для каждого свойства. Это возможно с помощью ретранслятора и петли, как указано в последнем ответе здесь
Foo{
id:myfoo
}
Column {
Repeater {
id: myrepeater
delegate: Slider {
from:0
to:400
y: 12*index
}
Component.onCompleted: {
let propArray = [];
for(var prop in myfoo){
//select only the properties I'm interested in
//a "onXXXChanged" is created on each properties so I also have to remove it
if(prop.substring(0, 6)==="myprop" amp;amp; prop.substring(prop.length-7,prop.length)!=="Changed"){
propArray.push(prop)
}
}
myrepeater.model = propArray
}
}
}
Проблема в том, что теперь я не знаю, как привязать эти 10 ползунков к моим свойствам.
Я попытался добавить в свой экземпляр Foo в main
Component.onCompleted: {
let i=0
for(var prop in myfoo){
if(prop.substring(0, 6)==="myprop" amp;amp; prop.substring(prop.length-7,prop.length)!=="Changed"){
//equivalent to myprop1.x: myslider.value when there was no repeater
myfoo.prop.x = Qt.binding(function() {
return myrepeater.itemAt(i).value
})
i
}
}
}
Но он возвращается
QQmlEngine::setContextForObject(): Object already has a QQmlContext
qrc:/main.qml:145: Error: Cannot assign to non-existent property "prop"
Проблема в том, что в цикле for prop
есть строка. Я также не уверен, что в тот момент, когда выполняется выполнение, повторитель уже создал все слайдеры.
Я мог бы использовать тип QML Bindings{}
, который принимает цель ( myrepeater.itemAt(i).value
) и имя свойства в виде строки, но я не знаю, как вызвать Bindings{}
тип из javascript
Комментарии:
1. Вы можете использовать оператор [], так
myfoo[prop]
что, если я правильно читаю это2. это решает
non-existent property
проблему. Теперь появилось первое сообщение об ошибке :QQmlEngine::setContextForObject(): Object already has a QQmlContext
все еще там3. Это я не могу проверить из данного кода. У вас есть представление, на какой линии это происходит?
4. Вы также можете попробовать использовать
Binding
объект5. Оказывается, это то, что я хотел сделать. Все объекты привязки, никакого javascript для привязки. Делегат моего ретранслятора-это элемент, содержащий слайдер объект привязки
Binding {target: myfoo[modelData]; property: "width"; value: slider.value }
Ответ №1:
Вы можете использовать оператор [] для чтения свойств, myfoo
и, как обсуждалось, я бы использовал Binding
объект внутри делегата:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Item {
id: myfoo
property int myprop_upper_threshold
onMyprop_upper_thresholdChanged: console.log("upper_threshold", myprop_upper_threshold)
property int myprop_lower_threshold
onMyprop_lower_thresholdChanged: console.log("lower_threshold", myprop_lower_threshold)
}
ColumnLayout {
Repeater {
id: myrepeater
delegate: Slider {
id: myslider
from: 0
to: 400
Text {
text: modelData
}
Binding {
target: myfoo
property: modelData
value: myslider.value
}
}
Component.onCompleted: {
let propArray = [];
for(var prop in myfoo)
{
//select only the properties I'm interested in
//a "onXXXChanged" is created on each properties so I also have to remove it
if(prop.substring(0, 6)==="myprop" amp;amp; prop.substring(prop.length-7,prop.length)!=="Changed")
{
propArray.push(prop)
}
}
myrepeater.model = propArray
}
}
}
}