探索 Electron:窗口菜单以及生命周期和对话框讲解

news2024/11/13 8:52:40

Electron是一个开源的桌面应用程序开发框架,它允许开发者使用Web技术(如 HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序,它的出现极大地简化了桌面应用程序的开发流程,让更多的开发者能够利用已有的 Web 开发技能来构建功能强大且跨平台的应用程序,这对于提升开发效率和应用程序的快速交付具有重要意义。

目录

窗口操作

自定义菜单

主进程生命周期

dialog对话框


窗口操作

在Electron中,窗口操作是非常重要的,开发者可以通过一些核心API来管理和控制应用程序窗口的行为,以下是对窗口内容的一些常见操作:

设置大小与位置:通过如下代码设置窗口的初始大小与在桌面的初始位置:

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800, // 设置窗口初始大小
        height: 600, 
        x: 100, // 设置窗口初始位置
        y: 100,
        maxWidth: 1000, // 设置窗口最大最小宽高
        maxHeight: 800,
        minWidth: 500,
        minHeight: 400,
        resizable: false, // 设置窗口是否可以拖动改变大小,默认是true,设置false不允许进行窗口缩放了
    })
    win.loadFile('./src/index.html') // 加载页面
}

解决首页加载白屏: 在我们创建完窗口之后,窗口里面是没有加载内容的,内容是放在加载本地页面或者外部链接页面完成的,由于内容的加载和窗体的显示是异步执行不是同步的,所以可能看到类似于首屏加载会出现白屏的现状,这里我们可以采用下面的方式解决:

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600,
        show: false, // 隐藏窗口,默认是true
        x: 100,
        y: 100
    })
    win.loadFile('./src/index.html') // 加载页面
    win.on('ready-to-show', () => { // 窗口准备就绪后,显示窗口
        win.show()
    })
}

窗口标题:如果想自定义窗口标题的话,可以将index.html中的title删除掉,采用如下的方式:

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800, 
        height: 600, 
        icon: 'logo.png', 
        title: "亦世凡华、"
    })
    win.loadFile('./src/index.html') // 加载页面
}

如果想去掉窗口标题和菜单的话可以采用如下方式frame去掉边框,去掉之后窗口不再能拖动了,当然也可以设置窗口透明,不过很少用:

当然如果想隐藏掉原本自带的导航栏可以采用如下的属性进行:

自定义菜单

如果想对electron进行自定义菜单的设置的话,可以采用如下的方式进行,通过自定义菜单选项,设置一级二级菜单,让给菜单设置回调事件来实现菜单的自定义:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow, Menu } = require('electron')

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800, 
        height: 600, 
        icon: 'logo.png', 
        title: "亦世凡华、",
    })
    win.loadFile('./src/index.html') // 加载页面
}

// 自定义菜单选项
let menuTemp = [
    { label: '文件', submenu: [
        { label: '打开文件', click() {
            console.log("打开文件")
        } },
        { type: 'separator' }, // 添加一个分割线
        { label: '关闭文件夹' },
        { label: '关于', role: 'about' },
    ] },
    { label: '编辑' },
]
// 利用上述的模板生成一个菜单选项
const menu = Menu.buildFromTemplate(menuTemp)
// 将上述的自定义菜单添加到应用里面
Menu.setApplicationMenu(menu)

// 监听app的ready事件,当应用加载完成的时候,创建窗口
app.on('ready', () => {
    createWindow()
})

得到的效果如下所示:

