如何从 javascript 向 qml 发出信号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8696448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Emit signals from javascript to qml
提问by aleks_misyuk
I want to emit signal from javascript-file and receive it in qml-file (To find when time-consuming operation will finished).
我想从 javascript-file 发出信号并在 qml-file 中接收它(以查找耗时的操作何时完成)。
How can I do it?
我该怎么做?
回答by Peace Makes Plenty
Neither Alex's nore Raja's solutions really answer the question. Alex's consists in calling directly from the javascript code the QML slot method, and Raja's consist in setting the value of a property of a QML object from the Javascript code. Both approaches negate the main advantage of the signal/slot mechanism which is that the signalling object does not need to know of the slot.
Alex 和 Raja 的解决方案都没有真正回答这个问题。Alex 包括直接从 javascript 代码调用 QML 插槽方法,而 Raja 包括从 Javascript 代码设置 QML 对象的属性值。这两种方法都否定了信号/时隙机制的主要优点,即信令对象不需要知道时隙。
An approach closer to the spirit of the signal/slot mechanism is described in this blog post(not mine). It consists, within the javascript file, of creating a QML object (via the Qt.createQmlObject()
function) the sole function of which is to contain the javascript's object signals. Signals are emitted from javascript through calling the internal QML objects signal (e.g. internalQmlObject.signalName()
), and the javascript object signal can be connected in QML to QML slots with the usual connect
mechanism via javascriptObject.internalQmlObject.signalName.connect(receiver.slotName)
.
这篇博文(不是我的)中描述了一种更接近信号/插槽机制精神的方法。它包括在 javascript 文件中创建一个 QML 对象(通过Qt.createQmlObject()
函数),该对象的唯一功能是包含 javascript 的对象信号。信号是通过调用内部 QML 对象信号(例如internalQmlObject.signalName()
)从 javascript 发出的,并且 javascript 对象信号可以connect
通过javascriptObject.internalQmlObject.signalName.connect(receiver.slotName)
.
An example adapted from the blog post is below:
改编自博客文章的示例如下:
javascript_object.js:
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:
测试.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();
}
}
On execution it gives the following:
在执行时,它给出了以下内容:
% qmlscene test.qml
Signal received 42
回答by aleks_misyuk
Thank you, @RajaVarma.
谢谢你,@RajaVarma。
I found solution for myself.
我为自己找到了解决方案。
In qml-file: create element Item (my loginItem) which contains function that plays the role of slot. For example (I need to know when handle login event):
在qml-file 中:创建元素 Item(我的 loginItem),其中包含充当插槽角色的函数。例如(我需要知道何时处理登录事件):
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
...
}
}
In js-file: create receiver for loginItem and use it.
在js-file 中:为 loginItem 创建接收器并使用它。
var loginItem;
function setLoginItem(tempLoginItem) {
loginItem = tempLoginItem;
}
...
// Emit "signal"
loginItem.logged();
...
回答by marmistrz
Well, it's very hacky to call signals from a real JS file. But there's a better option, IMHO, used it myself instead. Create your own class.
好吧,从真正的 JS 文件中调用信号是非常困难的。但有一个更好的选择,恕我直言,我自己使用它。创建自己的类。
MyClass.qml
我的类.qml
import QtQuick 2.0
QtObject
{
property var myVariable
function myFunction() { console.log("emitting signal"); mySignal() }
signal mySignal
}
This way you can easily achieve the needed encapsulation. And you can even nicely connect to the object.
通过这种方式,您可以轻松实现所需的封装。您甚至可以很好地连接到对象。
Then you can do whatever you want with it: create a singleton from it, create a global object, instantiate it.
然后你可以用它做任何你想做的事情:从它创建一个单例,创建一个全局对象,实例化它。