【问题标题】:How to use JavaScript libraries on QML如何在 QML 上使用 JavaScript 库
【发布时间】:2019-04-05 09:08:52
【问题描述】:

我在 5.12.2 上使用了一些带有 QML 的 javascript 库。其中一些像 Proj4JS 一样工作。但是在将 geographiclib.js 库与 QML 一起使用时出现错误。 JavaScript库如何导入QML?

main.qml:

import QtQuick 2.12
import QtQuick.Window 2.12
import "geographiclib.js" as MyGeo
Window {
    visible: true
    width: 640
    height: 480
    Component.onCompleted: {
        var Geodesic = MyGeo.GeographicLib.Geodesic,
            DMS = MyGeo.GeographicLib.DMS,
            geod = Geodesic.WGS84;
        var r = geod.Inverse(23, 22, 44, 29);
        console.log("distance is: ", r.s12.toFixed(3) + " m")
    }
}

错误:

qrc:/geographiclib.js:3081: ReferenceError: window is not defined
qrc:/main.qml:9: TypeError: Cannot read property 'Geodesic' of undefined

【问题讨论】:

  • 您将 .js 文件放在哪里(在运行时)?我认为它应该作为资源附加到 .qrc
  • js文件在qrc:<file>main.qml</file><file>geographiclib.js</file>

标签: javascript qt qml


【解决方案1】:

最简单的方法是让GeographicLib 全局可用:

geographiclib.js文件的最后,更改

window.GeographicLib = geo;

this.GeographicLib = geo;

然后你就可以使用:

main.qml:

import QtQuick 2.12
import QtQuick.Window 2.12
import "geographiclib.js" as ThenItWillBeAvailableGlobally
Window {
    visible: true
    width: 640
    height: 480
    Component.onCompleted: {
        var Geodesic = GeographicLib.Geodesic,
            DMS = GeographicLib.DMS,
            geod = Geodesic.WGS84;
        var r = geod.Inverse(23, 22, 44, 29);
        console.log("distance is: ", JSON.stringify(r))
    }
}

导致:

qml: distance is:  {"lat1":23,"lat2":44,"lon1":22,"lon2":29,"a12":21.754466225665134,"s12":2416081.7576307985,"azi1":13.736139413215236,"azi2":17.669059640534535}

如果您根本不想更改 geographiclib.js 文件,您可以添加一个全局窗口对象,例如:

window.js:

this.window = this;

然后使用:

import QtQuick 2.12
import QtQuick.Window 2.12
import "window.js" as ThenWindowWillBeAvailableGlobally
import "geographiclib.js" as ThenGeographicLibWillBeAvailableGlobally
Window {
    visible: true
    width: 640
    height: 480
    Component.onCompleted: {
        var Geodesic = GeographicLib.Geodesic,
            DMS = GeographicLib.DMS,
            geod = Geodesic.WGS84;
        var r = geod.Inverse(23, 22, 44, 29);
        console.log("distance is: ", JSON.stringify(r))
    }
}

如果您不想添加任何全局变量但您很乐意编辑 geographiclib.js 文件,那么您只需将第 68 行移至文件顶部:

var GeographicLib = {};
/*
 * Geodesic routines from GeographicLib translated to JavaScript.  See
 * https://geographiclib.sourceforge.io/html/js/

并在文件更改结束时

  } else {
    /******** otherwise just pollute our global namespace ********/
    window.GeographicLib = geo;
  }
});

  } else if (typeof window === 'object') {
    /******** otherwise just pollute our global namespace ********/
    window.GeographicLib = geo;
  }
});

然后你的 main.qml 就可以正常工作了。

【讨论】:

  • 感谢您的精彩回答!如果我继续使用带有 QML 的 npm 包,我将不需要启动 React Native :) 我希望 Qt 公司会添加有关此的详细文档。顺便说一下距离打错了,应该是"distance is: ", r.s12
【解决方案2】:

您正在正确导入 javascript 文件。

来自doc

QML 提供了一个为编写 QML 量身定制的 JavaScript 宿主环境 应用程序。此环境与宿主环境不同 由浏览器或服务器端 JavaScript 环境提供,例如 节点.js。例如,QML 不提供窗口对象 或 DOM 浏览器环境中常见的 API。

【讨论】:

  • 我认为在 5.12.2 上支持 Ecmascript 7,QML 可能会接受窗口对象。 JavaScript 库包含窗口对象。不幸的是,我不知道如何为 QML 安装 javascript 库。我尝试了像 Qmljsfy(一个 qml 模块,用于将 npm 包转换为 QML javascript 文件)之类的库,但没有成功。
  • 谢谢。我没有收到窗口错误,但我收到了TypeError: Cannot read property 'Geodesic' of undefined
猜你喜欢
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
相关资源
最近更新 更多