当然菜单本身的role属性还分配了不同的角色,这里就不再一一赘述了,通过如下代码进行一个简单的演示:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow, Menu } = require('electron')

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800, 
        height: 600, 
        icon: 'logo.png', 
        title: "亦世凡华、",
    })
    // 自定义菜单选项
    let menuTemp = [
        {
            label: '角色',
            submenu: [
                { label: '复制', role: 'copy' },
                { label: '剪切', role: 'cut' },
                { label: '粘贴', role: 'paste' },
                { label: '最小化', role: 'minimize' }
            ]
        },
        {
            label: '类型',
            submenu: [
                { label: '选项1', type: 'checkbox' },
                { label: '选项2', type: 'checkbox' },
                { label: '选项3', type: 'checkbox' },
                { type: 'separator' },
                { label: 'item1', type: 'radio' },
                { label: 'item2', type: 'radio' },
                { type: 'separator' },
                { label: 'windows', type: 'submenu', role: 'windowMenu' },
            ]
        },
        {
            label: '其它',
            submenu: [
                {
                    label: '退出',
                    width: 80,
                    height: 60,
                    // icon: 'logo.png',
                    accelerator: 'CmdOrCtrl+Q', // 快捷键
                    click() {
                        app.quit()
                    }
                }
            ]
        }
    ]
    // 利用上述的模板生成一个菜单选项
    const menu = Menu.buildFromTemplate(menuTemp)
    // 将上述的自定义菜单添加到应用里面
    Menu.setApplicationMenu(menu)
    win.loadFile('./src/index.html') // 加载页面
}

// 监听app的ready事件,当应用加载完成的时候,创建窗口
app.on('ready', () => {
    createWindow()
})

// 当所有的窗口都被关闭时,并且还不是苹果系统,则直接退出程序
app.on('window-all-closed', () => {
    console.log("第四步: window-all-closed-所有窗口都被关闭了")
    app.quit() // 退出程序
})

最终呈现的效果如下所示:

主进程生命周期

Electron应用程序的生命周期涉及到整个应用程序从启动到关闭的各个阶段和事件,这些阶段包括主进程和渲染进程的不同生命周期事件,以下是一个简要的概述:

应用程序启动:当应用程序启动时,主进程开始执行,并触发app模块的ready事件,在这一阶段,通常进行应用程序的初始化设置:

窗口创建与关闭:主进程通过创建窗口实例来展示用户界面,窗口的创建和关闭触发了一系列事件,如browser-window模块的ready-to-show、closed等事件:

应用程序激活和休眠:当应用程序从后台切换到前台时,会触发activate事件,应用程序进入休眠状态时,可以监听before-quit事件进行必要的清理工作:

退出应用程序:用户关闭所有窗口或者通过代码触发退出时,会触发window-all-closed和will-quit事件,允许应用程序执行最后的清理操作:

接下来我们通过代码对主进程生命周期进行一个简单的梳理:

// app应用;BrowserWindow 窗口
const { app, BrowserWindow } = require('electron')

const createWindow = () => {
    const win = new BrowserWindow({ // 窗口的配置
        width: 800,
        height: 600,
        autoHideMenuBar: true, // 自动隐藏菜单栏
    })
    win.loadFile('./src/index.html') // 加载页面

    win.webContents.on('did-finish-load', () => { // 页面加载完毕后,执行回调函数
        console.log("第三步: did-finish-load-页面加载完毕")
    })
    win.webContents.on('dom-ready', () => { // 页面dom加载完毕后,执行回调函数
        console.log("第二步: dom-ready-dom加载完毕")
    })

    win.on('closed', () => { // 窗口关闭时,销毁窗口对象
        console.log("第八步: closed-窗口被销毁了")
    })
}

// 当app准备完毕,创建窗口
app.on('ready', () => {
    console.log("第一步: ready-app准备完毕")
    createWindow()
})

// 当所有的窗口都被关闭时,并且还不是苹果系统,则直接退出程序
app.on('window-all-closed', () => {
    console.log("第四步: window-all-closed-所有窗口都被关闭了")
    app.quit() // 退出程序
})
app.on('before-quit', () => {
    console.log("第五步: before-quit-准备退出程序")
})
app.on('will-quit', () => {
    console.log("第六步: will-quit-即将退出程序")
})
app.on('quit', () => {
    console.log("第七步: quit-退出程序")
})

从上文代码可以看出,所谓的app的生命周期就是我们在桌面上点击一个图标,那么app就会启动,启动完成之后会进行一些初始化操作,所以这里就需要ready准备,准备完成之后app就需要给我们进行展示特定界面也就是窗口,窗口有了之后它里面的dom元素就会进行dom-ready加载,页面加载完成然后我们再点击其中导航栏中的某个选项,这个时候某个选项dom加载完成之后会触发did-finsh-load的执行,点击关闭app窗口之后会执行closed,关闭所有窗口window-all-closed函数会被执行。

以下是具体的函数代码流程:

