electron 主进程与渲染进程通讯

主进程和渲染器进程

Electron 有两种进程:主进程和渲染进程。

  • 主进程通过创建 BrowserWindow 实例来创建 网页。 每一个 BrowserWindow 实例在其渲染过程中运行网页, 当一个 BrowserWindow 实例被销毁时,对应的渲染过程也会被终止。
  • 主进程 管理 所有网页及其对应的渲染进程。

  • 渲染进程只能管理相应的网页, 一个渲染进程的崩溃不会影响其他渲染进程。
  • 渲染进程通过 IPC 与主进程通信在网在页上执行 GUI 操作。 出于安全和可能的资源泄漏考虑,直接从渲染器进程中调用与本地 GUI 有关的 API 受到限制。

进程之间的通信可以通过 Inter-Process Communication (IPC) 模块进行:ipcMain 和 ipcRenderer

若要创建一个窗口,请调用 BrowserWindow 类,但只能在主进程中使用 (main.js):

const { BrowserWindow } = require('electron')
const win = new BrowserWindow()

若要从渲染进程调用主进程,请使用 IPC 模块: 例如净化窗口模式下自定义关闭窗口功能

1. 首先由主进程向渲染进程发送消息,告诉它窗口的 id (开启了多个渲染进程);

win.once('ready-to-show', () => {
    win.webContents.send('init_win_id', win.id);
    win.show()
  });

 2. 在渲染进程接收 winid, 并在关闭窗口时发送给主进程

//渲染进程监听init_win_id事件(自定义),将winid赋给全局变量winid
let winid = '';

require('electron').ipcRenderer.on('init_win_id', (event, message) => {
		winid = message;
})


// 关闭窗体
	function closex(){
		 
		 //渲染进程里把窗口id发给主进程

		const { ipcRenderer } = require('electron')
		ipcRenderer.send('close_window', winid);
	 
	}

3. 在主进程中接收需要关闭的渲染进程

// 主进程获取winid关闭窗体
ipcMain.on('close_window', (event, arg) => {

    //app.quit()单个窗口可以直接app.quit()
    //win.close();
    // 1、接收渲染进程发来的窗口id
    let winid = arg;
    console.log(winid);
    // 2、通过id找到对应的BrowserWindow对象(win、win22),调用这个对象的close()关闭对应的窗口
    BrowserWindow.fromId(winid).close();
   
})

 主进程创建并关闭多个渲染进程

主脚本指定了运行主进程的 Electron 应用程序的入口 , 通常是 man.js 文件 , Electron 应用程序只能有一个主进程。

1. 为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,需要从 electron 包导入了 app 和 BrowserWindow 模块,

const { app, BrowserWindow } = require('electron')

2.  定义一个创建新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 index.html 文件加载到窗口中,

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
//注意: 设置 nodeIntegration 选项为 true 表示渲染过程中可以访问Node.js API 
      nodeIntegration: true
    }
  })

  win.loadFile('index.html')
}

3. 调用 createWindow方法,在 electron app 第一次被初始化时创建一个新的窗口

app.whenReady().then(createWindow)

4.  添加一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的。

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

5.  添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序。

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

-------------------------------------------------------------------------------------- 创建多个窗口 -----------------------

若要创建一个窗口,请调用 BrowserWindow 类,再次创建一个 BrowserWindow 实例,但只能在主进程中使用:我们可以修改以上代码


const {
	app,
	BrowserWindow
} = require('electron')

//全局访问
let win
let win22

function createWindow() {
	win = new BrowserWindow({
		width: 800,
		height: 600,
		frame: false,
		webPreferences: {
			nodeIntegration: true
		}
	})

	win.loadFile('index.html')
	win.once('ready-to-show', () => {
		win.show()
	})

	win22 = new BrowserWindow({
		width: 800,
		height: 600,
		frame: false,
		webPreferences: {
			nodeIntegration: true
		}
	})

	win22.loadFile('index.html')
	win22.once('ready-to-show', () => {
		win.show()
	})

}

