永久域名最新網(wǎng)站搭建一個(gè)網(wǎng)站平臺(tái)需要多少錢
????完成初始應(yīng)用的創(chuàng)建Electron桌面應(yīng)用開發(fā):創(chuàng)建應(yīng)用,隨后我們就可以自定義軟件的菜單了。菜單可以幫助用戶快速找到和執(zhí)行命令,而不需要記住復(fù)雜的快捷鍵,通過將相關(guān)功能組織在一起,用戶可以更容易地發(fā)現(xiàn)和使用應(yīng)用程序的各種特性。同時(shí)菜單允許開發(fā)者提供更多的功能選項(xiàng)而不必?fù)?dān)心界面會(huì)因此變得擁擠或難以導(dǎo)航,比如下拉菜單
、彈出菜單
等可以在有限的空間內(nèi)提供大量的選項(xiàng)。
Electron
的原始菜單為以下頁(yè)面:
取消頂部菜單顯示
這里可以使用兩種常用的方法,第一種是在窗口創(chuàng)建函數(shù)中設(shè)置frame: false
:
const {app, BrowserWindow, Menu} = require('electron');let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,frame: false,webPreferences: {nodeIntegration: true},});win.loadFile('index.html');win.on('closed', () => {win = null;});
}app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});
這樣大小化和關(guān)閉按鈕、標(biāo)題也全部消失了,所以只適合個(gè)別情況使用。
第二種是在創(chuàng)建窗口函數(shù)中加入Menu.setApplicationMenu(null);
設(shè)置,這樣可以保留標(biāo)題等內(nèi)容:
const {app, BrowserWindow, Menu} = require('electron');let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true},});win.loadFile('index.html');Menu.setApplicationMenu(null);win.on('closed', () => {win = null;});
}app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});
自定義子菜單
????這里我們可以在主文件main.js
中直接添加自定義菜單的代碼,也可以新建一個(gè)menu.js
文件,隨后在main.js
中進(jìn)行引用(個(gè)人推薦做法)
在Electron中定義菜單需要先引入Menu
:
const {Menu} = require('electron')
定義格式如下:
const template = [{label: '菜單1',submenu: [{label: '子菜單1'},{label: '子菜單2',}]},{label: '菜單2',submenu: [{label: '子菜單1'},{label: '子菜單2',submenu: [{label: '孫子菜單1'},{label: '孫子菜單2'}]}]}]
可以使用click
來監(jiān)聽事件,例如:
{label: '歐耶',accelerator: 'CmdOrCtrl+O',click: () => {console.log('菜單被點(diǎn)擊了');}},
在main.js
中直接添加菜單代碼的格式如下:
const { app, BrowserWindow, Menu } = require('electron');let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true},});win.loadFile('index.html');win.on('closed', () => {win = null;});
}const template = [{label: '菜單1',submenu: [{label: '子菜單1'},{label: '子菜單2',}]},{label: '菜單2',submenu: [{label: '子菜單1'},{label: '子菜單2',submenu: [{label: '孫菜單1'},{label: '孫菜單2'}]}]},{label: '幫助',role: 'help',click() { require('electron').shell.openExternal('https://example.com/help') }}
];const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {if (win === null) {createWindow();}
});
這里我們還是推薦使用將創(chuàng)建菜單的代碼轉(zhuǎn)移到其他文件中,比如新建一個(gè)menu.js
,這樣可以更加方便的進(jìn)行代碼編寫和問題排查:
main.js
:
const {app, BrowserWindow, Menu} = require('electron');
// 引入menu.js文件
const menuTemplate = require('./menu.js'); let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true},});win.loadFile('index.html');win.on('closed', () => {win = null;});// 創(chuàng)建窗口const menu = Menu.buildFromTemplate(menuTemplate(win));Menu.setApplicationMenu(menu);
}app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});
menu.js
:
const {Menu} = require('electron')module.exports = function (win) {const template = [{label: '菜單1',submenu: [{label: '子菜單1'},{label: '子菜單2',}]},{label: '菜單2',submenu: [{label: '子菜單1'},{label: '子菜單2',submenu: [{label: '孫菜單1'},{label: '孫菜單2'}]}]},{label: '幫助',role: 'help',click() { require('electron').shell.openExternal('https://example.com/help') }}]return template;
}
兩種方法的最終效果如下:
上下文菜單
上下文菜單通常在用戶右鍵點(diǎn)擊某個(gè)元素時(shí)顯示,通常通過監(jiān)聽事件來創(chuàng)建和顯示上下文菜單。
在主文件中需要導(dǎo)入ipcMain
模塊,main.js
:
const { app, BrowserWindow, Menu, ipcMain } = require('electron');
const menuTemplate = require('./menu.js');let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true,contextIsolation: false,preload: __dirname + './preload.js'},});win.loadFile('index.html');const menu = Menu.buildFromTemplate(menuTemplate(win));Menu.setApplicationMenu(menu);win.on('closed', () => {win = null;});
}app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {if (win === null) {createWindow();}
});
renderer.js
,DOM內(nèi)容加載完成后執(zhí)行的邏輯:
document.addEventListener('DOMContentLoaded', () => {
});
使用preload腳本處理上下文菜單的preload.js
, 用于安全地暴露API給渲染進(jìn)程:
const { contextBridge, ipcRenderer } = require('electron');contextBridge.exposeInMainWorld('electronAPI', {send: (channel, data) => {// 向主進(jìn)程發(fā)送消息ipcRenderer.send(channel, data);},receive: (channel, func) => {// 接收來自主進(jìn)程的消息ipcRenderer.on(channel, (event, ...args) => func(...args)); }
});
menu.js:
const {Menu} = require('electron')module.exports = function (win) {const template = [{label: '菜單1',submenu: [{label: '子菜單1'},{label: '子菜單2',}]},{label: '菜單2',submenu: [{label: '子菜單1'},{label: '子菜單2',submenu: [{label: '孫菜單1'},{label: '孫菜單2'}]}]},{label: '幫助',role: 'help',click() { require('electron').shell.openExternal('https://example.com/help') }}]return template;
}
index.html
:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="./style.css"><title>GGBond勇猛無敵</title>
</head>
<body><h1>Hello GGBond</h1><script src="./renderer.js"></script>
</body>
</html>
彈出式菜單
彈出式菜單可以通過編程方式手動(dòng)顯示,不需要特定的觸發(fā)事件。
main.js
:
const { app, BrowserWindow, Menu } = require('electron');
const menuTemplate = require('./menu.js'); // 引入自定義菜單模板let win = null;function createWindow() {win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true,contextIsolation: false, // 在使用nodeIntegration時(shí)需要禁用contextIsolationpreload: __dirname + '/preload.js' // 使用preload腳本處理上下文菜單},});win.loadFile('index.html');win.on('closed', () => {win = null;});const menu = Menu.buildFromTemplate(menuTemplate(win));Menu.setApplicationMenu(menu); // 設(shè)置為應(yīng)用菜單
}app.on('ready', createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {if (win === null) {createWindow();}
});
使用preload腳本處理上下文菜單的preload.js
,使用contextBridge
來安全地暴露API
給渲染進(jìn)程,允許渲染進(jìn)程調(diào)用showPopupMenu
方法。:
const { contextBridge, ipcRenderer } = require('electron');contextBridge.exposeInMainWorld('electronAPI', {showPopupMenu: (x, y) => {ipcRenderer.invoke('show-popup-menu', x, y);}
});
renderer.js
:
document.addEventListener('DOMContentLoaded', () => {document.body.addEventListener('click', (event) => {window.electronAPI.showPopupMenu(event.x, event.y);});
});
menu.js:
const {Menu} = require('electron')module.exports = function (win) {const template = [{label: '菜單1',submenu: [{label: '子菜單1'},{label: '子菜單2',}]},{label: '菜單2',submenu: [{label: '子菜單1'},{label: '子菜單2',submenu: [{label: '孫菜單1'},{label: '孫菜單2'}]}]},{label: '幫助',role: 'help',click() { require('electron').shell.openExternal('https://example.com/help') }}]return template;
}
index.html
:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="./style.css"><title>GGBond勇猛無敵</title>
</head>
<body><h1>Hello GGBond</h1><script src="./src/renderer.js"></script>
</body>
</html>