如何在QML上使用JavaScript库

如何在QML上使用JavaScript库,javascript,qt,qml,Javascript,Qt,Qml,我在5.12.2上使用了一些带有QML的javascript库。其中一些类似于Proj4JS。但我在使用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.onCom

我在5.12.2上使用了一些带有QML的javascript库。其中一些类似于Proj4JS。但我在使用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

您正在正确导入javascript文件

从:

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


最简单的方法是在全球范围内提供
geographicalib

在geographicalib.js文件的末尾,更改

window.geographicalib=geo;

this.geographicalib=geo;
然后你可以使用:

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")
    }
}
导致:

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

如果您根本不想更改geographicalib.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))
    }
}

如果您不想添加任何全局变量,但很乐意编辑geographicalib.js文件,则只需将第68行移到文件顶部即可:

var geographicalib={};
/*
*GeographicalIB中的测地例程被翻译成JavaScript。看见
* https://geographiclib.sourceforge.io/html/js/
在文件更改的最后

}其他{
/********否则只会污染我们的全局名称空间********/
window.geographicalib=geo;
}
});

}否则如果(窗口类型==='object'){
/********否则只会污染我们的全局名称空间********/
window.geographicalib=geo;
}
});

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

你在运行时把.js文件放在哪里了?我认为它应该作为资源附加在.qrct中。js文件位于qrc:
main.qmlgeographicallib.js
我认为在5.12.2上支持Ecmascript 7时,QML可能会接受窗口对象。JavaScript库包含窗口对象。不幸的是,我不知道如何为QML安装javascript库。我尝试了Qmljsfy(一个将npm包转换为qmljavascript文件的qml模块)之类的库,但没有成功。谢谢。我没有得到窗口错误,但我得到了
TypeError:无法读取未定义的属性“测地线”
谢谢你的精彩回答!如果我继续使用带有QML:)的npm包,我就不需要启动React Native了。我希望Qt公司会添加一份关于这方面的详细文档。顺便说一下,我输入的距离是错误的,应该是
“distance is:”,r.s12