electronjs入门-编辑器应用程序
我们将在Electron中创建一个新项目,如我们在第1章中所示,名为“编辑器”,我们将在下一章中使用它来创建编辑器;在index.js中,这是我们的主要过程;请记住为Electron软件包放置必要的依赖项:
npm init -y
cnpm install --save-dev electron
package.json
"start":"DEBUG=true electron ."
新建index.js
const { app, BrowserWindow } = require("electron");
function createWindow() {let win = new BrowserWindow({width: 800,height: 600,});win.loadFile("index.html");
}
app.whenReady().then(createWindow);
新建index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initialscale=1.0"><title>My Editor</title>
</head><body><textarea id="MyID"></textarea>
</body></html>
npm start
启动项目之后我们将看到如下的情形
配置文本编辑器让我们配置以下文本编辑器:
https://www.npmjs.com/package/simplemde
我们在项目中安装它时使用:
npm i simplemde -registry=https://registry.npm.taobao.org
# 或者yarn安装
yarn add simplemde
修改index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initialscale=1.0"><title>My Editor</title><link rel="stylesheet" href="./node_modules/simplemde/dist/simplemde.min.css"><script src="./node_modules/simplemde/dist/simplemde.min.js"></script>
</head><body><textarea id="MyID"></textarea><script>var simplemde = new SimpleMDE({element:document.getElementById("MyID")});</script>
</body></html>
启动项目
npm run start
在上面的代码中,我们加载编辑器插件的JS和CSS,并使用以下方法进行配置:
var simplemde = new SimpleMDE({element:document.getElementById("MyID")});
其中,我们将先前创建的TEXTAREA的选择器作为引用传递。为了使编辑器填充屏幕的宽度,我们将使用CSS:
html,body {display: flex;flex-direction: column;height: 100%;}.CodeMirror {flex: 1}
编辑器应用程序和进程之间的通信
双方事件的使用对于Electron中的任何应用程序都是至关重要的,也是Electron应用程序的核心,对于我们使用编辑器的notes应用程序,能够为以下功能执行这项工作是至关重要的:
- 打开文件
- 保存文件
- 对文本执行一些操作,例如下划线、加粗等
这一点很重要,因为这取决于我们在哪里实施这些选项,我们可能必须沟通进程,例如,如果我们定义了一个带有粗体选项的菜单,该菜单是从渲染过程,因为它是由具有Electron对操作系统的相应调用;让我们请记住,我们与操作人员进行的所有沟通系统是通过渲染过程完成的,但我们想要的操作执行(将粗体应用于文本)将在编辑器中完成,其是安装在网页或呈现过程上的插件,因此,当单击菜单中的此选项时,我们必须发送从主进程到呈现进程的消息。
菜单结构
在本节中,我们将为应用程序创建选项菜单,该菜单由一组选项组成,既可以编辑内容,也可以执行文件操作,特别是打开和保存文件。
创建和打开文件
对于使用文件的部分,即保存或打开文件,我们将在项目中的新文件中执行此操作:editor-options.js
创建文件
为了保存文件,我们将创建一个新函数,它将接收窗口和我们要插入的数据作为参数,特别是与用户在编辑器中编写的HTML内容相对应的数据:
module.exports.save_file = function(win,data){}
要使用弹窗创建文件,请执行以下操作:
保存文件需要哪个模块,我们使用该模块:
const { dialog } = require('electron')
其模块包含打开文件保存对话框的功能:
const path = dialog.showSaveDialogSync(win,option)
其中:
win
,对应于将打开对话框的窗口。option
,选项对应于我们要处理的文件的标题和类型,在本例中为txt文件
const option = {title: "Guardar archivo",filters: [{name: "archivo",extensions: ["txt"],},],
};
“showSaveDialogSync()”函数返回用户选择的文件;如果对话框被取消,则返回undefined。有了文件路径,我们可以用它来写,在Node中处理文件,我们有了模块:
const fs = require('fs')
内容如下:
fs.writeFileSync(path,data)
最后,函数变为:
const { app, dialog } = require("electron");
const fs = require("fs");
const path = require("path");
module.exports.save_file = function (win, data) {const option = {title: "Guardar archivo",filters: [{name: "archivo",extensions: ["txt"],},],};const path = dialog.showSaveDialogSync(win, option);// console.log(path)fs.writeFileSync(path, data);/* dialog.showSaveDialog(win,option).then(result => {console.log(result.canceled)console.log(result.filePaths)})*/
};
读取文件
要读取上述函数生成的文件,我们将使用一个新函数:
editor-options.js
module.exports.open_file = function(win){}
要使用alter窗口打开文件:
打开我们使用与上一个功能相同的模块的项目文件是必要的:
const { dialog } = require('electron')
我们有:
paths = dialog.showOpenDialogSync(win,option)
返回用户选择的文件的路径; 如果对话框被取消,则返回undefined。
有了这个路径,我们就可以通过fs模块读取文件的内容,并将数据返回给渲染进程或者网页; 最后的实现如下:
module.exports.open_file = function (win) {const option = {title: "Abrir archivo",filters: [{name: "archivo",extensions: ["txt"],},],};paths = dialog.showOpenDialogSync(win, option);if (paths && paths.length > 0) {const content = fs.readFileSync(paths[0]).toString();win.webContents.send("file-open", content);var filename = path.basename(paths[0]);win.webContents.send("title-change", app.name + " " + filename);}
};
菜单选项
在本节中,我们将为编辑器应用程序创建一个菜单,如第二章所述,我们将使用自定义选项,例如预定义的角色和分隔符,以及快捷键或键盘快捷键; 为了保持应用程序的组织性和模块化,我们将在单独的文件中定义菜单。
由于菜单是在渲染进程中定义的,并且将具有能够操作在网页中定义的 simplemde 插件中定义的文本的选项,因此我们必须在进程之间发送消息才能实现此操作; 例如,如果从菜单中,我们有一个将文本设置为粗体的选项,那么我们必须从菜单(主进程)向网页发送一条消息,并从这里实现将所选文本设置为粗体的功能 ; 考虑到这一点,我们有以下结构:
menu.js
const {app,ipcMain,Menu,shell,BrowserWindow,globalShortcut,
} = require("electron");const { open_file, save_file } = require("./editor-options");const template = [{label: "About us",submenu: [{label: "About us",click() {shell.openExternal("https://www.electronjs.org");},},],},{label: "File",submenu: [{label: "Save",accelerator: "CommandOrControl+S",click() {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editorchannel", "file-save");},},{label: "Open",accelerator: "CommandOrControl+O",click() {const win = BrowserWindow.getFocusedWindow();open_file(win);},},],},{label: "Style and format",submenu: [{label: "Bold",click() {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editorchannel", "style-bold");console.log("Negritas");},},{label: "Italic",click() {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editor-channel", "style-italic");},},{type: "separator",},{label: "H1",click() {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editor-channel", "style-h1");},},{label: "H2",click() {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editor-channel", "style-h2");},},],},
];const menu = Menu.buildFromTemplate(template);module.exports = menu;
在上面的脚本中,我们还定义了其他选项,例如打开外部链接:
shell.openExternal
通过定义到菜单项的加速器选项,我们可以指示激活这些选项的快捷键。
如果你想为每个操作系统设置自定义选项,你所要做的就是询问所使用的平台; 例如,如果我们想在使用 Windows 或 MacOS 时显示特定选项:
·menu.js·
if (process.platform == "win32" || process.platform == "darwin") {template.push({label: "Default",submenu: [{ role: "reload" },{ role: "forceReload" },{ role: "toggleDevTools" },{ role: "resetZoom" },{ role: "zoomIn" },{ role: "zoomOut" },{ type: "separator" },{ role: "togglefullscreen" },],});
}
我们还将为应用程序实现一系列键盘快捷键,专门用于打开文件或保存内容,为此,我们将分别使用 ctrl/command+S 和 ctrl/command+O 的组合:
menu.js
ipcMain.on("editor-channel", (event, arg) => {console.log("Mensaje recibido del canal 'editor-channel': " + arg);
});ipcMain.on("file-open", (event, arg) => {const win = BrowserWindow.getFocusedWindow();open_file(win);
});
ipcMain.on("file-save", (event, arg) => {const win = BrowserWindow.getFocusedWindow();save_file(win, arg);
});app.on("ready", () => {globalShortcut.register("CommandOrControl+S", () => {const win = BrowserWindow.getFocusedWindow();win.webContents.send("editor-channel", "file-save");});globalShortcut.register("CommandOrControl+O", () => {const win = BrowserWindow.getFocusedWindow();open_file(win);});
});
虽然,当在菜单中定义这些选项时:不需要通过 globalShortcut API 定义键盘快捷键,可以通过如下方式:
const template = [{label: 'About us',click() {shell.openExternal("https://www.electronjs.org")}},{ label: 'File',submenu: [{label: "Save",accelerator: 'CommandOrControl+S',***},{label: "Open",accelerator: 'CommandOrControl+O',***},]}
]
在 index.js 中,我们导入菜单,以便我们可以在应用程序中使用它:index.js
const menu = require('./menu')
//***
Menu.setApplicationMenu(menu)
最后,该菜单的所有处理主要基于发送消息,其中一些包括使用特定模块来执行其操作,例如打开或保存文件的对话框。
最后,在网页流程中,我们定义从menu.js调用的事件并执行相应的操作来编辑所选内容:
index.html
<script>const { ipcRenderer } = require('electron')ipcRenderer.on('message', (event, arg) => {alert("Mensaje recibido desde el proceso principal: " + arg);});ipcRenderer.send('editor-channel', 'Página cargada')ipcRenderer.on('file-open', (event, arg) => {console.log("Mensaje recibido desde el proceso principal: " + arg);simplemde.value(arg)});ipcRenderer.on('editorchannel', (event, arg) => {console.log("Mensaje recibido desde el proceso principal: " + arg);editorOptions(event, arg)});ipcRenderer.on('title-change', (event, arg) => {document.title = arg;});function editorOptions(event, arg) {console.log("editor")switch (arg) {case 'style-bold':simplemde.toggleBold()break;case 'style-italic':simplemde.toggleItalic()break;case 'style-h1':simplemde.toggleHeading1()break;case 'style-h2':simplemde.toggleHeading2()break;case 'file-save':console.log(simplemde.value())event.sender.send('file-save', simplemde.value())break;}}</script>
index.js完整代码如下
const { app, BrowserWindow, Menu } = require("electron");
const menu = require("./menu");function createWindow() {let win = new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true,contextIsolation: false,},});win.loadFile("index.html");
}
app.whenReady().then(createWindow);
Menu.setApplicationMenu(menu);
来自同一事件:
event.sender
我们可以将消息发送回发送事件的窗口。
simplemde 插件实现了一系列功能,允许您以编程方式编辑所选内容; 例如,toggleBold() 函数允许您将文本转换为粗体。
作为一个网页,我们可以使用 JavaScript 以及 HTML 和 CSS 的任何脚本,例如,我们可以实现其他附加选项,例如在客户端使用纯 JavaScript 的暗模式:
index.html
<script>var simplemde = new SimpleMDE({element: document.getElementById("MyID")});function darkMode() {document.querySelector(".CodeMirror").style.background = "black"}
</script>
按钮代码如下
index.html
<button onclick="darkMode()">Dark Mode</button>
对于打开文件的功能,由于它是一个必须由主进程处理的进程,我们发送一个事件,该函数用于上面显示的editorOptions()函数:
index.html
function openFile() {ipcRenderer.send('file-open', 'file-open')
}
我们还可以使用HTML API拖放来实现打开文件的功能:
index.html
document.ondrop = function (event) {event.preventDefault();if (event.dataTransfer.items) {item = event.dataTransfer.items[0];if (item.kind == "file" && item.type == "text/plain") {var reader = new FileReader()var file = item.getAsFile();reader.onload = e => {//console.log(e.target.result);simplemde.value(e.target.result);}reader.readAsText(file);}}
}
这些选项是多种多样的,但它们意味着主进程和渲染进程之间的通信,甚至可能有必要根据情况再次与渲染进程通信;例如,要打开一个文件,在该文件中,我们传递文件的内容:
editor-options.js
win.webContents.send('file-open',content)
在网页上,我们可以选择打开文件,稍后我们将看到:
index.html
function openFile() {ipcRenderer.send('file-open', 'file-open')
}
另一个例子是关于保存文件的选项;按下菜单中的选项(主进程)会通过Electron中的事件向渲染进程发送一条消息(如我们在第2章中看到的):
从渲染过程中,我们获得编辑器中生成的HTML,将带有HTML内容的消息发送回渲染过程,以便它从操作系统请求对话框保存带有所述HTML内容的文件:
最后,当使用以下内容运行应用程序时:
npm run start
源代码如下https://github.com/libredesarrollo/electron-editor
相关文章:

electronjs入门-编辑器应用程序
我们将在Electron中创建一个新项目,如我们在第1章中所示,名为“编辑器”,我们将在下一章中使用它来创建编辑器;在index.js中,这是我们的主要过程;请记住为Electron软件包放置必要的依赖项: npm…...

Xilinx Kintex7中端FPGA解码MIPI视频,基于MIPI CSI-2 RX Subsystem架构实现,提供工程源码和技术支持
目录 1、前言免责声明 2、我这里已有的 MIPI 编解码方案3、本 MIPI CSI2 模块性能及其优缺点4、详细设计方案设计原理框图OV5640及其配置权电阻硬件方案MIPI CSI-2 RX SubsystemSensor Demosaic图像格式转换Gammer LUT伽马校正VDMA图像缓存AXI4-Stream toVideo OutHDMI输出 5、…...
SIMCSE求相似度分数
import torch from transformers import AutoTokenizer, AutoModelForMaskedLM from sklearn.metrics.pairwise import cosine_similarity# simcse相似度分数 def simcse_similar(model, tokenizer, text_a, text_b):inputs_source tokenizer(text_a, return_tensors"pt&…...

java入门,从CK到一部分数据到mysql
一、需求 需要从生产环境ck数据库导数据到mysql,数据量大约100w条记录。 二、处理步骤 1、这里的关键词是生产库,第二就是100w条记录。所以处理数据的时候就要遵守一定的规范。首先将原数据库表进行备份,或者将需要导出的数据建一张新的表了…...

LeetCode(13)除自身以外数组的乘积【数组/字符串】【中等】
目录 1.题目2.答案3.提交结果截图 链接: 238. 除自身以外数组的乘积 1.题目 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素…...
WPF资源,静态资源,动态资源
WPF资源介绍 在WPF(Windows Presentation Foundation)中,资源是一种可以在多个地方重复使用的对象。资源可以是任何类型的对象,比如字符串、颜色、画刷、形状、动画、数据模板、样式等。通过将这些对象定义为资源,你可…...

绘图软件 OmniGraffle mac中文版特点说明
OmniGraffle mac是一款图形绘制和图表设计软件,主要面向 macOS 和 iOS 平台。它适用于用户创建流程图、组织结构图、原型设计、网站线框图、地图等各种类型的图形。该软件的界面直观,用户友好,让用户能够轻松地创建和编辑复杂的图形。 OmniGr…...

ai批量剪辑矩阵无人直播一站式托管系统源头技术开发
一、剪辑技术开发 智能剪辑:咱们研发公司自主研发的,包括算法,算法是阶乘算法,无限产出,六大剪辑模式已经满足当下需求了,当然剪辑出的视频可以一键发布,也可以内部批量发布,都可以的…...

CCNA课程实验-14-Final_Lab
目录 实验条件网络拓朴需求 配置实现1. 配置PC1~3, DHCP_Server的vlan2. VLAN10、20的网关为MSW1对应的SVI,VLAN30、40的网关为MSW2对应的SVI;3. 配置5台交换机之间线路均为Trunk4. 配置5台交换机均启用Rapid-PVST(RSTP)5. 配置DHCP Server,创…...

Latex在图表标题里面引用参考文献时,出现参考文献顺序混乱的解决方案(适用于bibtex)
问题描述 如果你在figure环境的\caption或\captionof中使用\cite,但是参考文献的顺序仍然不正确,可能是因为LaTeX的处理流程导致了这个问题。 比如图片在第二章节但里面引用了参考文献,在文章末尾的参考文献第二章图片的参考文献顺序&#…...
多进程间通信学习之消息队列共享内存信号灯集
消息队列:1、基于内核实现,必须在内核空间创建消息队列;2、消息队列中的消息由类型和正文组成;3、消息队列的默认大小为16KB;运行过程:1、进程1将消息写入到消息队列,进程2根据消息的类型从消息…...
机器学习基础之《回归与聚类算法(6)—模型保存与加载》
一、背景 现在我们预测每次都要重新运行一遍模型。完整的流程应该是不断调整阈值重复计算。 当训练或者计算好一个模型之后,那么如果别人需要我们提供结果预测,就需要保存模型(主要是保存算法的参数)。 二、sklearn模型的保存和…...

修改Openwrt软路由的web端口
如何修改openwrt路由器的web访问端口号? 在OpenWrt路由器上,如何修改Web访问端口号,通常涉及到修改HTTP服务器的配置文件。默认情况下,OpenWrt使用的HTTP服务器是uHTTPd。 以下是修改Web访问端口号的步骤: 一、通过…...

编程怎么学习视频教程,编程实例入门教程,中文编程开发语言工具下载
编程怎么学习视频教程,编程实例入门教程,中文编程开发语言工具下载。 给大家分享一款中文编程工具,零基础轻松学编程,不需英语基础,编程工具可下载。 这款工具不但可以连接部分硬件,而且可以开发大型的软件…...

得帆信息携手深信服,联合打造高安全PaaS超融合一体化解决方案
上海得帆信息技术有限公司(以下简称“得帆”)和深信服科技股份有限公司(以下简称“深信服”)携手推出融合安全性、稳定性、高效性于一体的全新PaaS超融合解决方案。 用户痛点分析 全面推进企业数字化与信息化的趋势下,…...

arcgis--浮点型栅格数据转整型
利用【Spatial Analyst工具】-【数学】-【转为整型】工具,将浮点型数据转为整型。如下: 【转为整型】对话框参数设计如下: 转换结果如下:...

nginx四层tcp负载均衡及主备、四层udp负载均衡及主备、7层http负载均衡及主备配置(wndows系统主备、负载均衡)
准备工作 服务器上安装、配置网络负载平衡管理器 windows服务器热备、负载均衡配置-CSDN博客 在windows服务器上安装vmware17 win10 上安装vmware17-CSDN博客 在windows上利用vmware17 搭建centos7 mini版 在windows上利用vmware17 搭建centos7 mini版本服务器-CSDN博客 …...
Electron 控制屏幕亮度
CMD控制屏幕亮度 一开始用brightness,dev下可用,打包后执行报错,找了很多文章都没办法解决。后来想到执行CMD命令去设置( 如何在 Windows 中使用命令行调整屏幕亮度 )。测试打包后正常,无需管理员权限。 引入exec const { exec }…...

TSINGSEE视频汇聚管理与AI算法视频质量检测方案
一、建设背景 随着互联网视频技术的发展,视频监管在辅助安全生产、管理等方面发挥了不可替代的作用。但是,在监管场景中,仍然存在视频掉线、视频人为遮挡、视频录像存储时长不足等问题,对企业的日常管理和运转存在较大的安全隐患…...
linux系统中文件系统和挂载点的联系和区别?
在 Linux 系统中,文件系统(File System)和挂载点(Mount Point)是密切相关的概念,它们之间有如下联系和区别: 文件系统:文件系统是操作系统用于组织和管理数据的一种结构。它定义了文…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...