如何从 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 04:15:40  来源:igfitidea点击:

How to Emit signals from javascript to qml

javascriptqtqt4qmlqt-quick

提问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 connectmechanism 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.

然后你可以用它做任何你想做的事情:从它创建一个单例,创建一个全局对象,实例化它。