iro*_*s7x 4 html python electron
我在 Electron JS 中有一个应用程序,它调用 python 函数来执行 python 脚本。当脚本执行时,它应该将数据发送回 Electron JS GUI 并显示它。
我遇到的问题是它说 join 未定义:
Weather.js:9未捕获类型错误:无法在HTMLButtonElement.onclick(weather.html:14)的get_weather(weather.js:9)读取未定义的属性“join”
这是我的 JavaScript 文件:
let {PythonShell} = require('python-shell')
var path = require("path")
function get_weather() {
var city = document.getElementById("city").value
var options = {
scriptPath : path.join(__dirname, '/../engine/'),
args : [city]
}
let pyshell = new PythonShell('weatherApp.py', options);
pyshell.on('message', function(message) {
swal(message);
})
document.getElementById("city").value = "";
}
Run Code Online (Sandbox Code Playgroud)
“scriptPath : path.join(__dirname, '/../engine/'),”行似乎是有问题的代码。
我的gui.html文件如下:
<html>
<head>
<title></title>
<meta charset="UTF-8">
</head>
<body>
<h1>Get your local weather ...</h1>
<br>
<br>
<label>Enter city name here: <label>
<input id="city" type = "text" placeholder="City">
<button type = "button" value="clickme" onclick="get_weather()">Get Weather</button>
<!--- <button class="btn btn-success" onclick="get_weather();">Go!</button> -->
<br>
<br>
<br>
<script src="/home/ironmantis7x/Documents/BSSLLC/projects/node_electron/electronDemoApps/guiApp/gui/linkers/weather.js"></script>
<p><button type="button"><a href="gui.html">Back to Main Page</a></button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我需要修复哪些错误才能使其正常工作?
谢谢。
问题
由于 Electron 5nodeIntegration在窗口中默认处于禁用状态。由于普通浏览器 API 不知道requireor join,因此当您尝试时会出现错误。
重新启用节点集成
您可以nodeIntegration再次启用,但由于某种原因它被禁用了。请务必阅读并理解电子安全教程。
使用预加载脚本
另一种方法是使用预加载脚本。让我们看一下BrowserWindow 文档。
创建新的浏览器窗口时,您可以添加多个选项。对于这种情况,我们需要以下webPreferences.preload选项:
指定将在页面中运行其他脚本之前加载的脚本。无论节点集成是打开还是关闭,该脚本始终可以访问节点 API。该值应该是脚本的绝对文件路径。当节点集成关闭时,预加载脚本可以将节点全局符号重新引入全局范围。
请注意,预加载脚本是在渲染器进程中运行的。
例子
以下是一个示例应用程序,它打开一个带有按钮的窗口,该按钮使用电子dialog来选择文件。这不适用于禁用的情况nodeIntegration,但由于我们的预加载脚本,我们重新引入dialog.showOpenDialog()了我们的窗口。
main.js
const { app, BrowserWindow } = require("electron");
const { join } = require("path");
let win;
app.on("ready", () => {
win = new BrowserWindow({
webPreferences: {
//this is the default since electron 5
nodeIntegration: false,
//here you load your preload script
preload: join(__dirname, "preload.js")
}
});
win.loadURL(join(__dirname, "index.html"));
});
Run Code Online (Sandbox Code Playgroud)
预加载.js
const { dialog } = require("electron").remote;
window.mystuff = {
selectFile
};
async function selectFile() {
const files = await dialog.showOpenDialog({
properties: ["openFile", "multiSelections"]
});
return files;
}
Run Code Online (Sandbox Code Playgroud)
索引.html
<html>
<body>
<main>
<button onclick="myFunction()">select file</button>
<ul id="foo"></ul>
</main>
<script>
async function myFunction() {
//the function provided by the preload script
const files = await window.mystuff.selectFile();
const list = document.getElementById("foo");
for (const file of files) {
const node = document.createElement("LI");
const textNode = document.createTextNode(file);
node.appendChild(textNode);
list.appendChild(node);
}
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
通过IPC发送事件
如果您不确定您的功能是否应该在窗口中公开,您还可以通过 发送事件ipcRenderer。
预加载.js
const { ipcRenderer } = require("electron");
window.mystuff = {
selectFile
};
function selectFile() {
return new Promise(resolve => {
ipcRenderer.on("selected-files", (e, files) => {
resolve(files);
});
ipcRenderer.send("select-files");
});
}
Run Code Online (Sandbox Code Playgroud)
main.js中的附加部分
ipcMain.on("select-files", async () => {
const files = await dialog.showOpenDialog({
properties: ["openFile", "multiSelections"]
});
win.webContents.send("selected-files", files);
});
Run Code Online (Sandbox Code Playgroud)