如何在Electron Framework中将信息从一个窗口发送到另一个窗口

本文概述

  • 1.配置2个Windows(可选)
  • 2.在主进程中添加侦听器以在Windows之间共享数据
  • 3.在第二个窗口的视图中添加侦听器以接收数据
  • 4.触发分享事件
  • 例子
【如何在Electron Framework中将信息从一个窗口发送到另一个窗口】许多桌面应用程序提供操纵和自定义功能。这些功能通常(并非总是)位于与原始应用程序不同的窗口中, 因此在使用Electron时, 你将需要学习如何将信息从一个窗口共享到另一个窗口。
在本文中, 我们将向你展示如何使用Electron的IPCMain和IPCRenderer模块来完成此简单任务。
注意 该过程可以双向进行, 因此你可以按照以下步骤将信息从第一个窗口发送到第二个窗口, 反之亦然。
1.配置2个Windows(可选) 如果主进程中已经有2个Windows实例, 则跳过此步骤。在我们的示例中, 我们将有2个带有变量mainWindow和secondWindow的窗口。这些窗口是在主进程中创建的(来自main.js), 它们将同时显示, 因此你可以根据需要更改其行为。重要的是你有2个Windows, 并且可以通过变量访问它们:
// Keep a global reference of the windows object, if you don't, the window will// be closed automatically when the JavaScript object is garbage collected.let mainWindow; let secondWindow; function createWindow() {// Create the browser window.mainWindow = new BrowserWindow({ width: 800, height: 600 }); secondWindow = new BrowserWindow({ width: 800, height: 600 }); // and load the index.html of the app.mainWindow.loadURL(url.format({pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true}))// and load the second window.secondWindow.loadURL(url.format({pathname: path.join(__dirname, 'otherfile.html'), protocol: 'file:', slashes: true}))// Emitted when the window is closed.mainWindow.on('closed', function () {// Dereference the window object, usually you would store windows// in an array if your app supports multi windows, this is the time// when you should delete the corresponding element.mainWindow = null; secondWindow = null; })}

这两个窗口都加载2个不同的HTML文件。
2.在主进程中添加侦听器以在Windows之间共享数据 现在, 你已经拥有两个将相互通信的窗口, 你可以在主流程中创建端点, 作为它们之间的桥梁。使用Electron的ipcMain模块, 可以在有权访问2个窗口的主窗口(后台进程)中添加” 事件侦听器” , 然后可以使用ipcRenderer从第一个窗口的视图触发此事件。
以下代码添加了一个事件侦听器(在main.js中), 该事件侦听器将在第一个窗口的视图中触发” request-update-label-in-second-window” (日期名称)事件时执行。在回调内部, 就像在可访问2个窗口的main.js文件中一样, 你可以访问要在其中发送信息的窗口的webContents属性。 webContents是一个EventEmitter。它负责呈现和控制网页, 并且是BrowserWindow对象的属性。使用send方法, 可以在第二个窗口的渲染器过程中触发一个事件(即action-update-label):
const { ipcMain } = require('electron'); // Attach event listener to event that requests to update something in the second window// from the first windowipcMain.on('request-update-label-in-second-window', (event, arg) => {// Request to update the label in the renderer process of the second window// We'll send the same data that was sent to the main process// Note: you can obviously send the secondWindow.webContents.send('action-update-label', arg); });

现在, 我们在后台建立了桥梁。接下来, 你需要在第二个窗口中构建桥的入口点。
3.在第二个窗口的视图中添加侦听器以接收数据 逻辑的其余部分非常明显, 因为你从主流程中触发了事件action-update-label, 所以当触发此事件时, 你需要在第二个窗口中执行某些操作。在第二个窗口的渲染器进程(otherfile.html)中, 使用以下代码继续使用ipcRenderer模块添加事件侦听器:
// Require ipcRendererconst { ipcRenderer } = require('electron'); // When the action-update-label event is triggered (from the main process)// Do something in the viewipcRenderer.on('action-update-label', (event, arg) => {// Update the second interface or whatever you need to do// for example show an alert ...alert("Hello, you did something in the first window !"); // arg contains the data sent from the first viewconsole.log(arg); });

现在, 当从主流程中的第一个窗口触发事件” 第二窗口中的请求更新标签” 时, 主流程将触发动作更新标签事件, 该事件将执行你需要的操作。
4.触发分享事件 最后一步, 你只需要在第一个窗口(在渲染器进程中)触发” request-update-label-in-second-window” :
const { ipcRenderer } = require('electron'); // Some data that will be sent to the main process// Feel free to modify the object as you wish !let Data = http://www.srcmini.com/{message:"Hello World !"}; // Trigger the event listener action to this event in the renderer process and send the dataipcRenderer.send('request-update-label-in-second-window', Data);