1)ready:app初始化完成

2)dom-ready:一个窗口中的文本加载完成

3)did-finsh-load:导航完成时触发

4)window-all-closed:所有窗口都被关闭时触发

5)before-quit:在关闭窗口之前触发

6)will-quit:在窗口关闭并且应用退出时触发

7)quit:当所有窗口被关闭时触发

8)closed:当窗口关闭时触发,此时应删除窗口引用

dialog对话框

在electron中dialog对话框可以显示用于打开和保存文件、警报等的本机系统对话框。这里对常用的dialog对话框函数进行一个简单的代码讲解:

showOpenDialog:用于显示一个打开文件或目录的对话框,让用户进行文件选择操作。

dialog.showOpenDialog({
    buttonLabel: '选择', // 设定对话框中选择按钮的显示文本为“选择”
    defaultPath: app.getPath('desktop'), // 设定默认路径为桌面
    properties: ['multiSelections','createDirectory','openFile','openDirectory'] // 设定选择类型为多选、新建文件夹、打开文件、打开文件夹
}).then((result)=> {
    console.log(result.filePaths) // 将用户选择的文件路径数组打印到控制台,以便开发者查看或进一步处理这些路径。
})

showSaveDialog:用于显示一个保存文件的对话框,并进行相应的操作。

dialog.showSaveDialog({
    title: "保存文件",
    defaultPath: 'test.txt' // 默认路径
}).then(res => {
    console.log("第一步: dialog.showSaveDialog", res)
})

showMessageBox:用于显示一个消息框并接收用户的选择。

const answers = ['Yes','No','Maybe']
dialog.showMessageBox({
    title: 'Message Box',
    message: 'Please select an option',
    detail: 'Message details',
    buttons: answers,
}).then(({ response }) => {
    console.log(`User selected ${answers[response]}`)
})

showErrorBox:用于显示一个简单的错误提示框。

dialog.showErrorBox('自定义标题', '当前错误内容')

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

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

相关文章

Linux文件编程(标准C库)

目录 一、标准C库打开/创建文件,读写文件,光标移动 二、标准C库写入结构体到文件 三、其他函数补充 1.fputc函数 2.feof函数和fgetc函数 前面讲到的open函数都是基于linux内核的,也就是说在Windows系统上无法运行,移植性比较…

shein测试开发会问些啥?

🏆本文收录于《CSDN问答解惑-》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&…

【thingsbord源码编译】 显示node内存不足

编译thingsbord显示报错 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory问题原因分析 重新安装java版本 编译通过

论文阅读【时空+大模型】ST-LLM(MDM2024)

论文阅读【时空大模型】ST-LLM(MDM2024) 论文链接:Spatial-Temporal Large Language Model for Traffic Prediction 代码仓库:https://github.com/ChenxiLiu-HNU/ST-LLM 发表于MDM2024(Mobile Data Management&#xf…

无人机之遥控器保养

一、使用存放 1、避免让遥控器受到强烈的震动或从高处跌落,以免影响内部结构的精度; 2、遥控器在使用完后,需要将天线收拢,避免折断,养成定期检查天线的习惯; 3、定期检查遥控器按键有无裂纹、畸变、松旷…

跨境电商API的全球视野:打破地域限制,连接全球消费者与商家

在全球化日益加深的今天,跨境电商已成为推动全球经济一体化的重要力量。它不仅为消费者提供了前所未有的购物体验,让世界各地的商品触手可及,更为商家开辟了全新的市场蓝海,实现了业务的全球化拓展。在这一进程中,跨境…

PyTorch | 加速模型训练的妙招

引言 提升机器学习模型的训练速度是每位机器学习工程师的共同追求。训练速度的提升意味着实验周期的缩短,进而加速产品的迭代过程。同时,这也表示在进行单一模型训练时,所需的资源将会减少。简而言之,我们追求的是效率。 熟悉 PyT…

Rust代码优化的九大技巧

一.使用 Cargo 内置的性能分析工具 描述:Cargo 是 Rust 的包管理器,带有内置工具来分析代码性能,以识别性能瓶颈。 解释: 发布模式:在发布模式下编译启用优化,可以显著提高性能。 cargo build --release基…

