05_ Electron 自定义菜单、主进程与渲染进程通信

Electron 自定义菜单、主进程与渲染进程通信

一、定义顶部菜单

单独写在一个 js 文件中,然后再在主进程中引入

javascript 复制代码
// ipMain/menu.js
const { Menu, shell} = require('electron')

let menuTemplate = [
  {
    labe: "文件",
    submenu: [
      {
        label: "新建文件",
        click: ()=>{
          console.log("Ctrl+N")
        }
      }
    ]
  },
  {
    label: "编辑",
    submenu: [
      {
        label: "复制",
        role: "copy",
        click: ()=>{

        }
      }
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  }
]
let menuBuilder = Menu.buildFromTemplate(menuTemplate)
Menu.setApplicationMenu(menuBuilder)
javascript 复制代码
// main.js
const {app, BrowserWindow} = require('electron')
const path = require('path')

// 1、引入初始化remote 模块
const remote = require("@electron/remote/main")
remote.initialize()

const createWindow = ()=>{
	const mainWindow = new BrowserWindow({
		width:800,
		height:600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	mainWindow.loadFile(path.join(__dirname, 'index.html'))
  // 打开调试模式
  // mainWindow.webContents.openDevTools()
  // 2、启用remote 模块
  remote.enable(mainWindow.webContents)
  require('./ipcMain/menu')
}

// 监听 electron ready 事件创建窗口
app.on('ready', createWindow);
// 监听窗口关闭的事件,关闭的时候退出应用, macOs 需要排除
app.on('window-all-closed', ()=>{
	if(process.platform !=='darwin') {
		app.quit();
	}
})

// Macos 中点击 dock 中的应用图标的时候重新创建窗口
app.on('activate', ()=>{
  if(BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

二、Electron 自定义右键菜单

实现右键菜单有两种方法:

1、使用 @electron/remote 模块实现

2、使用主进程和渲染进程通信实现

1、使用 @electron/remote 模块实现

在 index.html 中引入下面文件

javascript 复制代码
const remote= require('@electron/remote')
const Menu = remote.Menu

let menuContextTemplate = [
  {
    label: "复制",
    role: "copy",
    click:()=>{
      console.log("copy")
    }
  },
  {
    label:'黏贴',
    role: "paste"
  }
]
let menuBuilder2 = Menu.buildFromTemplate(menuContextTemplate)
Menu.setApplicationMenu(menuBuilder2)


window.onload = ()=>{
  window.addEventListener("contextmenu", (e)=>{
    console.log("鼠标点击了右键")
    e.preventDefault()
    menuBuilder2.popup({window: remote.getCurrentWindow() })
  },false)
}

三、 Electron 主进程和渲染进程通信

有时候我们想在渲染进程中通过一个事件去执行主进程里面的方法。或者在渲染进程中通知主进程处理事件,主进程处理完成后广播一个事件让渲染进程去处理一些事情。这个时候就用到了主进程和渲染进程之间的相互通信。
Electron 主进程和渲染进程的通信主要用到两个模块: ipcMain 和 ipcRenderer

ipcMain : 当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息,当然也有可能从主进程向渲染进程发送消息。
ipcRenderer: 使用它提供的一些方法从渲染进程(web 页面)发送同步或者异步的消息到主进程。也可以接收主进程回复的消息。

场景1:渲染进程给主进程发送异步消息

javascript 复制代码
// 主进程
const {ipcMain} = require("electron")
ipcMain.on("msg", (event, data)=>{
  // 接收事件对象以及 传递过来的参数
  console.log(event, data)
})

// 渲染进程
const {ipcRenderer}  = require("electron")


window.onload = ()=>{
  let sendMsgDom = document.getElementById("sendMsg")
  sendMsgDom.onclick = ()=>{
    // 给主进程发送消息, 执行主进程中的方法
    ipcRenderer.send("msg", {name: "小星星"})
  }
}

实现效果:

场景2:渲染进程给主进程发送异步消息,主进程接收到异步消息以后通知渲染进程

javascript 复制代码
// 主进程
const {ipcMain} = require("electron")
ipcMain.on("sendMsg", (event, data)=>{
  // 接收事件对象以及 传递过来的参数
  console.log(event, data)
})
ipcMain.on("sendMsgReply", (event, data)=>{
  // 接收事件对象以及 传递过来的参数
  console.log(event, data)
  //给渲染进程回复消息
  event.sender.send('replyRenderer',"accept msg")
})
javascript 复制代码
// 渲染进程
const {ipcRenderer}  = require("electron")


window.onload = ()=>{
  let sendMsgDom = document.getElementById("sendMsg")
  sendMsgDom.onclick = ()=>{
    // 给主进程发送消息, 执行主进程中的方法
    ipcRenderer.send("sendMsg", {name: "小星星"})
  }
  let sendMsgReplyDom = document.getElementById("sendMsgReply")
  sendMsgReplyDom.onclick = ()=>{
    // 给主进程发送消息, 执行主进程中的方法
    ipcRenderer.send("sendMsgReply", 'this is ipcRenderer msg,need reply me')
  }
  // 监听主进程的广播
  ipcRenderer.on("replyRenderer", (e, data)=>{
    console.log(data)
  })
}

场景3:渲染进程给主进程发送同步消息

javascript 复制代码
// 主进程
const {ipcMain} = require("electron")
ipcMain.on("sendSyncMsg", (event, data)=>{
  // 接收同步消息
  console.log(event, data)
  event.returnValue = "hello, I am ipcMain"
})
javascript 复制代码
// 渲染进程
const {ipcRenderer}  = require("electron")
window.onload = ()=>{
  let sendMsgSyncDom = document.getElementById("sendMsgSync")
  sendMsgSyncDom.onclick = ()=>{
    // 同步发送消息
   let replyInfo = ipcRenderer.sendSync("sendSyncMsg", "I am ipcRenderer")
   console.log("reply:", replyInfo)
  }
}

场景4: 主进程通知渲染进程执行操作

javascript 复制代码
// 主进程
 BrowserWindow.getFocusedWindow().webContents.send("reply", "BrowserWindow reply")
javascript 复制代码
// 渲染进程
const {ipcRenderer}  = require("electron")
// 监听主进程主动发送过来的消息
  ipcRenderer.on("reply", (event, data)=>{
    console.log(event, data)
  })

渲染进程中获取当前窗口的方法 :

javascript 复制代码
remote.getCurrentWindow()

主进程中获取当前窗口的方法:

javascript 复制代码
BrowserWindow.getFocusedWindow()
相关推荐
m0_7482552611 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
长风清留扬31 分钟前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.1 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood2 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架