Electron学习笔记(二)Hello World

news2025/2/24 20:46:15

目录

前言

运行主进程

创建界面

使用窗口打开界面

管理窗口的生命周期

关闭所有窗口时退出应用 (Windows & Linux)​

如果没有窗口打开则打开一个窗口 (macOS)

使用预加载脚本访问渲染器的Node.js

添加你自己的功能

完整代码展示

效果展示


前言

接上一篇文章

Electron学习笔记(一)基础环境-CSDN博客

这一篇文章我们开始做第一个小demo

运行主进程

上一篇文章我们在根目录配置了package.json文件

任何 Electron 应用程序的入口都是 main 字段对应文件。 这个文件控制了主进程,它运行在一个完整的Node.js环境中,负责控制应用的生命周期,显示原生界面,执行特殊操作并管理渲染器进程(稍后详细介绍)。

执行期间,Electron 将依据应用中 package.json配置下main字段中配置的值查找此文件。

我们在上一篇中配置了scripts字段中的start。此时我们可以执行以下命令来开始运行程序:

npm start

此时会弹窗并报错,提示你找不到main.js文件。

要初始化这个main文件,需要在项目的根目录下创建一个名为main.js的空文件。

创建完成后再次执行,效果如下

注意:这一次运行start命令,应用将不再抛出任何错误! 然而,它不会做任何事因为我们还没有在main.js中添加任何代码。

创建界面

在为我们的应用创建窗口前,我们需要先创建加载进该窗口的内容。 在Electron中,各个窗口显示的内容可以是本地HTML文件,也可以是一个远程url。

我们这里使用本地的HTML文件。

在项目根目录下创建一个名为index.html的文件,内容如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using Node.js <span id="node-version"></span>,
    Chromium <span id="chrome-version"></span>,
    and Electron <span id="electron-version"></span>.
  </body>
</html>

注意:在这个HTML文本中,你会发现主体文本中丢失了版本编号。 稍后我们将使用 JavaScript 动态插入它们。

使用窗口打开界面

现在我们有了一个页面,下面需要将它加载进应用窗口中。 要做到这一点,你需要 两个Electron模块:

  • app 模块,它控制应用程序的事件生命周期。
  • BrowserWindow 模块,它创建和管理应用程序 窗口。

因为主进程通过Node.js运行,所以我们需要在 main.js文件开头import这些模块。

const { app, BrowserWindow } = require('electron')

然后,添加一个createWindow()方法来将index.html加载进一个新的BrowserWindow实例。

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600
  })

  win.loadFile('index.html')
}

接着,调用createWindow()函数来打开您的窗口。

在 Electron 中,只有在 app 模块的 ready 事件被激发后才能创建浏览器窗口。 您可以通过使用 app.whenReady() API来监听此事件。 在whenReady()成功后调用createWindow()

app.whenReady().then(() => {
  createWindow()
})

到这里,整个main.js文件应该是这样的

const { app, BrowserWindow } = require('electron')

const createWindow = () => {
    const win = new BrowserWindow({
      width: 800,
      height: 600
    })
  
    win.loadFile('index.html')
}

app.whenReady().then(() => {
    createWindow()
})

保存后,在cmd中运行上面提到的开始命令:

npm start

此时你的“Hello World”窗口应该已经可以成功打开了。

管理窗口的生命周期

虽然我们现在可以打开一个浏览器窗口,但你还需要一些额外的模板代码使其看起来更像是各平台原生的应用。 应用程序窗口在每个OS下有不同的行为,Electron将在app中实现这些约定的责任交给开发者们。

一般而言,你可以使用 进程 全局的 platform 属性来专门为某些操作系统运行代码。

关闭所有窗口时退出应用 (Windows & Linux)​

在Windows和Linux上,关闭所有窗口通常会完全退出一个应用程序。

为了实现这一点,你需要监听 app 模块的 'window-all-closed' 事件。如果用户不是在 macOS(darwin) 上运行程序,则调用 app.quit()。

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

如果没有窗口打开则打开一个窗口 (macOS)

当 Linux 和 Windows 应用在没有窗口打开时退出了,macOS 应用通常即使在没有打开任何窗口的情况下也继续运行,并且在没有窗口可用的情况下激活应用时会打开新的窗口。