这将遵循上述逻辑, 将带有属性消息的Data对象发送到第二个视图中的渲染器进程。
例子 以下基于3个文件的示例说明了一个简单应用程序中提到的步骤:
main.js
const electron = require('electron'); const path = require('path'); const { ipcMain } = require('electron'); // Module to control application life.const app = electron.app; // Module to create native browser window.const BrowserWindow = electron.BrowserWindowconst url = require('url')// Keep a global reference of the windows object, if you don't, the window will// be closed automatically when the JavaScript object is garbage collected.let mainWindow; let secondWindow; function createWindow() {// Create the browser window.mainWindow = new BrowserWindow({ width: 800, height: 600 }); secondWindow = new BrowserWindow({ width: 800, height: 600 }); // and load the index.html of the app.mainWindow.loadURL(url.format({pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true}))// and load the second window.secondWindow.loadURL(url.format({pathname: path.join(__dirname, 'otherfile.html'), protocol: 'file:', slashes: true}))// Attach event listener to event that requests to update something in the second window// from the first windowipcMain.on('request-update-label-in-second-window', (event, arg) => {// Request to update the label in the renderer process of the second windowsecondWindow.webContents.send('action-update-label', arg); }); // Emitted when the window is closed.mainWindow.on('closed', function () {// Dereference the window object, usually you would store windows// in an array if your app supports multi windows, this is the time// when you should delete the corresponding element.mainWindow = null; secondWindow = null; })}// This method will be called when Electron has finished// initialization and is ready to create browser windows.// Some APIs can only be used after this event occurs.app.on('ready', createWindow)// Quit when all windows are closed.app.on('window-all-closed', function () {// On OS X it is common for applications and their menu bar// to stay active until the user quits explicitly with Cmd + Qif (process.platform !== 'darwin') {app.quit()}})app.on('activate', function () {// On OS X it's common to re-create a window in the app when the// dock icon is clicked and there are no other windows open.if (mainWindow === null) {createWindow()}})

index.html
< !DOCTYPE html> < html lang="en"> < head> < meta charset="utf-8"> < meta http-equiv="X-UA-Compatible" content="IE=edge"> < title> Electron Application< /title> < meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1"> < /head> < body> < div id="app"> Hello First Window< br /> < input type="text" id="field" value="http://www.srcmini.com/This String Will be Sent to the second Window" /> < input type="button" id="btn" value="http://www.srcmini.com/Update Label in Second Window with Text" /> < /div> < script> const { ipcRenderer } = require('electron'); document.getElementById("btn").addEventListener("click", () => {// Some data that will be sent to the main processlet Data = http://www.srcmini.com/{message: document.getElementById("field").value, backgroundColor: "black", color: 'white'}; // Trigger the event listener action to this event in the renderer process and send the dataipcRenderer.send('request-update-label-in-second-window', Data); }, false); < /script> < /body> < /html>

otherfile.html
< !DOCTYPE html> < html lang="en"> < head> < meta charset="utf-8"> < meta http-equiv="X-UA-Compatible" content="IE=edge"> < title> Electron Second Window< /title> < meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, maximum-scale=1, minimum-scale=1"> < /head> < body> < div id="app"> Hello Second Window< br /> < span id="label"> Hello This Label Will be updated < /span> < /div> < script> const { ipcRenderer } = require('electron'); ipcRenderer.on('action-update-label', (event, arg) => {// Update the second window label content with the data sent from// the first window :) !let label = document.getElementById("label"); label.innerHTML = arg.message; label.style.color = arg.color; label.style.backgroundColor = arg.backgroundColor; }); < /script> < /body> < /html>

在Electron中执行前面的代码, 将显示2个窗口。在第一个窗口中, 你会找到一个简单的文本输入和一个按钮, 单击该按钮后, 它将向你发送具有CSS样式(背景色为黑色和文本色为白色)的对象, 并将输入的文本发送到第二个窗口。在第二个窗口中, 将处理该对象并将其显示在视图中:
如何在Electron Framework中将信息从一个窗口发送到另一个窗口

文章图片
请注意, 你可以遵循相同的过程, 但是要反向进行(从第二个窗口到第一个窗口)。
编码愉快!

    推荐阅读