Skip to content

第5章:Electron 窗口操作

5.1 窗口创建与配置

5.1.1 BrowserWindow 参数详解

BrowserWindow 是 Electron 中创建和控制窗口的核心类,它提供了丰富的配置选项来定制窗口的外观和行为。

5.1.1.1 窗口大小与位置

  • width:窗口宽度(默认:800)
  • height:窗口高度(默认:600)
  • x:窗口左上角 x 坐标(默认:居中)
  • y:窗口左上角 y 坐标(默认:居中)
  • minWidth:窗口最小宽度
  • minHeight:窗口最小高度
  • maxWidth:窗口最大宽度
  • maxHeight:窗口最大高度

5.1.1.2 窗口样式

  • frame:是否显示窗口边框和标题栏(默认:true)
  • titleBarStyle:标题栏样式('default', 'hidden', 'hiddenInset', 'customButtonsOnHover')
  • resizable:是否可调整大小(默认:true)
  • maximizable:是否可最大化(默认:true)
  • minimizable:是否可最小化(默认:true)
  • closable:是否可关闭(默认:true)
  • fullscreen:是否全屏(默认:false)
  • fullscreenable:是否可进入全屏(默认:true)
  • skipTaskbar:是否在任务栏中显示(默认:false)

5.1.1.3 窗口内容

  • icon:窗口图标路径
  • title:窗口标题
  • webPreferences:网页设置对象

5.1.2 窗口创建示例

javascript
const { BrowserWindow } = require('electron')

const win = new BrowserWindow({
  // 窗口大小
  width: 800,
  height: 600,
  
  // 窗口位置
  x: 100,
  y: 100,
  
  // 窗口样式
  frame: true,
  titleBarStyle: 'default',
  resizable: true,
  maximizable: true,
  minimizable: true,
  closable: true,
  
  // 窗口图标和标题
  icon: __dirname + '/assets/icon.png',
  title: 'My Electron App',
  
  // 网页设置
  webPreferences: {
    nodeIntegration: true,
    contextIsolation: false
  }
})

// 加载页面
win.loadFile('index.html')

5.2 窗口常用操作

5.2.1 窗口状态控制

5.2.1.1 显示与隐藏

  • show():显示窗口
  • hide():隐藏窗口
  • isVisible():检查窗口是否可见
javascript
// 显示窗口
win.show()

// 隐藏窗口
win.hide()

// 检查窗口是否可见
const isVisible = win.isVisible()
console.log('窗口是否可见:', isVisible)

5.2.1.2 最小化与最大化

  • minimize():最小化窗口
  • maximize():最大化窗口
  • unmaximize():取消最大化
  • isMinimized():检查窗口是否最小化
  • isMaximized():检查窗口是否最大化
javascript
// 最小化窗口
win.minimize()

// 最大化窗口
win.maximize()

// 取消最大化
win.unmaximize()

// 检查窗口状态
const isMinimized = win.isMinimized()
const isMaximized = win.isMaximized()
console.log('窗口是否最小化:', isMinimized)
console.log('窗口是否最大化:', isMaximized)

5.2.1.3 关闭窗口

  • close():关闭窗口(会触发 close 事件)
  • destroy():强制关闭窗口(不会触发 close 事件)
javascript
// 关闭窗口
win.close()

// 强制关闭窗口
win.destroy()

5.2.2 窗口大小与位置

  • setSize(width, height, animate):设置窗口大小
  • getSize():获取窗口大小
  • setPosition(x, y, animate):设置窗口位置
  • getPosition():获取窗口位置
  • center():将窗口居中
javascript
// 设置窗口大小
win.setSize(1000, 700, true) // 第三个参数为是否动画

// 获取窗口大小
const size = win.getSize()
console.log('窗口大小:', size) // [width, height]

// 设置窗口位置
win.setPosition(200, 150, true)

// 获取窗口位置
const position = win.getPosition()
console.log('窗口位置:', position) // [x, y]

// 将窗口居中
win.center()

5.2.3 多窗口管理

5.2.3.1 创建多个窗口

javascript
const { BrowserWindow } = require('electron')

// 创建主窗口
const mainWindow = new BrowserWindow({ /* 配置 */ })

