Electron实战之菜单与托盘
菜单、托盘是桌面端应用必备的功能之一,我们通常会在菜单上配置应用常用的:偏好设置、显示隐藏、打开文件等功能,在托盘内设置:退出、重启、帮助等辅助性功能,帮助用户方便快捷地控制应用的一些系统功能。系统托盘实际上也是一个菜单,通过点击鼠标触发。
一、应用菜单(Menu)
Electron 里的菜单大体上分为三类:应用菜单、上下文菜单和 Dock 菜单(仅针对 OSX 系统)。这里以 VSCode 为例,来分别介绍这几种菜单的含义。打开 VSCode 编辑器,可以通过下图,很清晰地发现 3 个菜单所处的位置。

图片

图片
1.1 应用内菜单
原生应用菜单可以理解为应用窗口菜单,在 MacOS 上,选中应用后,应用内菜单出现在桌面的左上方。在 Windows 和 Linux 上,Menu 将会被设置成窗口顶部菜单。在 Electron 中,通常会使用 Menu.setApplicationMenu(menu) 函数来设置应用内菜单。
import { Menu } from 'electron'function createMenu () {const template = [{label: '菜单一',submenu: [{label: '功能一'},{label: '功能二'}]},{label: '菜单二',submenu: [{label: '功能一'},{label: '功能二'}]}];const menu = Menu.buildFromTemplate(template);Menu.setApplicationMenu(menu);
}
通过以上代码设置完成一个应用菜单后,在 macOS 下的效果如下。

图片
可以看到第一个菜单的标题是 Electron 而不是我们设置的标题 菜单一。这是因为:在 macOS 中应用程序菜单的第一个项目的标签总是你的应用程序的名字,无论你设置什么标签。如果你想展示成自己的标题,Electron 官方给了一种修改 Info.plist 的方法:About Information Property List Files。除此之外,你也可以重新修改一下 template 的格式:
if (process.platform === 'darwin') {template.unshift({label: app.getName(),submenu: [{label: 'Quit',click() {app.quit();}}]});
}
这样,三个菜单就显示出来了,如下图所示。

