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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/193103.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp基础学习笔记01

文章目录 本博客根据黑马教程学习uniapp一、技术架构二、创建项目2.1 Hbuilder创建2.2 插件安装2.3 微信开发者工具配置与运行2.3.1 简单修改基础页面 2.4 pages.json和tabBar2.4.1 pages.json与tabBar配置2.4.2 案例 三、uniapp与原生开发的区别 本博客根据黑马教程学习uniapp…

安装node.js指定任意版本详解

Node.js是一种基于Chrome V8引擎的JavaScript运行时环境。它允许开发人员使用JavaScript编写服务器端和网络应用程序。与传统的JavaScript在浏览器中执行不同&#xff0c;Node.js使得JavaScript可以在服务器端运行。 Node.js具有以下特点&#xff1a; 1. 非阻塞式I/O&#xf…

Java设计模式-结构型模式-适配器模式

适配器模式 适配器模式应用场景案例类适配器模式对象适配器模式接口适配器模式适配器模式在源码中的使用 适配器模式 如图&#xff1a;国外插座标准和国内不同&#xff0c;要使用国内的充电器&#xff0c;就需要转接插头&#xff0c;转接插头就是起到适配器的作用 适配器模式&…

springboot国际化

1.环境配置 这里插入图片描述](https://img-blog.csdnimg.cn/024d6bc95623485eb6da4d998a892458.png) 2.文件配置 第一个默认环境 第二个英文环境 第三个中文环境 3.变量配置 调整语言 原理&#xff1a; 找到MessageSourceAutoConfiguration 中的 利用代碼的方式獲取国…

图论11-欧拉回路与欧拉路径+Hierholzer算法实现

文章目录 1 欧拉回路的概念2 欧拉回路的算法实现3 Hierholzer算法详解4 Hierholzer算法实现4.1 修改Graph&#xff0c;增加API4.2 Graph.java4.3 联通分量类4.4 欧拉回路类 1 欧拉回路的概念 2 欧拉回路的算法实现 private boolean hasEulerLoop(){CC cc new CC(G);if(cc.cou…

数字化转型时代,商业智能BI到底是什么?

据国际数据公司&#xff08;IDC&#xff09;预测&#xff0c;2025年时中国产生的数据量预计将达48.6ZB&#xff0c;在全球中的比例为27.8%。商业智能BI这一专为企业提供服务的数据类解决方案&#xff0c;仅2021年上半年在中国商业智能BI市场规模就达到了3.2亿美元&#xff0c;商…

java入门,从CK导一部分数据到mysql

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

Java绘图-第19章

Java绘图-第19章 1.Java绘图类 1.1Graphics类 Graphics类是用于绘制图形的抽象类&#xff0c;它是java.awt包中的一部分。Graphics类提供了各种方法&#xff0c;可以在图形上绘制各种形状、文本和图像。这些方法包括画线、画矩形、画椭圆、画弧、绘制图像等。 1.2Graphics2…

Android修行手册 - 阴影效果的几种实现以及一些特别注意点

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC &#x1f449;关于作者 专…

3D造型渲染软件DAZ Studio mac中文版介绍

DAZ Studio mac是一款3D造型和渲染软件&#xff0c;由 Daz 3D 公司开发。它允许用户创建、编辑、动画化并渲染精美的数字图像与动画。DAZ Studio 还提供了一个虚拟的3D艺术家工作室环境&#xff0c;让用户可以轻松地设置场景、布置角色和应用材质。 用户可以通过 DAZ Studio 中…

8.查询数据

一、单表查询 MySQL从数据表中查询数据的基本语为SELECT语。SELECT语的基本格式是: SELECT {* | <字段列名>} [ FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY <group by definition> [HAVING <expression> [{<operator>…

032-从零搭建微服务-定时服务(一)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;mingyue: &#x1f389; 基于 Spring Boot、Spring Cloud & Alibaba 的分布式微服务架构基础服务中心 源…

C语言不可不敲系列:跳水比赛排名问题

目录 1题干&#xff1a; 2解题思路&#xff1a; 3代码: 4运行结果: 5总结: 1题干&#xff1a; 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果 A选手说&#xff1a;B第二&#xff0c;我第三&#xff1b; B选手说&#xff1a;我第二&#xff0c;E第四&am…

十九章总结

Graphics类 Graphics类是所有图形上下文的抽象基类&#xff0c;封装了Java支持的基本绘图操作所需的状态信息&#xff0c;主要包括颜色、字体、画笔 Graphics2D类 Graphics2D类继承Graphics类实现功能更加强大的绘图操作集合 绘制图形 在项目中创建一个类&#xff0c;是该…

nginx安装搭建

下载 免费开源版的官方网站&#xff1a;nginx news Nginx 有 Windows 版本和 Linux 版本&#xff0c;但更推荐在 Linux 下使用 Nginx&#xff1b; 下载nginx-1.14.2.tar.gz的源代码文件&#xff1a;wget http://nginx.org/download/nginx-1.14.2.tar.gz 我的习惯&#xff0…

【Linux进阶之路】一文吃透文件

前言 先来谈一下文件的共识 文件 内容 属性。 解释&#xff1a;文件在创建时就有基本属性&#xff0c;比如权限&#xff0c;文件名&#xff0c;文件的创建时间等基本信息。文件分为打开的文件与未被打开的文件。 解释&#xff1a;打开的文件由操作系统进行管理。未打开的文件…

JZ22:链表中倒数第k个结点

JZ22&#xff1a;链表中倒数第k个结点 题目描述&#xff1a; 输入一个链表&#xff0c;输出该链表中倒数第k个结点。 示例1 输入&#xff1a; 1,{1,2,3,4,5} 返回值&#xff1a; {5} 分析&#xff1a; 快慢指针思想&#xff1a; 需要两个指针&#xff0c;快指针fast&…

云课五分钟-03第一个开源游戏复现-贪吃蛇

前篇 云课五分钟-02第一个代码复现-终端甜甜圈C 视频 云课五分钟-03第一个开源游戏复现-贪吃蛇 一个终端的动态字符显然很难调动编程的积极性&#xff0c;那么更有趣的开源的游戏也许是一种更好的启发。 文本 蓝桥ROS机器人之绚丽贪吃蛇 如何在Linux下使用 DungeonRush-mast…

【java学习—十四】反射机制调用指定方法、指定属性(5)

文章目录 1. 调用指定方法2. 调用指定属性 1. 调用指定方法 通过反射&#xff0c;调用类中的方法&#xff0c;通过 Method 类完成。步骤&#xff1a;     ①通过 Class 类的 getMethod(String name,Class...parameterTypes) 方法取得一个 Method 对象&#xff0c;并设置此…

C#使用时序数据库 InfluxDB

一、安装 https://docs.influxdata.com/influxdb/v2/install/?tWindows 解压后使用cmd运行 访问 localhost:8086 配置 第一次登入会初始化 配置登入账号 保存TOKEN 这个TOKEN用于后期代码链接访问数据库&#xff0c;忘记了只能删除重新生成 点击QUCK START进入管理页面 …