gpt4 book ai didi

javascript - QML:Lambda 函数意外运行

转载 作者:数据小太阳 更新时间:2023-10-29 04:08:58 27 4
gpt4 key购买 nike

我认为 QML 支持 lambda 函数是因为 JavaScript 支持匿名函数以及函数是一流对象这一事实,但它们并不像我预期的那样工作。拿这段代码:

Item {
property var items: []

function handler( item ) {
console.log( item );
}

Component.onCompleted: {
for ( var i = 0; i < 3; ++i ) {
var item = someObj.createObject();
item.someValueChanged.connect( function() {
handler( item ); } );

items.push( item );
console.log( "Adding:", item );
}
}

Component {
id: someObj

Item {
property bool someValue: false

Timer {
running: true
onTriggered: {
parent.someValue = true;
}
}
}
}
}

我正在尝试使用 lambda function() { handler( item ); } 这样,当发出 someObj::someValueChanged 信号时,发射项将传递给 handler( item ) 函数。

假设每个循环都会创建一个新的 lambda 实例,并且 item 引用会携带 someObj 实例的引用在该循环中创建(即 item 将被 lambda 捕获)。但事实并非如此,因为输出是:

qml: Adding: QQuickItem_QML_1(0x2442aa0)
qml: Adding: QQuickItem_QML_1(0x2443c00)
qml: Adding: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)

如您所见,要么在每个循环中替换整个函数,要么只替换 item 引用,因此最终只引用最后创建的 someObj。有人可以向我解释为什么 lambda(如果它是这样的话)不能按我期望的方式工作吗?这是 QML 问题,还是一般的 JavaScript 问题?

最佳答案

尝试这样的事情:

item.someValueChanged.connect(function(capture) {
return function() {
handler(capture)}
}(item))

很直观,对吧? :D

如果 JS 使用“ block 作用域”,则每次循环迭代都会引用 3 个不同的 item,并且它将“按预期工作”。但是对于“功能范围”,只有一个 item 被引用,并且它引用了它的最终值,因此需要使用 hack 来及时“捕获”每个值。​​

只是解释一下,如果不是很明显,信号连接到一个处理程序,该处理程序由一个函数仲裁,该函数在特定时间将参数值捕获为离散对象,用于馈送到处理程序。

希望最初的 Qt 5.12 版本能够通过引入对 let 的支持来解决这个问题,也就是 block 作用域变量。

更新:我可以确认使用 5.12,它现在可以按预期工作:

let item = someObj.createObject(); // will produce 3 distinct obj refs

关于javascript - QML:Lambda 函数意外运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28898526/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com