图片
上述代码中,对于 template 菜单项字段内有很多配置项,具体的字段也可以直接阅读官方文档,针对每个字段都有详细的解释。
1.2 上下文菜单(context menu)
上下文菜单(context menu)就是我们通常说的右键菜单,需要注意的是:上下文菜单,需要在渲染进程中进行实现,可以通过 IPC 发送所需的信息到主进程,并让主进程代替渲染进程显示菜单,示例代码如下。
// 主进程 main/index.js
ipcMain.on('show-context-menu', (event) => {const template = [{label: '菜单一',click: () => {// 发送点击菜单一事件到渲染进程event.sender.send('context-menu-command', 'menu-item-1')}},{ type: 'separator' },{label: '菜单二',type: 'checkbox',checked: true}]const menu = Menu.buildFromTemplate(template)menu.popup({window: BrowserWindow.fromWebContents(event.sender)})
})
// 渲染进程 renderer/main.js
window.addEventListener("contextmenu", (e) => {e.preventDefault();electron.ipcRenderer.send("show-context-menu");
});
electron.ipcRenderer.on("context-menu-command", (e, command) => {// todo
});
最终的运行效果如下图。

图片
1.3 Dock 菜单(仅 MacOS 可用)
Dock 的菜单实现也是在主进程中,可以通过 app.dock.setMenu 这个 API 来直接创建。
// main.js
const createDockMenu = () => {const dockTempalte = [{label: '菜单一',click () {console.log('New Window');}}, {label: '菜单二',submenu: [{ label: 'Basic' },{ label: 'Pro' }]},{label: '其他...'}];const dockMenu = Menu.buildFromTemplate(dockTempalte);app.dock.setMenu(dockMenu);
}
运行效果如下图。

图片
二、应用托盘(Tray)
实现应用托盘主要依托于 Electron 的 Tray 模块,在 MacOS 和 Ubuntu,托盘将位于屏幕右上角上,靠近你的电池和 wifi 图标。在 Windows 上,托盘通常位于右下角。

图片
通过以上图片可以清晰地看到创建一个托盘需要准备一个图标用于显示,以及一个菜单项用于呈现所需的功能菜单。我们来看一下 Windows 下一个简单的应用托盘的实现方式:
// 主进程
import {app, Menu, Tray} from 'electron';let tray = new Tray('public/icon.ico');
const contextMenu = Menu.buildFromTemplate([{label: '退出',click: function(){app.quit();}}
]);
tray.setToolTip('应用标题');
tray.setContextMenu(contextMenu);
在 Rubick 中,应用托盘实现的源码链接:GitHub - rubickCenter/rubick: 🔧 Electron based open source toolbox, free integration of rich plug-ins. 基于 electron 的开源工具箱,自由集成丰富插件。
相关文章:
Electron实战之菜单与托盘
菜单、托盘是桌面端应用必备的功能之一,我们通常会在菜单上配置应用常用的:偏好设置、显示隐藏、打开文件等功能,在托盘内设置:退出、重启、帮助等辅助性功能,帮助用户方便快捷地控制应用的一些系统功能。系统托盘实际…...
【Java EE初阶十六】网络原理(一)
在网络原理中主要学习TCP/IP四层模型中的重点网络协议 1. 应用层 1.1 应用程序与协议 应用层是和程序员接触最密切的; 应用程序:在应用层这里,很多时候都是程序员自定义应用层协议(步骤:1、根据需求,明确…...
51_蓝桥杯_led流水灯
一 原理图分析 二 三八译码器工作原理 三八译码器:3个输入控制8路互斥的低电平有效输出。 C B A 输出 0 0 0 Y0 0 0 1 Y1 0 1 0 Y2 0 1 1 Y3 1 0 0 Y4 1 0 1 Y5 1 1 0 Y6 1 1 1 Y7 三 锁存器工作原理 锁存器:当使…...
⭐北邮复试刷题589. N 叉树的前序遍历__DFS (力扣每日一题)
589. N 叉树的前序遍历 给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。 示例 1: 输入:root [1,null,…...
php伪协议之phar
一.phar协议 用于将多个 PHP 文件、类、库、资源(如图像、样式表)等打包成一个单独的文件。这个归档文件可以像其他 PHP 文件一样被包含(include)或执行。PHAR 归档提供了一种方便的方式来分发和安装 PHP 应用程序和库,…...
蓝桥杯电子类单片机提升三——NE555
目录 单片机资源数据包_2023 一、NE555和定时器工作模式 1.NE555的介绍 2.定时器的计数模式 二、NE555频率读取代码的实现 1.定时器0初始化 2.通过读取TH0和TL0来读取频率 3.通过中断读取频率 三、完整代码演示 通过读取TH0和TL0来读取频率 main.c 通过中断读取频…...
发掘GPT-4商业创新的潜力
GPT-4在商业创新方面的应用潜力巨大,它能够基于庞大的训练数据集和强大的语言生成能力,协助企业或个人用户在多个商业场景中推动创新: 市场分析与战略规划:GPT-4可以对历史数据、行业趋势、竞争对手信息进行深度分析,并…...
LeetCode42.接雨水(单调栈)
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 : 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,…...
黄东旭:“向量数据库”还是“向量搜索插件 + SQL 数据库”?丨我对 2024 年数据库发展趋势的思考
本文由 PingCAP 黄东旭撰写,讨论了数据库技术在 2023 年的快速变革,并对 2024 年的数据库发展趋势进行了预测。文章重点关注了 GenAI 时代对数据库的影响,提出了在数据库选择上的两种路径:“向量数据库”和“向量搜索插件 SQL 数…...
Spark编程实验五:Spark Structured Streaming编程
目录 一、目的与要求 二、实验内容 三、实验步骤 1、Syslog介绍 2、通过Socket传送Syslog到Spark 3、Syslog日志拆分为DateFrame 4、对Syslog进行查询 四、结果分析与实验体会 一、目的与要求 1、通过实验掌握Structured Streaming的基本编程方法; 2、掌握…...
【已解决】引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
这种问题产生一般都会手足无措,包括笔者,但是不要慌,这种问题一般都是内存泄漏引起的。例如读者要访问一个已经被析构或者释放的变量,当然访问不了,导致存在问题。这时候读者应该从哪里产生内存泄漏这方面进行考虑&…...
Python Flask高级编程之RESTFul API前后端分离(学习笔记)
Flask-RESTful是一个强大的Python库,用于构建RESTful APIs。它建立在Flask框架之上,提供了一套简单易用的工具,可以帮助你快速地创建API接口。Flask-RESTful遵循REST原则,支持常见的HTTP请求方法,如GET、POST、PUT和DE…...
Windows如何打开投影到此电脑
1.首先点开设置 找到系统 点击投影到此电脑,如果这3行都显示灰色说明没有开启。 2.如何开启投影到此电脑 ①回到设置,点击应用 ②点击可选应用 ③ 安装无线显示器 投影设置可以和我一样...
【BUG】段错误
1. 问题 8核工程,核4在运行了20分钟以上,发生了段错误。 [C66xx_4] A00x53 A10x53 A20x4 A30x167e A40x1600 A50x850e2e A60x845097 A70xbad9f5e0 A80x0 A90x33 A100x53535353 A110x0 A120x0 A130x0 A140x0 A150x0 A160x36312e35 A170x20 A180x844df0 …...
深入理解指针(3)
目录 一、 字符指针变量二、 数组指针变量1.数组指针变量是什么?2.数组指针变量怎么初始化? 三、 二维数组传参的本质四、 函数指针变量1. 函数指针变量的创建2.函数指针变量的使用3.typedef关键字 五、 函数指针数组六、 转移表 一、 字符指针变量 在指针的类型中…...
ssm在线学习平台-计算机毕业设计源码09650
目 录 摘要 1 绪论 1.1 选题背景及意义 1.2国内外现状分析 1.3论文结构与章节安排 2 在线学习平台系统分析 2.1 可行性分析 2.2 系统业务流程分析 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 3 在线学习平台总体设计 …...
【Linux 内核源码分析】内存映射(mmap)机制原理
内存映射(mmap)是 Linux 内核的一个重要机制,它为程序提供了一种将文件内容直接映射到进程虚拟地址空间的方式。同时内存映射也是虚拟内存管理和文件 IO 的重要组成部分。 在 Linux 中,虚拟内存管理是基于内存映射来实现的。在调用 mmap 函数时…...
贪心算法之合并区间
“任世界多宽广,停泊在这港口~” 区间问题,涉及到最多的就是 取交集 和 并集的概念。我们使用C排序算法后,其默认规则就是按照 “左排序”进行的。因而,我们实质上注意的是每一个区间的 右端点,根据题目要求ÿ…...
Eclipse - Colors and Fonts
Eclipse - Colors and Fonts References 编码最好使用等宽字体,Ubuntu 下自带的 Ubuntu Mono 可以使用。更换字体时看到名字里面带有 Mono 的基本都是等宽字体。 Window -> Preferences -> General -> Appearance -> Colors and Fonts -> C/C ->…...
java 数据结构LinkedList类
目录 什么是LinkedList 链表的概念及结构 链表的结构 无头单向非循环链表 addFirst方法(头插法) addLast方法(尾插法) addIndex方法 contains方法 removeAllKey方法 size和clear方法 链表oj题 无头双向非循环链表 ad…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