// 创建第二个窗口
const secondWindow = new BrowserWindow({
  width: 600,
  height: 400,
  parent: mainWindow, // 设置父窗口
  modal: false, // 是否为模态窗口
  show: false // 初始隐藏
})

// 加载页面
secondWindow.loadFile('second.html')

// 显示第二个窗口
secondWindow.show()

5.2.3.2 管理所有窗口

  • BrowserWindow.getAllWindows():获取所有窗口
  • BrowserWindow.getFocusedWindow():获取当前聚焦的窗口
javascript
const { BrowserWindow } = require('electron')

// 获取所有窗口
const windows = BrowserWindow.getAllWindows()
console.log('窗口数量:', windows.length)

// 获取当前聚焦的窗口
const focusedWindow = BrowserWindow.getFocusedWindow()
if (focusedWindow) {
  console.log('当前聚焦的窗口:', focusedWindow.title)
}

5.3 窗口事件

5.3.1 常用窗口事件

  • close:窗口关闭时触发
  • closed:窗口关闭后触发
  • show:窗口显示时触发
  • hide:窗口隐藏时触发
  • minimize:窗口最小化时触发
  • maximize:窗口最大化时触发
  • unmaximize:窗口取消最大化时触发
  • resize:窗口大小改变时触发
  • move:窗口位置改变时触发
  • focus:窗口获得焦点时触发
  • blur:窗口失去焦点时触发

5.3.2 事件监听示例

javascript
const { BrowserWindow } = require('electron')

const win = new BrowserWindow({ /* 配置 */ })

// 监听窗口关闭事件
win.on('close', (event) => {
  console.log('窗口即将关闭')
  // 可以在这里阻止窗口关闭
  // event.preventDefault()
})

// 监听窗口关闭后事件
win.on('closed', () => {
  console.log('窗口已关闭')
  // 可以在这里清理资源
  win = null
})

// 监听窗口显示事件
win.on('show', () => {
  console.log('窗口显示')
})

// 监听窗口大小改变事件
win.on('resize', () => {
  const size = win.getSize()
  console.log('窗口大小改变:', size)
})

// 监听窗口位置改变事件
win.on('move', () => {
  const position = win.getPosition()
  console.log('窗口位置改变:', position)
})

5.4 实操案例:多窗口应用

5.4.1 场景描述

创建一个具有以下功能的多窗口 Electron 应用:

  • 主窗口显示应用主界面
  • 点击按钮打开设置窗口
  • 设置窗口可以独立操作
  • 主窗口和设置窗口之间可以通信
  • 关闭主窗口时关闭所有窗口

5.4.2 实现步骤

  1. 修改 main.js
javascript
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')

let mainWindow
let settingsWindow

function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    icon: path.join(__dirname, 'assets', 'icon.png'),
    title: '主窗口',
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })

  mainWindow.loadFile('index.html')
  mainWindow.webContents.openDevTools()

  // 监听来自渲染进程的消息
  ipcMain.on('open-settings', () => {
    createSettingsWindow()
  })

  // 监听窗口关闭事件
  mainWindow.on('closed', () => {
    // 关闭所有窗口
    if (settingsWindow) {
      settingsWindow.close()
    }
    mainWindow = null
  })
}

function createSettingsWindow() {
  // 如果设置窗口已存在,显示它
  if (settingsWindow) {
    settingsWindow.show()
    return
  }

  settingsWindow = new BrowserWindow({
    width: 600,
    height: 400,
    parent: mainWindow,
    modal: false,
    icon: path.join(__dirname, 'assets', 'icon.png'),
    title: '设置窗口',
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })

  settingsWindow.loadFile('settings.html')
  settingsWindow.webContents.openDevTools()

  // 监听窗口关闭事件
  settingsWindow.on('closed', () => {
    settingsWindow = null
  })

  // 监听来自设置窗口的消息
  ipcMain.on('settings-changed', (event, settings) => {
    console.log('设置已更改:', settings)
    // 向主窗口发送设置更改消息
    if (mainWindow) {
      mainWindow.webContents.send('settings-updated', settings)
    }
  })
}

app.whenReady().then(() => {
  createMainWindow()

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
  })
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})
  1. 修改 index.html(主窗口)