为了实现这一特性,监听 app 模块的 activate 事件。如果没有任何浏览器窗口是打开的,则调用 createWindow() 方法。

因为窗口无法在 ready 事件前创建,你应当在你的应用初始化后仅监听 activate 事件。 通过在您现有的 whenReady() 回调中附上您的事件监听器来完成这个操作。

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

使用预加载脚本访问渲染器的Node.js

这个步骤我们演示的是输出Electron的版本号和它的依赖项到你的web页面上。

通过 Node 的全局进程对象在主进程中访问这些信息非常简单。 然而,你不能直接在主进程中编辑DOM,因为它无法访问渲染器的document上下文。 它们存在于完全不同的进程!

英文参考文档:Process Model | Electron (electronjs.org)

这时我们要用到预加载脚本。预加载脚本在渲染器进程加载之前加载,并有权访问两个渲染器全局 (例如 window 和 document) 和 Node.js 环境。

在根目录创建一个名为 preload.js 的新脚本如下:

window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, process.versions[dependency])
  }
})

上面的代码访问 Node.js的 process.versions 对象,并运行一个基本的 replaceText 辅助函数将版本号插入到 HTML 文档中。

要将此脚本附加到渲染器流程,请在你现有的 BrowserWindow 构造器中将路径中的预加载脚本传入 webPreferences.preload 选项。修改后如下:

const { app, BrowserWindow } = require('electron')
// 在你文件顶部导入 Node.js 的 path 模块
const path = require('node:path')

// 修改已有的 createWindow() 方法
const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  win.loadFile('index.html')
}
// ...

这里使用了两个Node.js概念:

  • __dirname 字符串指向当前正在执行脚本的路径 (在本例中,它指向你的项目的根文件夹)。
  • path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。

使用相对路径的方法在开发和打包时同样有效。

添加你自己的功能

此刻,你可能想知道如何为应用程序添加更多功能。

对于任何与 Web 内容的交互,需要将脚本添加到渲染器进程中。由于渲染器在正常的 Web 环境中运行,因此可以在 index.html 文件的结束标记 </body> 之前添加 <script> 标记,以包含您想要的任意脚本,例如:

<script src="./renderer.js"></script>

renderer.js 中包含的代码可以在接下来使用与前端开发相同的 JavaScript API 和工具。例如使用 webpack 打包并最小化您的代码,或者使用 React 来管理您的用户界面。

完整代码展示

main.js

const { app, BrowserWindow } = require('electron')
// 在你文件顶部导入 Node.js 的 path 模块
const path = require('node:path')

const createWindow = () => {
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      webPreferences: {
        preload: path.join(__dirname, 'preload.js')
      }
    })
  
    win.loadFile('index.html')
}

app.whenReady().then(() => {
    createWindow()
  
    app.on('activate', () => {
      if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })
})

preload.js

window.addEventListener('DOMContentLoaded', () => {
    const replaceText = (selector, text) => {
      const element = document.getElementById(selector)
      if (element) element.innerText = text
    }
  
    for (const dependency of ['chrome', 'node', 'electron']) {
      replaceText(`${dependency}-version`, process.versions[dependency])
    }
})

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using Node.js <span id="node-version"></span>,
    Chromium <span id="chrome-version"></span>,
    and Electron <span id="electron-version"></span>.
    
    <script src="./renderer.js"></script>
  </body>
</html>

package.json

{
  "name": "项目名称",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
	  "start": "electron ."
  },
  "author": "你的名字",
  "license": "ISC",
  "description": "你的项目描述"
}

效果展示

执行上面的提到的start命令开始程序,结果如下:

 快捷键 ctrl+shift+i 打开控制台,如下:

下一篇文章将项目打包成发布版本

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JWT详细解析

目录 1. 什么是JWT&#xff1f; 2. 前后端完全分离认证问题 3. JWT的原理 4. JWT的数据结构 5. Header 6. Payload 7. Signature 8.JWT的使用方式 1. 什么是JWT&#xff1f; Json web token (JWT)&#xff0c;是为了在网络应用环境间传递声明而执行的一种基于JSON的开放…