app.whenReady().then(createWindow)

app.on('window-all-closed', () => {
	if (process.platform !== 'darwin') {
		app.quit()
	}
})

app.on('activate', () => {
	if (BrowserWindow.getAllWindows().length === 0) {
		createWindow()
	}
})

BrowserWindow 对象可调用的成员有很多,比如 id 获取唯一窗口 id,close () 成员方法关闭窗口等

-------------------------------------------------------------------------------------- 删除多个窗口 -----------------------

在主进程中将多个窗口的 id 分别发送给各自的渲染窗口,主 -> 渲染通讯 使用 BrowserWindow 实例属性 webContents 的 send () 方法实现

const {
	app,
	BrowserWindow
} = require('electron')
let win
let win22

function createWindow() {
	win = new BrowserWindow({
		width: 800,
		height: 600,
		frame: false,
		webPreferences: {
			nodeIntegration: true
		}
	})

	win.loadFile('index.html')
	win.once('ready-to-show', () => {
		win.webContents.send('init_win_id', win.id);
		win.show()
	})

	win22 = new BrowserWindow({
		width: 800,
		height: 600,
		frame: false,
		webPreferences: {
			nodeIntegration: true
		}
	})

	win22.loadFile('index.html')
	win22.once('ready-to-show', () => {
		win22.webContents.send('init_win_id', win22.id);
		win22.show()
	})

}

app.whenReady().then(createWindow)

app.on('window-all-closed', () => {
	if (process.platform !== 'darwin') {
		app.quit()
	}
})

app.on('activate', () => {
	if (BrowserWindow.getAllWindows().length === 0) {
		createWindow()
	}
})

在各自的渲染窗口中获取 winid. 并在关闭窗口事件中将之传给主进程,由主进程关闭渲染进程

以下是主进程获取到需要关闭的窗口 id 以后需要执行的操作

const {
	ipcMain
} = require('electron')
ipcMain.on('close_window', (event, arg) => {
 let winid;
  winid = arg
  console.log(winid);
//根据id获取 BrowserWindow实例,然后调用close()方法
  BrowserWindow.fromId(winid).close();
 
})

关闭一个渲染进程,开启另一个渲染进程 

1. 将登录页面的窗口 id 发给主进程

let winid = '';

	require('electron').ipcRenderer.on('init_win_id', (event, message) => {
		winid = message;
    })

function dologin()
{
//登录成功以后
const {ipcRenderer} = require('electron')
ipcRenderer.send('dologin',winid)//winid是主进程在初始化登录页面时传过来的
}

接着在主进程中接收 winid, 关闭登录窗口,显示 qq 聊天界面

const {
	app,
	BrowserWindow
} = require('electron')
var win;
let winQQList;
function createWindow() {
	win = new BrowserWindow({
		width: 1200,
		height: 800,
		frame: false,
		show: false,
		webPreferences: {
			nodeIntegration: true,
			enableRemoteModule: true,
		}
	});

	win.loadFile('login.html');

	win.once('ready-to-show', () => {
		// 向渲染进程发消息,告诉它窗口的id
		global.winid = win.id;
		win.webContents.send('init_win_id', win.id);
		win.show()
	});
	
}

ipcMain.on('dologin', () => {
        let winid = arg
		winQQList = new BrowserWindow({
			width: 300,
			height: 800,
			frame: false,
			show: false,
			webPreference: {
				nodeIntegration: true
			}

		})
		winQQList.loadFile('list.html')

		winQQList.once('ready-to-show', () => {
			winwinQQList.webContents.send('init_win_id', winQQList.id);
			winQQList.show()
		})


	})

转自主进程创建并关闭多个渲染进程 - imzchloe的个人空间 - OSCHINA - 中文开源技术交流社区 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值