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

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('自定义标题', '当前错误内容')

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序问题

1.获取节点 wx.createSelectorQuery() wx.createSelectorQuery().in(this) //组件中加in(this),不然获取不到 2.使用实例 wx.createSelectorQuery().in(this).select(#share).fields({node: true,size: true}).exec(async (res) > {const canvas res[0].node;…

【栈和队列OJ题】

栈和队列OJ题 文章目录 栈和队列OJ题1. 用队列实现栈2. 用栈实现队列3. 括号匹配问题4. 循环队列 1. 用队列实现栈 OJ链接:225. 用队列实现栈 - 力扣(LeetCode) 好的,我们一起来看一下题目,题目是这样说的 思路&…

【斯坦福因果推断课程全集】2_无混淆和倾向分1

目录 Beyond a single randomized controlled trial Aggregating difference-in-means estimators Continuous X and the propensity score 随机试验的一个最简单的扩展是无约束下的干预效果估计。从定性上讲,当我们想估计一种并非随机的治疗效果,但一…

PyTorch | 加速模型训练的妙招

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

mybatis的拦截器

文章目录 第三个是参数拦截器第四个是结果集拦截器mybatis拦截器-笔试题1.笔试题 JDBC的执行流程3.执行sql语句,返回执行结果 mybatis的四种拦截器 第一个是执行拦截器: Executor(执行器拦截器): 用途:拦截MyBatis执行器方法的…

AI版Siri要明年见,研究表明ChatGPT暂无法取代程序员,Kimi推出浏览器插件

ChatGPT狂飙160天,世界已经不是之前的样子。 更多资源欢迎关注 根据彭博社记者马克古尔曼的最新消息,苹果公司今年不会推出全新的Apple Intelligence驱动的Siri,该公司计划在明年1月开始测试,并在iOS 18.4中才推出正式版本。 此前…

未来工业革命:区块链在工业4.0中的角色与应用

随着科技的迅猛发展,人类社会正在逐步迈向工业4.0时代。在这一新时代的背景下,区块链技术作为一种创新性的分布式账本技术,正逐步在工业领域展示其独特的价值和潜力。本文将深入探讨区块链在工业4.0中的角色与应用,分析其对工业生…

windows安装Docker Desktop及国内镜像

简介 Docker 是一个开源的应用容器引擎,它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。通过Docker工具,简化了应用的部署、配置和管理过程,提高…

dataX入门

下载dataX https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz 然后 下载后解压至本地某个目录,进入bin目录,即可运行同步作业: $ cd {YOUR_DATAX_HOME}/bin $ python datax.py {YOUR_JOB.json} 要求你有python…

FPGA上板项目(一)——点灯熟悉完整开发流程、ILA在线调试

目录 创建工程创建 HDL 代码仿真添加管脚约束添加时序约束生成 bit 文件下载ILA 在线调试 创建工程 型号选择:以 AXU9EG 开发板为例,芯片选择 xczu9eg-ffvb1156-2-i 创建 HDL 代码 注意:由于输入时钟为 200MHz 的差分时钟,因此…

【Python】已解决:ModuleNotFoundError: No module named ‘nltk’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:ModuleNotFoundError: No module named ‘nltk’ 一、分析问题背景 在使用Python进行自然语言处理或文本分析时,我们经常会用到各种库来辅助我们的工…

【ACM 独立出版,高录用EI稳检索】2024年大数据与数字化管理国际学术会议 (ICBDDM 2024,8月16-18)

2024年大数据与数字化管理国际学术会议 (ICBDDM 2024),将于2024年8月16-18日在中国上海召开。 “大数据与数字化管理”作为会议主题,旨在聚焦这一跨学科领域中最新的理论研究、技术进展、实践案例和未来趋势。本主题探讨的研究方向涵盖了大数据的收集、…

GD32F303RET6读取SGM58031电压值

1、SGM58031芯片详解 (1)SGM58031是一款低功耗,16位精度,delta-sigma (ΔΣ)模数转换器(ADC)。它从3V到5.5V供电。 (2)SGM58031包含一个片上参考和振荡器。它有一个I2C兼容接口,可以选择四个I2…

15、电科院FTU检测标准学习笔记-基本性能

作者简介: 本人从事电力系统多年,岗位包含研发,测试,工程等,具有丰富的经验 在配电自动化验收测试以及电科院测试中,本人全程参与,积累了不少现场的经验 ———————————————————…

Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇

Nginx七层(应用层)反向代理 SCGI代理scgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this art…

利用Altair One 云平台,轻松实现全球企业产品研发创新与优化

在过去的几十年里,工程师和数据科学家引入了大量改变世界的技术,但他们的工作方式却出人意料地停滞不前。技术的革新也带来了效率的不断提升。 面对众多企业的同样难题,Altair整合产品,创造出了用于协作工程、数据工程和分析应用程…

数列分块<2>

本期是数列分块入门<2>。该系列的所有题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:http://hzwer.com/8053.html sto hzwer orz %%% [转载] 好像上面的链接↑打不开&#xff0c;放一个转载:https://www.cnblogs.…

【C++】C++-机房收费管理系统(源码+注释)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

RK3568平台开发系列讲解(内存篇)Linux进程内存的消耗统计

🚀返回专栏总目录 文章目录 一、VSS(Virtual Set Size)二、RSS(Resident Set Size)三、PSS(Proportional Set Size)四、USS(Unique Set Size)五、其他工具Linux 提供了多种进程内存占用的度量指标, 它们反映了不同的内存使用特征: VSS 反映进程虚拟内存总需求, 包括未…

Oracle基础以及一些‘方言’(一)

1、什么是Oracle ORACLE数据库系统是美国ORACLE公司&#xff08;甲骨文&#xff09;提供的以分布式数据库为核心的一组软件产品&#xff0c;是最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一。 ORACLE 通常应用于大型系统的数据库产品。 ORACLE 数据库是目前世界…