我想从JavaScript文件中发出信号,并在QML文件中接收它(以找到耗时操作何时完成)。
我该如何做呢?
我该如何做呢?
既然Alex和Raja的解决方案都有缺点,就不能很好地回答这个问题。Alex的方法是直接从javascript代码中调用QML slot方法,而Raja的方法是从Javascript代码中设置QML对象的属性值。两种方法都否认了信号/插槽机制的主要优点,即发出信号的对象不需要知道插槽。
更符合信号/插槽机制精神的方法在这篇博客文章中描述(不是我的)。它在javascript文件中创建了一个QML对象(通过Qt.createQmlObject()
函数),该对象唯一的功能是包含javascript对象信号。通过调用内部的QML对象信号(例如internalQmlObject.signalName()
)从javascript中发出信号,并且javascript对象信号可以使用通常的connect
机制通过javascriptObject.internalQmlObject.signalName.connect(receiver.slotName)
连接到QML插槽中。
以下示例改编自博客文章:
javascript_object.js:
var internalQmlObject = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal someSignal(int value) }', Qt.application, 'InternalQmlObject');
function doSomething() {
internalQmlObject.someSignal(42);
}
test.qml:
import QtQuick 2.0
import 'javascript_object.js' as JavascriptObject
Rectangle {
Rectangle {
id: someComponent
function someSlot(v) {
console.log("Signal received " + v);
}
}
Component.onCompleted: {
JavascriptObject.internalQmlObject.someSignal.connect(someComponent.someSlot);
JavascriptObject.doSomething();
}
}
执行时会得到以下结果:
% qmlscene test.qml
Signal received 42
谢谢,@RajaVarma。
我已经为自己找到了解决方案。
在qml文件中:创建元素项目(Item),其中包含充当槽的函数。 例如(我需要知道何时处理登录事件):
import "scripts/auth.js" as Auth
...
Item {
id: loginItem
// Send himself to javascript module named Auth
Component.onCompleted: {
Auth.setLoginItem(loginItem);
}
// "Slot" function
function logged() {
console.debug("Login successfully");
// Do something
...
}
}
var loginItem;
function setLoginItem(tempLoginItem) {
loginItem = tempLoginItem;
}
...
// Emit "signal"
loginItem.logged();
...
嗯,从真正的JS文件中调用信号非常不专业。但是有一个更好的选择,在我看来,我自己使用了这个方法。创建你自己的类。
MyClass.qml
import QtQuick 2.0
QtObject
{
property var myVariable
function myFunction() { console.log("emitting signal"); mySignal() }
signal mySignal
}
通过这种方式,您可以轻松实现所需的封装。而且您甚至可以很好地连接到对象。
然后,您可以随心所欲地使用它:从中创建一个单例,创建一个全局对象,实例化它。