nginx服务---负载均衡、平滑升级

一、nginx服务配置属性监控、nginx代理服务和nginx的IP访客黑名单 1.属性监控 通过在编译时加入 nginx 的 ngx_http_stub_status_module 模块可以实时监控以下基本的指标&#xff1a; 部署过程&#xff1a; 在配置文件/usr/local/nginx/conf/nginx.conf中的server模块中&…

【uniapp离线打包】(基于Android studio)

文章目录 uniapp打包官方教程入口一、准备工作(工具三大件)二、准备工作&#xff08;Android壳和uniapp包&#xff09;导入Android壳生成uniapp包将uniapp包导入android壳 三、准备工作&#xff08;证书、&#xff09;准备Android平台离线签名证书 四、修改配置参数build.gradl…

Data Augmentation数据增强

目录 数据增强是什么 为什么数据增强 数组增强分类 有监督数据增强 无监督数据增强 数据增强是什么 数据增强又称数据扩增&#xff0c;是一种通过应用合理且随机的变换&#xff08;例如图像位移、旋转&#xff09;来增加训练集多样性的技术。让有限的数据产生等价于更多数…

卷积神经网络(五)---图像增强的方法

前面的部分专注于卷积神经网络的层结构介绍&#xff0c;同时还介绍了到目前为止比较出名的卷积神经网络&#xff0c;接着使用比较复杂的卷积神经网络提高了 MNIST 数据集的准确率。下面将从另外的角度——图像增强的方面入手&#xff0c;提高模型的准确率和泛化能力。 一直以来…

C# 弃元的详解与示例

文章目录 1. 什么是弃元&#xff1f;2. 弃元的语法3. 弃元的应用场景4. 示例代码5. 总结 在C# 7.0及更高版本中&#xff0c;弃元&#xff08;Discard&#xff09;是一个新的语言特性&#xff0c;允许开发者在特定情况下忽略某些值。这在处理元组、解构操作或其他只需要部分值的…

【区块链+绿色低碳】泸州:“绿芽积分”号召全民绿色减碳 | FISCO BCOS应用案例

2021 年 6 月 5 日&#xff0c; 首个基于“绿普惠云”所构建的政府级碳普惠平台“泸州市‘绿芽积分’”在生态环境部 2021 年 六五世界环境日国家主场活动中展示&#xff0c;并跻身进入生态环境部“提升公民生态文明意识行动计划”2021 十佳公众 参与案例。 “绿普惠云”是为政…

精通推荐算法11:基于异构图游走的Graph Embedding

DeepWalk、Line和Node2vec对图结构数据进行随机游走&#xff0c;成功将其转化为一个序列问题&#xff0c;并利用Word2vec训练得到节点的Embedding向量。但它们都基于同构图&#xff0c;其节点均属于同一种类型。但现实世界的数据网络大多基于异构图&#xff0c;其节点类型以及节…

【Linux】全志Tina配置log串口信息以及env信息的方法

一、文件位置 V:\f1c100s\Evenurs\f1c100s\tina\device\config\chips\c200s\configs\F1C200s\linux\env-3.10.cfg 二、文件内容 三、介绍 console&#xff1a;串口信息 version&#xff1a;版本信息 appAB&#xff1a;ab区信息 cma&#xff1a;cma容量 四、总结 在此文…

【HarmonyOS】鸿蒙中如何获取资源文件的指定类型 fd,string,Uint8Array,RawFileDescriptor

【HarmonyOS】鸿蒙中如何获取资源文件的指定类型 fd&#xff0c;string&#xff0c;Uint8Array&#xff0c;RawFileDescriptor 一、问题背景&#xff1a; 众所周知&#xff0c;在鸿蒙中的资源分为media和rawfile。两者的区别对标android工程一致&#xff0c;后者是其他类型文…

高月供,高负债,有没有好的办法去解决?

朋友们&#xff0c;有没有过这样的经历&#xff0c;觉得手里那堆贷款账户和每个月高高的月供&#xff0c;就像两座大山压得你喘不过气&#xff1f;特别是想从网贷的高利贷坑跳到银行的低息怀抱&#xff0c;却屡遭拒绝&#xff0c;那种无力感和自我怀疑&#xff0c;简直让人崩溃…

