Electron学习笔记(一)

news2024/12/23 11:20:56

文章目录

      • 相关笔记
      • 笔记说明
    • 一、轻松入门
      • 1、搭建开发环境
      • 2、创建窗口界面
      • 3、调试主进程
    • 二、主进程和渲染进程
      • 1、进程互访
      • 2、渲染进程访问主进程类型
      • 3、渲染进程访问主进程自定义内容
      • 4、渲染进程向主进程发送消息
      • 5、主进程向渲染进程发送消息
      • 6、多个窗口的渲染进程接收主进程发送的消息
      • 7、渲染进程之间消息传递
        • 方法一:利用主进程进行中转
        • 方法二:单向传递

相关笔记

  • Electron学习笔记(一)
  • Electron学习笔记(二)
  • 使用 electron-vite-vue 构建 electron + vue3 项目并打包

笔记说明

文本为学习《Electron 实战 入门、进阶与性能优化 刘晓伦 著》时所记录的笔记 主要将书本上的案例运行一遍,针对原理部分并无相关记录。笔记记录于 2023年9月。

一、轻松入门

1、搭建开发环境

安装 yarn :

npm i -g yarn

创建一个文件夹,进行项目的初始化:

yarn init -y

配置 Electron 的镜像网站:

yarn config set electron_mirror https://registry.npmmirror.com/-/binary/electron/

使用 yarn 安装 Electron:

yarn add electron --dev

2、创建窗口界面

创建一个 index.html 文件,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron</title>
</head>
<body>
    <h1>Hello World</h1>
</body>
</html>

新建一个 index.js 文件,内容如下:

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

let win = null;

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true
        }
    });
    // 访问资源文件
    win.loadFile('index.html');

    // 程序启动后开启 开发者工具
    // win.webContents.openDevTools();
    
    win.on('close',function() {
        win = null;
    })
});

app.on('window-all-closed',function() {
    app.quit();
})

更新 package.json 文件:

"scripts": {
"start": "electron ./index.js"
},

启动项目:

yarn start

结果展示:

效果展示

3、调试主进程

点击调试按钮,创建 launch.json 文件 -> 选择Node.js环境

调试

修改 launch.json 文件如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "调试主进程",
            // type: 调试环境为 Node.js 环境
            "type": "node",
            "request": "launch",
            "cwd": "${workspaceRoot}",
            // runtimeExecutable: 指向的是批处理文件,该批处理文件用于启动 Electron
            // ${workspaceRoot} 是正在进行调试的程序的工作目录的绝对路径
            "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
            "windows": {
                "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
            },
            // 此处的参数是主进程程序路径的简写形式,填写 "./index.js" 亦可
            "args": ["."],
            "outputCapture": "std"
        }
    ]
}

快捷键:

Ctrl+Shift+I:打开渲染进程的调试窗口

Ctrl+R:代码修改后,刷新界面

二、主进程和渲染进程

1、进程互访

注:原书籍中的代码由于 Electron 版本的更新,remote 模块无法直接导入使用,需要进行下载:

下载 remote 模块:

yarn add @electron/remote

更新 index.js 文件如下:(主进程代码

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

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    require("@electron/remote/main").initialize();
    require("@electron/remote/main").enable(win.webContents);

    // 访问资源文件
    win.loadFile('index.html');

    // 程序启动后开启 开发者工具
    // win.webContents.openDevTools();

    win.on('close',function() {
        win = null;
    })
});

app.on('window-all-closed',function() {
    app.quit();
})

参考链接:https://blog.csdn.net/m0_45961428/article/details/122982510

在 index.html 添加以下代码:

<button id="openDevToolsBtn">打开开发者工具</button>
<script>
    const remote =require('@electron/remote');
    document.querySelector('#openDevToolsBtn').addEventListener('click',function() {
        remote.getCurrentWindow().webContents.openDevTools();
    })
</script>

运行程序:

yarn start

运行结果:(点击按钮可打开开发者工具)

运行结果

2、渲染进程访问主进程类型

主进程代码:主进程代码

更新 index.html 文件如下:

<button id="makeNewWindow">创建新窗口</button>
<script>
    const remote = require('@electron/remote');

    // 在渲染进程中创建一个新的窗口
    document.querySelector('#makeNewWindow').addEventListener('click',function() {
        win = new remote.BrowserWindow({
            webPreferences: {
                nodeIntegration: true,
            }
        });
        win.loadFile('newWin.html');
    });
