QML:Lambda 函数意外工作
QML: Lambda function works unexpectedly
我认为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
。 有人可以向我解释为什么 lambdas(如果它就是这样的话)不能按照我预期的方式工作吗? 这是一个QML问题,还是一个通用的JavaScript问题?
尝试这样的事情:
item.someValueChanged.connect(function(capture) {
return function() {
handler(capture)}
}(item))
很直观,对吧?:D
如果JS使用"块范围",则每个循环迭代将引用3个不同的item
,并且它将"按预期工作"。但是对于"函数范围",只有一个item
被引用,并且它引用了它的最终值,因此需要使用该技巧来"捕获"每个值。
只是为了解释它,如果它不是很明显,信号被连接到一个处理程序,该处理程序由一个函数仲裁,该函数在特定时间捕获参数值作为离散对象,用于馈送到处理程序。
希望早期的Qt 5.12版本将通过引入对let
(即块作用域变量)的支持来弥补这一点。
更新:我可以确认使用 5.12,它现在按预期工作:
let item = someObj.createObject(); // will produce 3 distinct obj refs
dtech 的答案解决了这个问题(谢谢!),但我们可以简化它,以便更清楚地了解到底发生了什么。"内部"功能需要匿名,但"外部"功能不需要匿名。对外部函数使用普通函数会使代码更容易理解,并且由于函数具有名称,因此更容易自我记录。外部函数创建一个信号处理程序,因此等效代码可以是:
var signal_handler = create_signal_handler(item);
item.someValueChanged.connect(signal_handler);
...
function create_signal_handler(item)
{
return function() { return handler(item); }
}
- Javascript:selenium Web驱动程序isDisplayed()不工作
- jQuery UI自动完成突然停止工作
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- JavaScript打印功能使日历停止工作
- Javascript.getHours()工作不正常
- 为什么这在IE中的工作方式与在Firefox中不同
- 视频HTML没有'无法在Internet Explorer 11上工作
- 扩展移相器按钮类不工作
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 分析高度属性时出现意外值{{specs.height}}.index.html
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- AngularJS指令意外地协同工作
- QML:Lambda 函数意外工作
- 未捕获的语法错误:意外的标记o:简单的JSON解析器不工作
- 试图设置Node.js (Express)与vhost一起工作,并获得意外错误
- Angularjs的focus意外地需要async setTimeout来工作
- 流星选择器不工作,出现意外字符串错误
- setInterval()--意外的标识符,但它只工作一次
- 未捕获的SyntaxError:意外令牌非法-完全相同的代码工作正常