前一段时间我用 WPF 开发了一个查看 emoji 表情的小工具 https://github.com/he55/EmojiViewer ,由于最近我使用 macOS 系统比较多,我想能在 macOS 系统上也能使用这个工具。于是我尝试将 WPF 应用迁移到 Electron 框架,感觉这个框架很强大,在这里记录一下应用迁移的过程。

安装 Electron 环境

  • 安装 nodejs。到官网 https://nodejs.org/en 下载最新的 nodejs,然后安装

  • 打开命令行输入 git clone https://github.com/electron/electron-quick-start.git 命令克隆 Electron 模板项目,使用模板可以快速搭建应用。
  • 然后使用 cd electron-quick-start 目录进入到目录,接着运行 npm install 命令还原项目。
  • 使用 vscode 打开文件夹,项目文件如下

编写代码

  • Electron 分为主进程和渲染进程,对文件、系统和窗口的操作需要在主线程,界面渲染在渲染进程。创建窗口属于主进程的工作,需要到 main.js 文件编写代码。创建窗口使用 BrowserWindow 对象,widthheight 分别设置窗口宽度和高度,autoHideMenuBar 设置是否隐藏菜单,最后使用 loadFile 加载页面文件并显示窗口。
function createWindow() {
const mainWindow = new BrowserWindow({
width: 915,
height: 560,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
}) mainWindow.loadFile('index.html')
}
  • 监听 whenReady 事件,等待应用初始化完成后显示窗口