html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>主窗口</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
      padding: 0;
      background-color: #f0f0f0;
    }
    .container {
      max-width: 700px;
      margin: 0 auto;
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    h1 {
      color: #333;
      text-align: center;
    }
    button {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
    }
    button:hover {
      background-color: #45a049;
    }
    #settings-info {
      margin-top: 20px;
      padding: 10px;
      background-color: #f9f9f9;
      border-radius: 4px;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>主窗口</h1>
    <p>这是应用的主窗口,点击下面的按钮打开设置窗口。</p>
    
    <button id="open-settings-btn">打开设置窗口</button>
    
    <div id="settings-info">
      <h3>设置信息</h3>
      <p>当前设置:默认设置</p>
    </div>
  </div>
  
  <script>
    const { ipcRenderer } = require('electron')
    
    // 打开设置窗口按钮点击事件
    document.getElementById('open-settings-btn').addEventListener('click', () => {
      ipcRenderer.send('open-settings')
    })
    
    // 监听设置更新
    ipcRenderer.on('settings-updated', (event, settings) => {
      const settingsInfo = document.getElementById('settings-info')
      settingsInfo.innerHTML = `
        <h3>设置信息</h3>
        <p>当前设置:${JSON.stringify(settings)}</p>
      `
    })
  </script>
</body>
</html>
  1. 创建 settings.html(设置窗口)
html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>设置窗口</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
      padding: 0;
      background-color: #f0f0f0;
    }
    .container {
      max-width: 500px;
      margin: 0 auto;
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    h1 {
      color: #333;
      text-align: center;
    }
    .setting-item {
      margin: 15px 0;
    }
    label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
    }
    input[type="text"], select {
      width: 100%;
      padding: 8px;
      border: 1px solid #ddd;
      border-radius: 4px;
    }
    button {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      margin-top: 20px;
    }
    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>设置窗口</h1>
    
    <div class="setting-item">
      <label for="username">用户名</label>
      <input type="text" id="username" value="user123">
    </div>
    
    <div class="setting-item">
      <label for="theme">主题</label>
      <select id="theme">
        <option value="light">浅色</option>
        <option value="dark" selected>深色</option>
        <option value="system">系统</option>
      </select>
    </div>
    
    <div class="setting-item">
      <label for="language">语言</label>
      <select id="language">
        <option value="zh-CN" selected>中文</option>
        <option value="en-US">英文</option>
      </select>
    </div>
    
    <button id="save-settings">保存设置</button>
  </div>
  
  <script>
    const { ipcRenderer } = require('electron')
    
    // 保存设置按钮点击事件
    document.getElementById('save-settings').addEventListener('click', () => {
      const settings = {
        username: document.getElementById('username').value,
        theme: document.getElementById('theme').value,
        language: document.getElementById('language').value
      }
      
      // 向主进程发送设置更改消息
      ipcRenderer.send('settings-changed', settings)
      
      // 显示保存成功提示
      alert('设置已保存')
    })
  </script>
</body>
</html>
  1. 创建资源文件夹和图标
  • 创建 assets 文件夹
  • 添加 icon.png(应用图标)

5.4.3 运行效果

  1. 启动应用

    bash
    npm start
  2. 测试功能

    • 点击 "打开设置窗口" 按钮,打开设置窗口
    • 在设置窗口中修改设置,点击 "保存设置"
    • 观察主窗口中的设置信息更新
    • 关闭主窗口,设置窗口也会关闭

5.5 小结

通过本章的学习,你已经掌握了 Electron 窗口操作的核心功能:

  • 窗口创建与配置:使用 BrowserWindow 类创建和配置窗口
  • 窗口常用操作:显示、隐藏、最小化、最大化、关闭等
  • 窗口事件:监听窗口状态变化事件
  • 多窗口管理:创建和管理多个窗口
  • 窗口间通信:通过 IPC 在不同窗口之间传递数据

这些功能是 Electron 应用开发的基础,掌握它们可以帮助你创建更加复杂和功能丰富的桌面应用。在接下来的章节中,我们将深入学习进程间通信的高级用法。

© 2026 编程马·菜鸟教程 版权所有