使用Electron的dialog模块实现一个本机打开文件对话框
促进主进程和渲染器进程之间的通信
将功能从主进程暴露给渲染器进程
使用Electron的remote模块从主进程导入功能到渲染器进程
使用webContents模块将信息从主进程发送到呈现器进程,并使用ipcRenderer模块为来自主进程的消息设置监听器
在前一章中,我们为第一个Electron项目打下了基础,这是一个笔记应用程序,它从左窗格中取出Markdown,并在右窗格中将其呈现为HTML。我们设置了主进程并将其配置为生成一个呈现器。我们建立了package.json,安装了必要的依赖项,创建了主进程和呈现器进程,并布置了UI。我们还探索了使我们的应用程序看起来像桌面应用程序的方法,但是我们还没有添加一个传统web应用程序所不能做的功能。
现在,应用程序允许用户在Markdown视图中编写。当用户在Markdown视图中按下一个键,应用程序将自动呈现Markdown为HTML并在HTML视图中显示它。
在本章中,我们将添加触发本机文件对话框的功能,并从文件系统上的任何位置选择文本文件并将其加载到应用程序中。在这章的最后,渲染进程的浏览器窗口中的“打开文件”按钮将从主进程触发“打开文件”对话框。在此之前,有必要更深入地讨论一下如何在进程之间进行通信。我们从第3章的分支开始,可以在第三章代码找到它。本章末尾的代码可以在第四章代码-使用本机文件对话框和帮助进程间沟通中找到。或者,您可以下拉主分支并检出这两个分支中的任何一个。
git clone https://github.com/sanshengshui/AUG git checkout -f 第4章-使用本机文件对话框和帮助进 程间通讯 触发本机文件对话框开始的一个简单方法是,当应用程序第一次启动并发出ready事件时,提示用户打开一个文件,如图4.1所示。在创建BrowserWindow实例之前,应用程序已经在侦听ready事件。本章稍后,我们将学习如何从UI触发此功能。在下一章中,我们还将学习如何从应用程序菜单中触发它。
图4.1 我们的应用程序将在启动时触发“打开文件”对话框。到本章结束时,此功能将被从UI触发对话框的功能所取代。
您可以使用Electron dialog模块创建本机对话框。将清单4.1中的代码添加到app/main.js中,就在需要其他Electron模块的地方。
列表4.1 导入dialog模块
const { app, BrowserWindow, dialog } = require('electron');最终,应用程序能从多个位置触发文件打开功能。第一步是创建一个稍后要引用的函数,首先,将选择的文件名称打印到控制台。
列表4.2 创建一个getFileFromUser()函数: ./app/main.js
const getFileFromUser = () => { const files = dialog.showOpenDialog({ //触发操作系统的OpenFile对话框。我们还将不同配置参数的JavaScript对象传递给函数。 properties: ['openFile'] //配置对象在“打开文件”对话框中设置不同的属性。 }); if (!files) { return; } //如果没有任何文件,请尽早从函数中返回。 console.log(files); //将文件打印到控制台 };我们的getFileFromUser()函数是dialog.showOpenDialog()的一个包装器,我们可以在应用程序的多个地方使用而无需重复。它将触发dialog上的showOpenDialog()方法,并传递一个JavaScript对象,该对象具有不同的设置,我们可以根据需要进行调整。在JavaScript中,对象的键称为其属性。我们正在创建的对话框的某些特性需要传递给dialog.showOpenDialog()配置的对象属性。其中一个设置是对话框本身的属性,配置对象上的properties属性接受我们可以在对话框上设置的不同标志的数组。在本例中,我们只激活openFile标志,它表示此对话框用于选择要打开的文件,而不是选择多个目录或多个文件。其他可用的标志是openDirectory和multiselection。
dialog.showOpenDialog()返回所选文件的名称,用户选择的路径数组存储在名为files的变量中。如果用户按下取消,如果我们试图在未定义的情况下调用文件的任何方法,dialog.showOpenDialog()将返回未定义的并中断。
必须在应用程序的某个地方调用getFileFromUser()来触发对话框。最终,它将从UI和应用程序菜单中调用。现在,一个方便的地方是应用程序中启动时,当应用程序模块触发它的ready事件时调用getFileFromUser()。如下面的清单所示,当我们的UI被配置为从渲染器进程中触发getFileFromUser()时,这个步骤将被删除。
列表4.3 在应用程序第一次准备好时调用getFileFromUser()
app.on('ready', () => { mainWindow = new BrowserWindow({ show: false }); mainWindow.loadFile('app/index.html'); mainWindow.once('ready-to-show', () => { mainWindow.show(); getFileFromUser(); //当窗口准备显示时,我们将调用getFileFromUser(),getFileFromUser()在清单4.2中定义 }); mainWindow.on('closed', () => { mainWindow = null; }); });