如何从javascript向qml发射信号

7
我想从JavaScript文件中发出信号,并在QML文件中接收它(以找到耗时操作何时完成)。
我该如何做呢?
3个回答

10

既然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

我同意。好的解决方案。 - aleks_misyuk

5

谢谢,@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
      ...
   }
}

js-file 中: 创建一个用于 loginItem 的接收器,并使用它。
var loginItem;

function setLoginItem(tempLoginItem) {
    loginItem = tempLoginItem;
}

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

请仅返回翻译后的文本:与问题无关,但 "logged in" 的正确形式是 "已登录" 而不是 "logined" ;) - Kamil Klimek
4
很抱歉我的英语不好,我承诺这个月将参加语言课程。 - aleks_misyuk

2

嗯,从真正的JS文件中调用信号非常不专业。但是有一个更好的选择,在我看来,我自己使用了这个方法。创建你自己的类。

MyClass.qml

import QtQuick 2.0

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

通过这种方式,您可以轻松实现所需的封装。而且您甚至可以很好地连接到对象。

然后,您可以随心所欲地使用它:从中创建一个单例,创建一个全局对象,实例化它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接