[英]Why does it look like IPC messages from one menu item in Electron reach my window, but not when sent from another menu iteam?
I have a simple application that needs to run a background process to get some data. 我有一个简单的应用程序,需要运行一个后台进程来获取一些数据。 I would like to show a loading indicator while the data is being retrieved and I am having trouble with getting that done. 我想在检索数据时显示一个加载指示器,但在完成任务时遇到了麻烦。
I am using ipcrenderer
to receive the message in the main window. 我正在使用ipcrenderer
在主窗口中接收消息。 My code is below: 我的代码如下:
//// main.js
const electron = require('electron');
const url = require('url');
const path = require('path');
const {
app,
BrowserWindow,
Menu,
ipcMain
} = electron
// SET ENV
//process.env.NODE_ENV = 'production';
let mainWindow;
let addWindow;
let workerWindow;
// Listen for app to be ready
app.on('ready', function () {
// Create new window
mainWindow = new BrowserWindow({});
// Load the HTML file into the window
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'mainWindow.html'),
protocol: 'file',
slashes: true
}));
// Quit app when closed
mainWindow.on('closed', function () {
app.quit();
})
// Build menu from menu template
const mainMenu = Menu.buildFromTemplate(mainMenuTemplate);
// Insert menu
Menu.setApplicationMenu(mainMenu);
});
// Handle create worker window
function createWorkerWindow() {
mainWindow.webContents.send('status:showLoading'); // This does NOT work
// Create new window
workerWindow = new BrowserWindow({
width: 300,
height: 200,
title: 'workerWindow',
show: process.env.NODE_ENV == 'production' ? false : true
});
// Load the HTML file into the window
workerWindow.loadURL(url.format({
pathname: path.join(__dirname, 'worker.html'),
protocol: 'file',
slashes: true
}));
// Garbage collection
workerWindow.on('close', function () {
workerWindow = null;
})
mainWindow.webContents.send('status:hideLoading'); // This does NOT work
}
// Catch item:add-worker
ipcMain.on('item:add-worker', function(e, item){
console.log(item);
mainWindow.webContents.send('item:add-worker', item);
workerWindow.close();
});
// Create menu template
const mainMenuTemplate = [{
label: 'File',
submenu: [
{
label: 'Add Item from Worker',
click() {
mainWindow.webContents.send('status:showLoading'); // This does NOT work
createWorkerWindow();
}
},
{
label: 'Clear Items',
click(){
mainWindow.webContents.send('item:clear'); // This works
}
},
{
label: 'Show Loading',
click(){
mainWindow.webContents.send('status:showLoading'); // This works
}
},
{
label: 'Hide Loading',
click(){
mainWindow.webContents.send('status:hideLoading') // This works
}
},
{
label: 'Quit',
accelerator: process.platform == 'darwin' ? 'Command+Q' : 'Ctrl+Q',
click() {
app.quit();
}
}
]
}];
When I use the Show Loading
and Hide Loading
menu items, the main window receives the message and does what it needs to do. 当我使用“ Show Loading
和“ Hide Loading
项”菜单项时,主窗口会收到消息并执行所需的操作。 However, when I click the Add Item from Worker
menu item, the message appears to not reach the main window. 但是,当我单击“ Add Item from Worker
菜单项时,该消息似乎未到达主窗口。
<!-- mainWindow.html --> <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Security-Policy" content="default-src file: https:"> <title>Shopping List</title> <!-- Compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css"> <link rel="stylesheet" href="mainWindow.css"> </head> <body> <nav> <div class="nav-wrapper"> <a class="brand-logo center">Shopping List</a> <div id="loadingIndicator" class="progress"> <div class="indeterminate"></div> </div> </div> </nav> <ul></ul> <script src="mainWindow.js"></script> </body> </html>
//// mainWindow.js
// Show Loading
ipcRenderer.on('status:showLoading', function(){
document.getElementById('loadingIndicator').style.display = 'block';
});
// Hide Loading
ipcRenderer.on('status:hideLoading', function(){
document.getElementById('loadingIndicator').style.display = 'none';
});
I tried to add the mainWindow.webContents.send('status:showLoading');
我试图添加mainWindow.webContents.send('status:showLoading');
line in side the click()
function for the menu item and inside the createWorkerWindow()
function. 线一侧的click()
菜单项和内部功能createWorkerWindow()
函数。 Neither appear to work. 两者似乎都不起作用。
Any insight would be much appreciated. 任何见解将不胜感激。
Thank you. 谢谢。
The problem is that loading a url in a browser window isn't synchronous so when it runs createWorkerWindow
it will send the status:showLoading
message then it'll create the worker window and send the status:hideLoading
all in a split second. 问题在于,在浏览器窗口中加载URL是不同步的,因此当它运行createWorkerWindow
,它将发送status:showLoading
消息,然后将创建工作器窗口并发送status:hideLoading
。 If you wanted to hide the loading window after the worker window has finished loading you can use: 如果要在工作程序窗口完成加载后隐藏加载窗口,可以使用:
workerWindow.webContents.on('did-finish-load', function () {
mainWindow.webContents.send('status:hideLoading');
});
Although keep in mind this will run when any url is loaded not just the first one. 尽管请记住,这将在加载任何URL而不只是第一个URL时运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.