解决vue多层弹框时存在遮挡问题

本文给大家介绍vue多层弹框时存在遮挡问题,解决思路首先想到的是找到对应的遮挡层的css标签,然后修改z-index值,但是本思路只能解决首次问题,再次打开还会存在相同的问题,故该思路错误,下面给大家带来一种正…

【鸿蒙学习笔记】文件管理

官方文档:Core File Kit简介 目录标题 文件分类什么是应用沙箱? 文件分类 应用文件,比如应用的安装包,自己的资源文件等。用户文件,比如用户自己的照片,录制的音视频等。 什么是应用沙箱? 应…

完美解决:MySQL8报错:Public Key Retrieval is not allowed

在配置数据源的时候直接将属性allowPublicKeyRetrieval设置为true即可 &AutoReconnecttrue

论文发表作图必备:训练结果对比,多结果绘在一个图片【Precision】【Recall】【mAP0.5】【mAP0.5-0.95】【loss】

前言:Hello大家好,我是小哥谈。YOLO(You Only Look Once)算法是一种目标检测算法,它可以在图像中实时地检测和定位目标物体。YOLO算法通过将图像划分为多个网格,并在每个网格中检测目标物体,从而实现快速的目标检测。本文所介绍的作图教程适用于所有YOLO系列版本算法,接…

Linux Ubuntu MySQL环境安装

1. 更新软件源 首先,确保你的Ubuntu系统已经更新了软件源列表,以便能够下载到最新的软件包。打开终端并输入以下命令: sudo apt update 2. 安装MySQL服务器 打开终端并输入以下命令来安装MySQL服务器 sudo apt install mysql-server 在…

代码随想录算法训练营第五十天| 739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II

739. 每日温度 题目链接: 739. 每日温度 文档讲解:代码随想录 状态:不会 思路: 这道题需要找到下一个更大元素。 使用栈来存储未找到更高温度的下标,那么栈中的下标对应的温度从栈底到栈顶是递减的。这意味着&#xff…

鸿蒙语言基础类库:【@ohos.application.testRunner (TestRunner)】 测试

TestRunner TestRunner模块提供了框架测试的能力。包括准备单元测试环境、运行测试用例。 如果您想实现自己的单元测试框架,您必须继承这个类并覆盖它的所有方法。 说明: 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-…

5款常用的漏洞扫描工具,网安人员不能错过!

漏洞扫描是指基于漏洞数据库,通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测,发现可利用漏洞的一种安全检测的行为。 在漏洞扫描过程中,我们经常会借助一些漏扫工具,市面上漏扫工具众多,其中有一…

windows环境下基于3DSlicer 源代码编译搭建工程开发环境详细操作过程和中间关键错误解决方法说明

说明: 该文档适用于  首次/重新 搭建3D-Slicer工程环境  Clean up(非增量) 编译生成 1. 3D-slicer 软件介绍 (1)3D Slicer为处理MRI\CT等图像数据软件,可以实行基于MRI图像数据的目标分割、标记测量、坐标变换及三维重建等功能,其源于3D slicer 4.13.0-2022-01-19开…

新火种AI|微软和苹果放弃OpenAI董事会观察员席位

作者:一号 编辑:美美 微软苹果双双不做OpenAI“观察员”,OpenAI能更自由吗? 7月10消息,微软当地时间周一宣布将放弃在OpenAI董事会的观察员席位,他们称,OpenAI在过去八个月中取得了“重大进展…

Java(十八)---单链表

文章目录 前言1.链表的概念及结构2.单链表的创建3.功能的实现3.1.创建链表(create)(需要自己创建)3.2.显示链表(display)3.3.获取链表的个数( size() )3.4.是否包含指定元素(contains)3.5.头插法(addFirst)3.6.尾插法(addLast)3.7.在指定位置进行插入(addIndex)3.8.删除出现在第…

基于Spring Boot的高校后勤餐饮管理系统

1 项目介绍 1.1 研究背景 “互联网”时代的到来,既给高校后勤管理发展带来了机遇,也带来了更大的挑战。信息化应用已经开始普及,传统的高校后勤餐饮管理模式往往存在着效率低下、信息不透明、资源浪费等问题,已经难以满足现代高…