</script>

说明:创建 BrowserWindow 的过程依然在主进程中进行,是由 remote 模块通知主进程完成相应的操作的,主进程创建了 BrowserWindow 对象的实例后,把对象的实例以远程对象的形式返回给渲染进程。

3、渲染进程访问主进程自定义内容

主进程代码:主进程代码

新建文件 mainModel.js:

let {BrowserWindow} = require('electron');

exports.makeWin = function() {
    let win = new BrowserWindow({
        webPreferences: {
            nodeIntegration: true,
        }
    });
    return win;
}

更新 index.html 文件如下:

<button id="makeNewWindow2">创建新窗口2</button>
<script>
    const remote = require('@electron/remote');
    const mainModel = remote.require('./mainModel');

    let win2 = null;
    document.querySelector('#makeNewWindow2').addEventListener('click',function() {
        win2 = mainModel.makeWin();
        win2.loadFile('newWin.html');
    });
</script>

4、渲染进程向主进程发送消息

更新 index.html 文件:

<button id="sendMsg">向主进程发送消息</button>
<script>
    const {ipcRenderer} = require('electron');

    document.querySelector('#makeNewWindow2').addEventListener('click',() => {
        // msg:消息管道的名称
        ipcRenderer.send('msg',{name: 'xiaom'},{name: 'xiaoh'});
    });
</script>

index.js 文件添加以下内容:(其余主进程代码见:主进程代码)

const {ipcMain} = require('electron');

ipcMain.on('msg',(event,param1,param2) => {
    console.log(param1);
    console.log(param2);
    console.log(event.sender);
})

运行结果:

运行结果

5、主进程向渲染进程发送消息

在主进程 index.js 文件中添加以下代码:

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

let win = null;

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    // 监听渲染进程发来的消息,随后再次发回给渲染进程
    ipcMain.on('msg',(event,param1,param2) => {
        win.webContents.send('msg_main',param1,param2);
    })

    // 访问资源文件
    win.loadFile('index.html');

    win.on('close',function() {
        win = null;
    })
});

更新渲染进程 index.html 文件如下:

<button id="sendMsg">向主进程发送消息</button>
<script>
    const {ipcRenderer} = require('electron');

    // 接收 主进程发送的消息
    ipcRenderer.on('msg_main',(event,param1,param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    })

    document.querySelector('#sendMsg').addEventListener('click',() => {
        ipcRenderer.send('msg',{name: 'xiaom'},{name: 'xiaoh'});
    });
</script>

运行程序后 -> 点击按钮(向主进程发送消息) -> Electron 程序控制台将会打印主进程发送来的消息。

运行结果:

运行结果

6、多个窗口的渲染进程接收主进程发送的消息

更新主进程 index.js 文件:

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

// 接收 渲染进程 发送来的消息 在VSCode控制台打印消息
ipcMain.on('msg',(event,param1,param2) => {
    console.log(param1);
    console.log(param2);
    console.log(event.sender);
});

let win = null;

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    // 为了使 remote 模块能够使用需要执行以下操作
    require("@electron/remote/main").initialize();
    require("@electron/remote/main").enable(win.webContents);

    // 监听 渲染进程 发来的消息,随后再次发回给渲染进程
    ipcMain.on('msg',(event,param1,param2) => {
        // 单个窗口时使用:
        // win.webContents.send('msg_main',param1,param2);

        // 多个窗口时使用
        // 方法一:
        // event.sender.send('msg_main',param1,param2);
        // 方法二:
        event.reply('msg_main',param1,param2);
    })

    // 访问资源文件
    win.loadFile('index.html');

    win.on('close',function() {
        win = null;
    })
});

app.on('window-all-closed',function() {
    app.quit();
});

更新 index.html 文件如下:

<button id="makeNewWindow">创建新窗口</button>
<button id="sendMsg">向主进程发送消息</button>
<script>

    const remote = require('@electron/remote');
    const { ipcRenderer } = require('electron');

    // 在渲染进程中创建一个新的窗口
    document.querySelector('#makeNewWindow').addEventListener('click', function () {
        win = new remote.BrowserWindow({
            webPreferences: {
                nodeIntegration: true,
                contextIsolation: false
            }
        });
        win.loadFile('newWin.html');
    });

    // 监听主进程发送来的消息
    ipcRenderer.on('msg_main', (event, param1, param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    })

    // 点击发送按钮 发送消息至主进程
    document.querySelector('#sendMsg').addEventListener('click', () => {
        ipcRenderer.send('msg', { name: 'xiaom' }, { name: 'xiaoh' });
    });
