7

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

我该怎么做?

4

3 回答 3

10

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

这篇博文(不是我的)描述了一种更接近信号/槽机制精神的方法。它包括在 javascript 文件中创建一个 QML 对象(通过Qt.createQmlObject()函数),该对象的唯一功能是包含 javascript 的对象信号。通过调用内部 QML 对象信号(例如internalQmlObject.signalName())从 javascript 发出信号,并且 javascript 对象信号可以在 QML 中使用通常的connect机制通过javascriptObject.internalQmlObject.signalName.connect(receiver.slotName).

改编自博客文章的示例如下:

javascript_object.js:

var internalQmlObject = Qt.createQmlObject('import QtQuick 2.0; QtObject { signal someSignal(int value) }', Qt.application, 'InternalQmlObject');

function doSomething() {
    internalQmlObject.someSignal(42);
}

测试.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
于 2013-09-14T19:23:16.143 回答
5

谢谢你,@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-file 中:为 loginItem 创建接收器并使用它。

var loginItem;

function setLoginItem(tempLoginItem) {
    loginItem = tempLoginItem;
}

...
   // Emit "signal"
   loginItem.logged();
...
于 2012-01-02T23:28:35.643 回答
2

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

MyClass.qml

import QtQuick 2.0

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

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

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

于 2015-09-11T10:40:21.207 回答