【发布时间】:2020-10-27 00:20:46
【问题描述】:
我通过加载的组件在转发器中显示了以下一些实例。我正在尝试控制重复组件的可见性:
property var modes : [new modeClass("Mode 1", "mode1", noteC1)];
function modeClass(name, representation, note) {
var active = true;
this.name = name;
this.representation = representation;
this.note = note;
this.activated = true;
Object.defineProperty(this, "activated", {
get : function () {
return active;
},
set : function (newActive) {
active = newActive;
if (!active)
note.selected = false;
this.dummy = active;
console.log(name, this.dummy);
},
enumerable : true
});
this.dummy = active;
}
还有中继器:
// Repeater pour les notes des modes
Repeater {
id : repModes
model : modes
//delegate : holeComponent - via Loader, to specify the "note" to display
Loader {
id : loaderModes
Binding {
target : loaderModes.item
property : "note"
value : modes[model.index].note
}
Binding {
target : loaderModes.item
property : "visible"
value : modes[model.index].activated
}
sourceComponent : holeComponent
}
}
我正在通过某个复选框控制 modeClass 实例的 activated 属性。
我没有设法让可见性工作的属性绑定。 它仅适用于组件的实例化,不会对属性更改做出反应。
我尝试了几种方法来进行绑定:
备选方案 1
带有getter和setter的属性
Binding {
target : loaderModes.item
property : "visible"
value : modes[model.index].activated
}
备选方案 2
带有“直接”属性(没有getter,没有setter)
Binding {
target : loaderModes.item
property : "visible"
value : modes[model.index].dummy
}
备选方案 3
采用“自下而上”的方法
Loader {
id : loaderModes
...
property bool showhide: modes[model.index].activated
//property bool showhide: modes[model.index].dummy
sourceComponent : holeComponent
}
在组件中:
Component {
id : holeComponent
Image {
id : img
property var note
visible : showhide
备选方案 4
在模型级别工作:
Repeater {
id : repModes
model : modes.filter(function(m) { return m.activated; })
//model : modes.filter(function(m) { return m.dummy; })
这些都不起作用。 holeComponents 的可见性始终保持在实例化时。
还有其他方法吗?
======================= 27/10 编辑:KISS 版本:
ColumnLayout {
id : layConfig
Repeater {
model : modes
delegate : CheckBox {
id : chkConfig
property var __mode : modes[model.index]
Layout.alignment : Qt.AlignLeft | Qt.QtAlignBottom
text : __mode.name + (__mode.activated ? "++" : "--")
checked : __mode.activated;
onClicked : {
console.log("onClik",__mode.name,modelData.name);
__mode.activated = !__mode.activated;
console.log("mode.activated ==> ",__mode.activated);
console.log("modelData.activated ==> ",modelData.activated);
}
}
}
}
我希望当单击复选框时,复选框文本会通过属性绑定自动更改。它不是。我想这可能与property var __mode : modes[model.index] 有关。我应该改用modelData。但是对于modelData,我无法访问更新的底层对象属性。所以它也不起作用。
日志输出:
Debug: onClik Mode 1 Mode 1
Debug: mode.activated ==> **true**
Debug: modelData.activated ==> **false**
Debug: onClik Mode 1 Mode 1
Debug: mode.activated ==> false
Debug: modelData.activated ==> false
【问题讨论】:
-
为什么不用common QML 方式定义属性,而是使用
Object.defineProperty?您想在中继器中实例化什么组件?无论如何,我看到 KISS principle 不是你最喜欢的 :-) -
请尝试绑定到
Loader的visible属性,就像我在这里的回答:stackoverflow.com/questions/64261836/gridlayout-arrangement/… -
Amfasis 它不起作用。我想问题出在其他地方。请看我的小例子。该问题似乎与访问模型中的对象有关。 @foibis 我承认,我来自一个强类型的世界(java),我无法摆脱我纯粹的 OO 习惯。你有什么建议让它更 KISS?
-
我是否面临 QML 优化的一些缺点,即在一定程度的深度后停止属性绑定?
-
我建议你单独设置一个包含uuids和modes/properties的数据结构,var data = [{uuid: 1234, mode: xyz}, {uuid:2382, mode: abc}]。然后,您可以让委托查询数据或在实例化时通过 connect' 功能将正确的数据传递给委托。
标签: qt qml repeater property-binding