【城市数据集】世界城市数据库和访问门户工具WUDAPT

世界城市数据库和访问门户工具WUDAPT WUDAPTLCZ分类具体步骤参考 在 城市气候研究中&#xff0c;用于描述城市特征的数据集一般采用基于类别的传统方法&#xff0c;将城市地区分为数量有限的类型&#xff0c;从而导致精确度下降。越来越多的新数据集以亚米微尺分辨率描述城市的…

嵌入式学习Day17---Linux软件变编程

目录 ​编辑 一、Linux 系统 1.1.Linux服务器 1.2.Linux嵌入式 1.3.Linux系统上的软件开发 1.操作系统 2.Linux内核 3.man手册 1.4.shell命令 1.基本命令 2.文件查看命令 3.文件查找命令 4.压缩解压文件 5.其他命令 6.通配符 7.管道 8.重定向 1.5.虚拟机上网 1.NAT模式 …

JS学习(变量、数据类型、运算符以及流程控制语句)

目录 一、变量 二、数据类型 三、运算符 四、类型转换 &#xff08;1&#xff09;字符串类型转为数字 &#xff08;2&#xff09;其他类型转为boolean&#xff08;这些全部都是自动转换&#xff09; 五、流程控制 一、变量 &#xff08;1&#xff09;var&#xff1a;声…

2024西安铁一中集训DAY26 ---- 模拟赛(最短路 + 实数域二分 + 线段树 + 并查集(平面图欧拉定理))

文章目录 前言时间安排与成绩题解A. 江桥的蓝紫灯&#xff08;最短路&#xff09;B. 江桥的破坏行动&#xff08;实数域二分&#xff09;C. 江桥的最小值&#xff08;线段树&#xff09;D. 江桥的山谷&#xff08;并查集&#xff0c;平面图欧拉定理&#xff09; 前言 感觉是做…

Android NDK 编译 libcurl支持https

最后在使用NDK中使用libcurl&#xff0c;由于不同的安卓设备&#xff0c;版本不一样&#xff1b;使用so时&#xff0c;会导致报错dlopen时找不到某函数或出错。 最后直接使用libcurl.a后&#xff0c;目前在几款盒子上测试均能正常工作。 libcurl需要支持https得提前编译两个库…

LLM评估 | 大模型评估方法调研--论文解读(持续更新ing!!!)

目录 LLM-based NLG Evaluation: Current Status and ChallengesAdaptEval: Evaluating Large Language Models on Domain Adaptation for Text SummarizationThe Potential and Challenges of Evaluating **Attitudes, Opinions, and Values** in Large Language ModelsEvalLM…

揭秘高效语音转文字工具:让沟通更便捷

嘿&#xff0c;各位办公室的小伙伴们&#xff0c;今儿咱们来聊聊那些能让咱们文员生活大变样的神器——特别是那些能把咱们嘴里嘟囔的话儿&#xff0c;瞬间变成电脑里整整齐齐文字的语音转文字工具。说起来&#xff0c;自从有了这些宝贝&#xff0c;我感觉自己都快能飞起来了&a…

VUE 3.0 如何新建项目 详细教程 附环境搭建 推荐

本人新入手一台电脑&#xff0c;需要安装各种环境配置&#xff0c;顺便把过程记录一下&#xff0c;方便自己以后查看&#xff0c;也欢迎大家参考交流。 目录 一、环境搭建&#xff1a; 1.Node.js安装 2.国内淘宝镜像设置 3.安装vue 环境 二、新建vue项目 1.vue脚手架新建…

昇思25天学习打卡营第21天|FCN图像语义分割案例:从数据集下载到模型推理

目录 MindSpore 版本管理与数据集下载准备 图像分割数据集的定义、处理与获取 训练集数据的图像展示 基于 MindSpore 的 FCN8s 图像分割模型定义 图像分割模型的预训练模型加载与评估指标定义 基于 CPU 的 FCN8s 模型训练配置与准备 FCN8s 模型的权重加载与评估数据集的评…