其他常用api
省略的其他代码在上一篇博客里
1.ipcMain和ipcRenderer进程间通讯属性
官方文档中两个模块进行通信的例子:
// In main process.
const {ipcMain} = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.sender.send('asynchronous-reply', 'pong') // 异步返回通信的方式
})
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.returnValue = 'pong' // 同步返回通信的方式
})
// In renderer process.
const {ipcRenderer} = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')
渲染进程可以通过 ipcRenderer 模块的 send 方法向主进程发送消息。在主进程中,通过 ipcMain 模块设置监听 asynchronous-message 和 synchronous-message 两个事件,当渲染进程发送时就可以针对不同的事件进行处理。
主进程监听事件的回调函数中,会传递 event 对象及 arg 对象。arg 对象中保存渲染进程传递过来的参数。通过 event.sender 对象,主进程可以向渲染进程发送消息。如果主进程执行的是同步方法,还可以通过设置 event.returnValue 来返回信息。
webContents主进程主动向渲染进程发送消息
在主进程中,我们会创建一个 BrowserWindow 对象,这个对象有 webContents 属性。webContets 提供了 send 方法来实现向渲染进程发送消息。当然 webContents 对象远不止这两个通信方法,具体可以看 webContents
下面是官方文档提供的使用 webContents 实现通信的例子:
// In the main process.
const {app, BrowserWindow} = require('electron')
let win = null
app.on('ready', () => {
win = new BrowserWindow({width: 800, height: 600})
win.loadURL(`file://${__dirname}/index.html`)
win.webContents.on('did-finish-load', () => {
win.webContents.send('ping', 'whoooooooh!')
})
})
<!-- index.html -->
<html>
<body>
<script>
require('electron').ipcRenderer.on('ping', (event, message) => {
console.log(message) // Prints 'whoooooooh!'
})
</script>
</body>
</html>
注意,webContents.on 监听的是已经定义好的事件,如上面的 did-finish-load。要监听自定义的事件还是通过 ipcMain 和 ipcRenderer。
渲染进程数据共享
更多情况下,我们使用HTML5 API实现,如localStorage、sessionStorage等,也可以使用electron的IPC机制实现
// 主进程
global.sharedObject = {
someProperty: 'default value'
}
// 渲染进程
console.log(require('electron').remote.getGlobal('sharedObject').someProperty) // new value
可以发现使用remote模块是最简单的,渲染进程代码中还可以直接使用electron模块
系统托盘
const { Menu, Tray } = require('electron')
/* 省略其他代码 */
let tray;
app.on('ready', () => {
tray = new Tray(__dirname + '/img.png');//系统托盘图标
const contextMenu = Menu.buildFromTemplate([ // 菜单项
{label: '显示', type: 'radio', click: () => {mainWindow.show()}},
{label: '隐藏', type: 'radio', click: () => {mainWindow.hide()}},
])
// tray.on('click', () => { // 鼠标点击事件最好和菜单只设置一种
// mainWindow.isVisible() ? mainWindow.hide() : win.show()
// })
tray.setToolTip('This is my application.') // 鼠标放上时候的提示
tray.setContextMenu(contextMenu) // 应用菜单项
})
notification通知
index.html
<!DOCTYPE html>
<html lang="en">
...
<body>
<button id="basic-noti">notification</button>
<script src="./js/index12.js"></script>
</body>
</html>
index12.js
const {app, mainWindow} = require("electron").remote;
const notification = {
title: '基本通知',
title2:'开始程序通知',
body: '短消息部分',
icon: '../img.png', // 用于在该通知上显示的图标
silent: true, // 在显示通知时是否发出系统提示音
}
const notificationButton = document.getElementById('basic-noti')
const myNotification = () => {
new window.Notification(notification.title2, notification)
}
notificationButton.addEventListener('click', function () {
const myNotification = new window.Notification(notification.title, notification)
myNotification.onclick = () => {
console.log('Notification clicked')
}
})
app.whenReady().then(mainWindow).then(myNotification) // 动程序时
进度条
mainWindow.setProgressBar(0.3)
mainWindow.setProgressBar(-1) // 删除进度条
macOs Dock图标
Electron有API来配置macOS Dock中的应用程序图标和菜单。
// main.js
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click() {
console.log('New Window')
}
}, {
label: 'New Window with Settings',
submenu: [
{label: 'Basic'},
{label: 'Pro'}
]
},
{label: 'New Command...'}
])
app.whenReady().then(() => {
app.dock.setMenu(dockMenu) //菜单栏
app.dock.setIcon('./img.png') //图标
})
原生文件拖放
// index13.js
const { ipcRenderer } = require('electron')
document.getElementById('drag').ondragstart =(event)=>{
event.preventDefault()
ipcRenderer.send('ondragstart','文件的绝对路径')
}
渲染进程处理 ondragstart 事件并将信息转发到主进程。
在主进程中,将收到的事件扩展到正在拖动的文件和图标
// mian.js
ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: filePath,
icon: '/path/to/icon.png' //拖拽时的图标
})
})
离屏渲染
我在实验过程中发现这个功能就是在不打开应用的情况下处理应用,然后屏幕展示成这样。离线模式不展示内容,但是我们可以通过截屏处理
mian.js
const fs = require("fs");const path = require("path");
app.disableHardwareAcceleration(); //禁用当前应用程序的硬件加速。这个方法只能在应用程序准备就绪(ready)之前调用。// -------------app.whenReady().then(createWindow);function createWindow() {
win = new BrowserWindow({ webPreferences: { offscreen: true } })
win.loadURL('https://www.baidu.com')
win.webContents.on("paint", (event, dirty, image) => { //截屏console.log("paint");
fs.writeFileSync(path.resolve(__dirname, "ex.png"), image.toPNG()); //截屏生成一张图片
});
win.webContents.setFrameRate(60); //设置渲染的帧率}
暗黑模式
在 macOS 10.14 Mojave中, Apple 为所有 macOS 电脑引入了一个全新的 系统级黑暗模式。
mian.js
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
}
index13.js
<p>Current theme source: <strong id="theme-source">System</strong></p>
<button id="toggle-dark-mode">Toggle Dark Mode</button>
<button id="reset-to-system">Reset to System Theme</button>
模板和命令行界面
命令行工具是在整个开发和分发过程中从另一方面给你提供帮助。 他们更有用,但同时也对代码结构和构建项目有着硬性的要求。
electron-forge
Electron Forge 是一个用来构建现代化Electron应用的完善的工具。Electron Forge将多个现有的( 且有稳定维护的 )Electron构建工具整合为一个简单易用的工具包,所有人都可以用它来快速地搭建Electron开发环境比如(electron-packager)。
Forge的更多信息,请查阅electronforge.io。
electron-builder
Electron Builder 是一个完备的Electron应用打包和分发解决方案,它致力于软件开发的集成体验。 electron-builder 出于简化的目的添加了一个依赖项,可以在内部管理所有更多的要求。
Electron Builder的更多信息,请查阅代码仓库。