</script>

newWin.html 文件内容如下:

<h1>newWindow</h1>
<button id="sendMsg2">向主进程发送消息</button>
<script>
    const { ipcRenderer } = require('electron');

    // 监听主进程发送来的消息
    ipcRenderer.on('msg_main', (event, param1, param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    })

    // 点击发送按钮 发送消息至主进程
    document.querySelector('#sendMsg2').addEventListener('click', () => {
        ipcRenderer.send('msg', { name: 'xiaod' }, { name: 'xiaoc' });
    });
</script>

7、渲染进程之间消息传递

一个程序有多个窗口,并要在窗口之间传递消息,可以通过主进程中转,此处通过win1先将消息发送给主进程,主进程再将消息发送给win2。

方法一:利用主进程进行中转

窗口(win1) --> 主进程(中转) --> 窗口(win2)

窗口(win2) --> 主进程(中转) --> 窗口(win1)

主进程 index.js 文件内容如下:

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

let win = null;

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    require("@electron/remote/main").initialize();
    require("@electron/remote/main").enable(win.webContents);

    // 监听 窗口win1 (index.html) 发来的消息
    ipcMain.on('msg_1',(event,param1,param2) => {
        // 向 窗口win1 (index.html) 发送消息
        win.webContents.send('msg_main',param1,param2);
    });

    // 访问资源文件
    win.loadFile('index.html');

    // 程序启动后开启 开发者工具
    win.webContents.openDevTools();

    win.on('close',function() {
        win = null;
    })
});

app.on('window-all-closed',function() {
    app.quit();
})

窗口(win1) index.html 文件内容如下:

<h1>win1</h1>
<button id="makeNewWindow">创建新窗口win2</button>
<button id="sendMsg">向主进程发送消息</button>
<script>

    const remote = require('@electron/remote');
    const { ipcRenderer } = require('electron');

    // 在渲染进程中创建一个新的窗口(win2)
    document.querySelector('#makeNewWindow').addEventListener('click', function () {
        win2 = new remote.BrowserWindow({
            webPreferences: {
                nodeIntegration: true,
                contextIsolation: false
            }
        });
        win2.loadFile('win2.html');
        win2.webContents.openDevTools();

        // 接收 主进程 的消息后 向 win2 发送消息
        ipcRenderer.on('msg_main', (event, param1, param2) => {
            win2.webContents.send('msg_win2',param1,param2);
        });
    });

    // 接收 主进程 发送的消息
    ipcRenderer.on('msg_main', (event, param1, param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    })

    // 点击按钮向 主进程 发送消息
    document.querySelector('#sendMsg').addEventListener('click', () => {
        ipcRenderer.send('msg_1', { name: 'xiaom' }, { name: 'xiaoh' });
    });
</script>

窗口(win2) win2.html 文件内容如下:

<h1>win2</h1>
<button id="sendMsg2">向主进程发送消息</button>
<script>
    const { ipcRenderer } = require('electron');

    // 接收 窗口 win1 (index.html) 发送来的消息
    ipcRenderer.on('msg_win2', (event, param1, param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    })

    // 点击按钮向 主进程 发送消息
    document.querySelector('#sendMsg2').addEventListener('click', () => {
        ipcRenderer.send('msg_1', { name: 'xiaod' }, { name: 'xiaoc' });
    });
</script>

结果展示:

结果展示

方法二:单向传递

窗口(win1) --> 窗口(win2)

主进程 index.js 文件内容如下:(此方法无需主进程中转,所以主进程无需接收消息)

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

let win = null;

