以MenuItem
为例,通常在QML中,指定triggered
信号的处理程序很简单:
MenuItem {
onTriggered: {
console.log("Hey");
}
}
现在,如果我想做同样的事情,而是动态创建的MenuItem
,例如通过Menu.addItem()
,那么连接和指定信号处理程序的语法是什么?
我没想到这会起作用,但这是一个有效的解决方案:
function onTriggered() {
console.log("Hey");
}
var newItem = myMenu.addItem("Item 1");
newItem.triggered.connect(onTriggered);
然而还有更好的方法吗?上面我定义了一个恰好命名为onTriggered
的自定义函数,但它可以命名为任何东西,对吧?所以这段代码没有使用内置的处理程序,这就是为什么我想知道是否有更简洁的解决方案?
更重要的是,后来我注意到了这种方法的进一步问题:在for循环中,如果处理程序使用了临时变量,那么事情就不再起作用了:
for (var i = 0; i < myArray.length; i ++) {
var info = myArray[i];
var newItem = myMenu.addItem("Item " + i);
newItem.triggered.connect(function() {
console.log(info);
});
}
在这里,您会看到控制台在info
中打印 last myArray
,以便在触发时显示所有添加的菜单项。如何为每个菜单项正确设置独立处理程序?
答案 0 :(得分:1)
除了评论之外,您还可以轻松地使其更容易&#34;:
Menu {
id: myMenu
function add(text, handler) {
var newItem = addItem(text)
newItem.triggered.connect(handler)
}
}
你有它,问题解决了,现在你可以简单地myMeny.add("Item 1", onTriggered)
至于你在循环和仿函数中得到的结果,这是因为JS的范围规则。查看链接的答案,了解如何解决该问题的详细信息。
所以这段代码没有使用内置处理程序
不要将onSignal
视为处理程序,它只是附加处理程序的钩子。将其视为声明性连接语法。当然,你也可以在声明中使用Connection
元素,但只有当情况真正有用时它才有意义。
我认为这种混淆源于其他一些为您生成处理程序方法的语言/框架。 onSignal
与function onSignal() { expression }
不同 - 后者是处理函数,前者是处理程序钩子,它只是将信号连接到绑定的expression.eval()
。 Qt文档也将onSignal
称为处理程序,IMO在技术上和概念上都是错误的,因为处理程序是执行的代码,处理程序是绑定到onSignal
的任何内容。
所以你可以轻松休息,你担心的代码不会导致任何冗余或效率低下,并且不会留下任何未使用的东西,实际上是用QML做事的正确方法。
所有这一切,你可以拥有内置处理程序&#34;但它是一个非常不同的东西:
// SomeItem.qml
Item {
signal someSignal
onSomeSignal: console.log("I am a built in handler")
}
// main.qml
SomeItem {
onSomeSignal: console.log("I am another handler")
Component.onCompleted: {
someSignal.connect(function(){console.log("Yet another handler")})
someSignal()
}
}
控制台中的输出会说:
qml: I am a built in handler
qml: I am another handler
qml: Yet another handler
如你所见,它不是一个真正的处理程序,而是一个连接钩子。没有阴影,没有&#34;替换/不使用内置处理程序&#34;,只有一个信号有3个连接来评估三个表达式。
将signal.connect()
与命名函数一起使用确实有一个优点,如果您需要删除内置函数或其他处理程序,可以稍后signal.disconnect(namedFunction)
。如果您使用onSignal: expr
,我不确定您是否可以这样做,因为您没有办法引用该匿名表达式。请注意,如果您使用onSignal: namedFunction()
这将无效,您将无法signal.disconnect(namedFunction)
,因为信号不直接连接到该函数,而是调用它的匿名表达式。