如何从 javascript 向 qml 发出信号

发布于 2024-12-24 00:53:06 字数 72 浏览 2 评论 0 原文

我想从 javascript 文件发出信号并在 qml 文件中接收它(以查找耗时的操作何时完成)。

我该怎么做呢?

I want to emit signal from javascript-file and receive it in qml-file (To find when time-consuming operation will finished).

How can I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

过度放纵 2024-12-31 00:53:06

亚历克斯和拉贾的解决方案都没有真正回答这个问题。 Alex 的方法是直接从 javascript 代码调用 QML slot 方法,而 Raja 的方法是从 Javascript 代码设置 QML 对象的属性值。这两种方法都否定了信号/时隙机制的主要优点,即信令对象不需要知道时隙。

博客文章(不是我的)。它包括在 javascript 文件中创建一个 QML 对象(通过 Qt.createQmlObject() 函数),该对象的唯一功能是包含 javascript 的对象信号。信号是通过调用内部 QML 对象信号(例如 internalQmlObject.signalName())从 javascript 发出的,并且 javascript 对象信号可以使用通常的 connectjavascriptObject.internalQmlObject.signalName.connect(receiver.slotName) 的 code> 机制。

下面是根据博客文章改编的示例:

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

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.

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).

An example adapted from the blog post is below:

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();
    }
}

On execution it gives the following:

% qmlscene test.qml
Signal received 42
半岛未凉 2024-12-31 00:53:06

谢谢你,@RajaVarma。

我为自己找到了解决方案。

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
      ...
   }
}

js文件中:为loginItem创建接收器并使用它。

var loginItem;

function setLoginItem(tempLoginItem) {
    loginItem = tempLoginItem;
}

...
   // Emit "signal"
   loginItem.logged();
...

Thank you, @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):

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.

var loginItem;

function setLoginItem(tempLoginItem) {
    loginItem = tempLoginItem;
}

...
   // Emit "signal"
   loginItem.logged();
...
看海 2024-12-31 00:53:06

嗯,从真实的 JS 文件中调用信号是非常 hacky 的。但有一个更好的选择,恕我直言,我自己用过它。创建您自己的类。

MyClass.qml

import QtQuick 2.0

QtObject
{
    property var myVariable
    function myFunction() { console.log("emitting signal"); mySignal() }
    signal mySignal
}

这样就可以轻松实现所需的封装。您甚至可以很好地连接到该对象。

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

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.

MyClass.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文