app.on('ready', function() {
    win = new BrowserWindow({
        // 为页面集成Node.js环境
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    require("@electron/remote/main").initialize();
    require("@electron/remote/main").enable(win.webContents);

    // 访问资源文件
    win.loadFile('index.html');

    // 程序启动后开启 开发者工具
    win.webContents.openDevTools();

    win.on('close',function() {
        win = null;
    })
});

app.on('window-all-closed',function() {
    app.quit();
});

窗口(win1) index.html 文件内容如下:

<h1>win1</h1>
<button id="makeNewWindow">创建新窗口win2</button>
<button id="sendMsg">向窗口win2发送消息</button>
<script>

    const remote = require('@electron/remote');
    const { ipcRenderer } = require('electron');

    // 在渲染进程中创建一个新的窗口(win2)
    document.querySelector('#makeNewWindow').addEventListener('click', function () {
        win2 = new remote.BrowserWindow({
            webPreferences: {
                nodeIntegration: true,
                contextIsolation: false
            }
        });
        win2.loadFile('win2.html');
        win2.webContents.openDevTools();

        // 获取 窗口(win2) 的 webContents.id 并通过 ipcRenderer.sendTo 方法发送消息至 win2
        document.querySelector('#sendMsg').addEventListener('click', () => {
            ipcRenderer.sendTo(win2.webContents.id,'msg_win2', { name: 'xiaom' }, { name: 'xiaoh' });
        });
    });

</script>

窗口(win2) win2.html 文件内容如下:

<h1>win2</h1>
<script>
    const { ipcRenderer } = require('electron');

    // 接收 窗口(win1) 发送来的消息
    ipcRenderer.on('msg_win2', (event, param1, param2) => {
        console.log(param1);
        console.log(param2);
        console.log(event.sender);
    });
</script>

结果展示:

结果展示

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

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

相关文章

OSError: image file is truncated (36 bytes not processed)解决方案

错误原因&#xff1a; 图像文件被损坏 解决方案&#xff1a; 代码开头添加如下两行代码&#xff1a; from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES True

[华为OD] B卷 树状结构查询 200

题目&#xff1a; 通常使用多行的节点、父节点表示一棵树&#xff0c;比如 西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲 输入一个节点之后&#xff0c;请打印出来树中他的所有下层节点 输入描述 第一行输入行数&#xff0c;下面是多行数据&#xff0c;每行以空…

远程开机与远程唤醒BIOS设置

远程开机与远程唤醒BIOS设置 在现代计算机应用中&#xff0c;远程管理和控制已成为许多企业和个人的基本需求。其中&#xff0c;远程开机和远程唤醒是两项非常实用的功能。要实现这些功能&#xff0c;通常需要在计算机的BIOS中进行一些特定的设置。以下是对远程开机和远程唤醒…

《深入解析阿里电商:数据中台与业务的双中台系统架构》

阿里巴巴作为全球领先的电商巨头&#xff0c;其技术架构一直是业界关注的焦点。特别是阿里电商的双中台系统架构——数据中台和业务中台&#xff0c;这两个平台在提升数据处理效率和业务响应速度方面起到了至关重要的作用。本文将深入探讨这一架构的设计理念、核心组件及其在实…

Androidstudio报错

现象&#xff1a; org.gradle.api.plugins.UnknownPluginException: Plugin [id: ‘com.android.application‘ 解决 方案&#xff0c;看是不是工具处于离线环境&#xff0c;是的话打开联网就好

【新手指南】Android Studio中应用App的相关配置

前言&#xff1a; 注意这是一个对于Android开发入门学习者而言的一个教程&#xff0c;因为自己平时很少使用Android进行原生应用的开发&#xff0c;对于使用Android Studio配置Android App应用的一些参数&#xff08;如版本号&#xff0c;应用包名&#xff0c;应用图标&#x…

MySQL变量的声明与使用

MySQL变量的声明与使用 1、标识符不能以数字开头 2、自能使用_或$符号&#xff0c;不允许使用其他符号。 3、不允许使用系统关键字 将赋值与查询结合 set userName 刘德华; select userName: 刘青云; # 将赋值与查询结合 查询变量/使用变量 select userName as 读取到的u…

Python批量备份华为设备配置到FTP服务器

Excel表格存放交换机信息&#xff1a; 备份文件夹效果图&#xff1a; Windows系统配置计划任务定时执行python脚本&#xff1a; Program/script&#xff1a;C:\Python\python.exe Add arguments (optional)&#xff1a; D:\Python_PycharmProjects\JunLan_pythonProje…

[C/C++] -- DFS搜索迷宫路径

设计一个程序&#xff0c;能够对给定的迷宫进行路径搜索&#xff0c;并输出一条从起点到终点的路径。具体来说&#xff0c;程序需要实现以下功能&#xff1a; 接受用户输入的迷宫地图&#xff0c;包括迷宫的行数和列数&#xff0c;以及每个格子的状态&#xff08;0 表示可通行…

十四五”智慧城市:视频大数据汇聚系统2.0建设方案与特点分析

一、背景需求分析 随着科技的不断发展&#xff0c;智慧城市的建设已经成为城市发展的重要方向。视频汇聚系统作为智慧城市建设的重要组成部分&#xff0c;已经得到了广泛的应用和推广。视频汇聚系统是智慧城市中非常重要的组成部分&#xff0c;它利用摄像头和传感器技术来收集…

Python | Leetcode Python题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; class Solution:def removeDuplicates(self, nums: List[int]) -> int:idx, left, right 0, 0, 0while left < len(nums):nums[idx] nums[left]idx 1while right < len(nums) and nums[right] nums[left]:right 1if right - …

【深度学习】时空图卷积网络(STGCN),预测交通流量

论文地址&#xff1a;https://arxiv.org/abs/1709.04875 Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic Forecasting 文章目录 一、摘要二、数据集介绍美国洛杉矶交通数据集 METR-LA 介绍美国加利福尼亚交通数据集 PEMS-BAY 介绍美国…

ASP.NET校园新闻发布系统的设计与实现

摘 要 校园新闻发布系统是在学校区域内为学校教育提供资源共享、信息交流和协同工作的计算机网络信息系统。随着网络技术的发展和Internet应用的普及&#xff0c;互联网已成为人们获取信息的重要来源。由于现在各大学校的教师和学生对信息的需求越来越高&#xff0c;校园信息…

SQL优化详解

目录 插入数据 insert的优化&#xff08;少量数据&#xff09; 批量插入 手动事务提交 主键顺序插入 插入大量数据 主键优化 数据组织方式&#xff1a; 页分裂&#xff1a; 主键顺序插入的方式&#xff1a; 主键乱序插入&#xff1a; 页合并&#xff1a; 主键设计…

软件技术主要学什么课程

软件技术专业主要学习的课程和内容有编程语言、数据结构与算法、数据库技术等&#xff0c;以下是上大学网( www.sdaxue.com)整理的软件技术主要学什么课程&#xff0c;供大家参考&#xff01; 编程语言&#xff1a;掌握一种或多种编程语言&#xff0c;如C#、Java、Python、C等&…

EdgeOne 免费证书快速实现网站 HTTPS 访问

在当今互联网环境下&#xff0c;HTTPS访问已经成为现代网站的必备功能。HTTPS 访问不仅能够更有效地保障用户在访问到网站时的数据安全传输&#xff0c;防止信息泄露、消息劫持等问题&#xff0c;在搜索引擎中&#xff0c;未实现 HTTPS 还会被浏览器提示为不安全网站&#xff0…

Windows平台PyCharm之PySide6开发环境搭建与配置

PySide6 是一个用于创建跨平台 GUI 应用程序的库&#xff0c;它是 Qt for Python 的官方库。Qt 是一个跨平台的 C 应用程序框架&#xff0c;用于开发具有图形用户界面&#xff08;GUI&#xff09;的应用程序。PySide6 允许开发者使用 Python 语言访问 Qt 的功能&#xff0c;从而…

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2 1、 Flyer[0].step() Flyer[1].step() Dev.step(4)2、 for i in range(2):Flyer[i].step()Dev.step(2)Dev.turnLeft() Flyer[0].step(2) Dev.step(2)3、 for i in range(2):Flyer[i * 2 1].step()Dev.step(-i - 2)Dev.tu…

OpenAI 发布 AI 生成图片检测器;Meta 推出 AI 广告创意工具;Google 正式发布 Pixel 8a,主打 AI

OpenAI 发布 AI 生成图片检测器 OpenAI 昨日官宣推出专用的 AI 监测工具&#xff0c;用于监测图片是否由其旗下 AI 图片生成工具 DALL-E 生成&#xff0c;准确率高达 98.8%。 不过该公司表示&#xff0c;这个检测工具并非旨在检测 Midjourney 和 Stability 等其他流行生成器生…

QAnything 在mac M2 上纯python环境安装使用体验(避坑指南)

这是一篇mac m2本地纯python环境安装 qanything的文章。安装并不顺利&#xff0c;官方提供的模型无法在本地跑。 这篇文章记录了&#xff0c;使用xinference来部署本地模型&#xff0c;并利用openAi的通用接口的方式&#xff0c;可以正常使用。 记录了遇到的所有的问题&#xf…