app.whenReady().then(() => {
createWindow() app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
  • 修改 index.html 文件,界面部分使用了 vue 进行渲染
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<script src="vue.global.js"></script>
<link href="./styles.css" rel="stylesheet">
<title>EmojiViewer</title>
</head> <body>
<div id="app" class="container">
<ul class="left">
<li v-for="(item, key) in categories" :class="{active: item.isActive}" @click="catetoryItemClick(item)">{{ key }}</li>
</ul>
<ul class="main" ref="mainElement">
<li v-for="emoji in emojis" :class="{active: emoji.isActive}" @click="emojiItemClick(emoji)">
<img :src="emoji.previewImage" alt="">
<p>{{emoji.name}}</p>
</li>
</ul>
<div class="right">
<img :src="selectedEmoji.previewImage">
<p>{{ selectedEmoji.name }}</p>
<button @click="copyEmoji(selectedEmoji)" type="button">Copy Emoji</button>
<button @click="copyImage(selectedEmoji)" type="button">Copy Image</button>
<button @click="openFile(selectedEmoji)" type="button">Open File</button>
</div>
</div> <script src="./renderer.js"></script>
</body> </html>
  • renderer.js 文件中编写页面处理代码
window.addEventListener('DOMContentLoaded', async () => {
const { createApp, ref, onMounted } = Vue
let emojiData = await ipc.getData() createApp({
setup() {
const mainElement = ref(null) const categories = ref(emojiData)
const emojis = ref([])
const selectedEmoji = ref({}) function copyEmoji(emoji) {
ipc.ipc('writeText', emoji.metadata.glyph)
}
function copyImage(emoji) {
ipc.ipc('writeImage', emoji.previewImage)
}
function openFile(emoji) {
ipc.ipc('showItemInFolder', emoji.previewImage)
} let lastSelectedEmojis
function catetoryItemClick(items) {
if (lastSelectedEmojis) {
lastSelectedEmojis.isActive = false
} items.isActive = true
lastSelectedEmojis = items // const main = document.querySelector('.main')
mainElement.value.scrollTop = 0
emojis.value = items
} function emojiItemClick(emoji) {
if (selectedEmoji.value) {
selectedEmoji.value.isActive = false
} emoji.isActive = true
selectedEmoji.value = emoji
} onMounted(() => {
catetoryItemClick(emojiData['Activities'])
emojiItemClick(emojiData['Activities'][0])
}) return {
mainElement,
categories,
emojis,
selectedEmoji,
catetoryItemClick,
emojiItemClick,
copyEmoji,
copyImage,
openFile,
}
}
}).mount('#app')
})
  • 读取文件,node 提供了文件操作相关的 api 可以很方便的操作文件系统。
function loadData(assetPath) {
const dirs = fs.readdirSync(assetPath)
const data = []
const groupData = {}
for (const dir of dirs) {
const fullPath = path.resolve(assetPath, dir)
const metadata = require(path.resolve(fullPath, 'metadata.json'))
let previewImage let imagePaths = [path.resolve(fullPath, '3D'), path.resolve(fullPath, 'Default', '3D')]
for (const imagePath of imagePaths) {
if (fs.existsSync(imagePath)) {
let files = fs.readdirSync(imagePath)
if (files.length === 0)
return
previewImage = path.resolve(imagePath, files[0])
}
} const { unicode, group } = metadata
const obj = {
metadata,
id: unicode,
name: dir,
previewImage,
}
data.push(obj) if (!groupData[group])
groupData[group] = []
groupData[group].push(obj)
}
return groupData
}

完整代码(WPF 版本) https://github.com/he55/EmojiViewer

完整代码(vue 版本) https://github.com/he55/web-learn/tree/main/9.electron-emoji-viewer(vue)

完整代码(js 原生版本) https://github.com/he55/web-learn/tree/main/6.electron-emoji-viewer

WPF 应用迁移到 Electron 框架过程记录的更多相关文章

  1. 将ibatis迁移到mybatis3的过程记录

    将ibatis迁移到mybatis3的过程记录 场景:有些以前的老项目是使用ibatis开发的,现在有转换成mybatis3的需求. 环境准备:需要安装Ant,以下是本人的安装版本,具体怎么安装不再赘 ...

  2. 半个前端新手入门Electron的过程

    前言 先说几句废话,本人是一名 web 后端开发,主语言是 java,在学 Electron 之前,只会一点点 HTML和 JavaScript.本文讲的也是我学习 Electron 的过程,而非教程 ...

  3. 将基于 .NET Framework 的 WPF 项目迁移到基于 .NET Core 3

    在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF:同时还发布了 Visual Studio 2019 预览版 ...

  4. 金蝶Apusic中间件适配JetSpeed2过程记录

    金蝶Apusic中间件适配JetSpeed2过程记录: 1.安装金蝶并配置域,确保域运行正常. 2.参考<JetSpeed2部署至Apusic操作步骤记录>进行应用迁移. https:// ...

  5. Electron安装过程深入解析(读完此文解决Electron应用无法启动,无法打包的问题)

    1. 安装Electron依赖包 开发者往往通过npm install(或 yarn add)指令完成为Node.js工程安装依赖包的工作, 安装Electron也不例外,下面是npm和yarn的安装 ...

  6. 升级Windows 10 正式版过程记录与经验

    升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...

  7. 双系统Ubuntu分区扩容过程记录

    本人电脑上安装了Win10 + Ubuntu 12.04双系统.前段时间因为在Ubuntu上做项目要安装一个比较大的软件,导致Ubuntu根分区的空间不够了.于是,从硬盘又分出来一部分空间,分给Ubu ...

  8. .NET 4.5+项目迁移.NET Core的问题记录

    .NET 4.5+项目迁移.NET Core的问题记录 这几天试着把目前的开发框架迁移到新的.net core平台,中间遇到的问题在这里简单记录一下. 迁移过程遇到的最大的问题IOC容器.我目前使用的 ...

  9. SVN迁移到Git的过程(+ 一些技巧)

    SVN迁移到Git的过程(+ 一些技巧) 李顺利 Key Words SVN,Git,Clone,Conversion,Tips,VCS,Pro Git 关于在VCS中SVN和Git之间的迁移(Clo ...

  10. CentOS 5.5 下安装Countly Web Server过程记录

    CentOS 5.5 下安装Countly Web Server过程记录 1. 系统更新与中文语言包安装 2. 基本环境配置: 2.1. NodeJS安装 依赖项安装 yum -y install g ...

随机推荐

  1. python中可变参数与装饰器的例子

    python的可变参数 方法定义 #*args是可以传list类型的可变参数,**kwargs是可以传dict的可变参数 def wrapper(*args, **kwargs): 使用示例 def ...

  2. Go语言的100个错误使用场景(一)|代码和项目组织

    目录 前言 1. Go: Simple to learn but hard to master 1.1 Go 语言概述 1.2 简单不等于容易 1.3 使用 Go 的100个错误 2. Code an ...

  3. C++ STL 标准模板库(非变易/变易)算法

    C++ STL模板是惠普实验室开发的标准开发模板,STL是C++的一部分,STL可分为容器(containers).迭代器(iterators).空间配置器(allocator).配接器(adapte ...

  4. 【分享】从Mybatis源码中,学习到的10种设计模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言:小镇卷码家 总有不少研发伙伴问小傅哥:"为什么学设计模式.看框架源码.补技 ...

  5. 面试官:什么是JIT、逃逸分析、锁消除、栈上分配和标量替换?

    JIT.逃逸分析.锁消除.栈上分配和标量替换等都属于 JVM 的优化手段,JVM 优化手段是指在运行 Java 程序时,通过对字节码的编译和执行过程进行优化,以提升程序的性能和效率. JVM 优化手段 ...

  6. Java并发(五)----线程常见方法总结

    常见方法 方法名 static 功能说明 注意 start()   启动一个新线程,在新的线程运行 run 方法中的代码 start 方法只是让线程进入就绪,里面代码不一定立刻运行(CPU 的时间片还 ...

  7. 开源.NetCore通用工具库Xmtool使用连载 - 发送短信篇

    [Github源码] <上一篇> 介绍了Xmtool工具库中的发送邮件类库,今天我们继续为大家介绍其中的发送短信类库. 发送短信就像发送邮件一样,在软件系统中使用非常普遍,甚至比发送邮件还 ...

  8. NVME(学习笔记_杂谈)

    NVME 协议中一些概念的理解: 1.Namespace :可以将Namespace 理解为一片Logic Block的区域,一个Controller可以支持多个Namespace,每个Namespa ...

  9. java 从零开始手写 redis(十)缓存淘汰算法 LFU 最少使用频次

    前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...

  10. Java并发编程实例--3.打断一个线程

    一般来讲一个java程序如果运行着多个线程,那么只有在这些线程都运行完毕后才会终止. 但有时候,我们需要去结束某个线程或者取消某个任务.此时就用到了Java线程的打断机制,即interruption. ...