Electron - 系统对话框
Electron - 使用系统对话框
Section titled “Electron - 使用系统对话框”桌面应用程序经常需要通过标准的系统对话框与用户交互,例如用于打开文件、保存文件或显示警报和确认的对话框。Electron 的 dialog 模块提供了一种直接的方式来使用这些原生的系统对话框,确保用户体验与操作系统保持一致。
对于这些标准交互,使用原生对话框比使用基于 HTML 的自定义对话框更可取,因为它们是用户熟悉的,并且与操作系统功能集成良好。
dialog 模块
Section titled “dialog 模块”dialog 模块只能在主进程中使用。如果你需要在渲染进程中触发对话框,则必须使用 IPC 请求主进程显示它。大多数 dialog 方法是异步的,并返回 Promise。
我们来创建一个示例应用程序,允许用户打开文本文件并显示其内容。
你的 main.js 文件将处理对话框和文件读取:
const { app, BrowserWindow, ipcMain, dialog } = require('electron');const path = require('path');const fs = require('fs').promises; // Use the promise-based fs module
let mainWindow;
function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js') } }); mainWindow.loadFile('index.html');}
app.whenReady().then(createWindow);
// Handle 'dialog:openFile' IPC message from rendereripcMain.handle('dialog:openFile', async () => { const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, { title: 'Open Text File', properties: ['openFile'], filters: [ { name: 'Text Files', extensions: ['txt', 'md', 'js', 'html', 'css'] }, { name: 'All Files', extensions: ['*'] } ] });
if (canceled || filePaths.length === 0) { console.log('File open dialog canceled or no file selected.'); return null; // Or throw an error, or return an object indicating cancellation }
const filePath = filePaths[0]; try { const content = await fs.readFile(filePath, 'utf-8'); return { filePath, content }; } catch (error) { console.error('Failed to read file:', error); dialog.showErrorBox('Error Reading File', `Could not read file: ${error.message}`); return null; // Or re-throw, or return an error object }});
app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit();});
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow();});创建 preload.js 以向渲染进程暴露 IPC 调用:
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', { openFile: () => ipcRenderer.invoke('dialog:openFile')});以及你的 index.html 文件,用于触发对话框并显示内容:
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>System Dialogs - File Reader</title> <style> body { font-family: sans-serif; margin: 20px; } #fileInfo { margin-bottom: 10px; font-style: italic; } #fileContent { white-space: pre-wrap; border: 1px solid #ccc; padding: 10px; background-color: #f9f9f9; } </style></head><body> <h1>Text File Viewer</h1> <button id="openFileButton">Open File</button> <div id="fileInfo">No file selected.</div> <pre id="fileContent">File content will appear here.</pre>
<script> const openFileButton = document.getElementById('openFileButton'); const fileInfoDiv = document.getElementById('fileInfo'); const fileContentPre = document.getElementById('fileContent');
openFileButton.addEventListener('click', async () => { try { const result = await window.electronAPI.openFile(); if (result && result.content !== null) { fileInfoDiv.textContent = `Displaying: ${result.filePath}`; fileContentPre.textContent = result.content; } else if (result === null) { // Error handled by main process (dialog.showErrorBox) fileInfoDiv.textContent = 'Failed to open or read file.'; fileContentPre.textContent = ''; } else { // Dialog was canceled fileInfoDiv.textContent = 'File open canceled.'; fileContentPre.textContent = ''; } } catch (error) { console.error('Error in renderer trying to open file:', error); fileInfoDiv.textContent = 'An unexpected error occurred.'; fileContentPre.textContent = ''; // Optionally, show a more user-friendly error in the UI } }); </script></body></html>当你运行应用程序(electron .)并点击“Open File”按钮时,将会出现一个原生的文件打开对话框。它的外观将与你操作系统的标准文件对话框一致。选择文本文件后,其内容将显示在应用程序窗口中。
dialog 模块提供几种类型的对话框:
dialog.showOpenDialogSync([browserWindow, ]options)和dialog.showOpenDialog([browserWindow, ]options): 用于打开文件和目录。异步版本返回一个 Promise。dialog.showSaveDialogSync([browserWindow, ]options)和dialog.showSaveDialog([browserWindow, ]options): 用于提示用户选择保存文件的路径。异步版本返回一个 Promise。dialog.showMessageBoxSync([browserWindow, ]options)和dialog.showMessageBox([browserWindow, ]options): 用于显示消息框(警报、确认、带有自定义按钮的提示)。异步版本返回一个 Promise,该 Promise 解析为一个包含用户响应的对象。dialog.showErrorBox(title, content): 一个简单的对话框,用于显示错误消息。这是一个同步操作。
在现代 Electron 开发中,始终优先使用对话框方法的异步版本,以避免阻塞主进程。记住要处理这些方法返回的 Promise 的成功结果和取消/错误情况。