Electron中如何将BrowserWindow数据传递至主进程?
问题分析
你的代码核心问题在于:main.ts里的ee和CustomWindow类内部的eventEmitter是完全独立的两个EventEmitter实例,所以CustomWindow中触发的事件,main进程里的监听器根本接收不到。
解决方案
以下两种方式都能实现主进程内的事件通信,完成窗口位置/大小数据的传递:
方式一:将主进程的EventEmitter实例传入CustomWindow
修改CustomWindow的构造函数,接收外部传入的EventEmitter实例,而非自行创建:
修改后CustomWindow.ts代码
import { BrowserWindow } from "electron"; import { EventEmitter } from 'events'; export default class CustomWindow extends BrowserWindow { typeKey: string; eventEmitter: EventEmitter; constructor(typeKey: string, preloadPath: string, eventEmitter: EventEmitter) { super({ show: false, webPreferences: { sandbox: true, preload: preloadPath, nodeIntegration: true, } }); this.typeKey = typeKey; this.eventEmitter = eventEmitter; // 使用传入的全局实例 // 监听窗口移动事件,发送位置数据 this.on('move', () => { const bounds = this.getBounds(); this.eventEmitter.emit('window-bounds-update', { typeKey: this.typeKey, bounds: bounds }); }); // 监听窗口缩放事件,发送大小数据 this.on('resize', () => { const bounds = this.getBounds(); this.eventEmitter.emit('window-bounds-update', { typeKey: this.typeKey, bounds: bounds }); }); this.on("ready-to-show", () => { this.eventEmitter.emit('event'); this.show(); // 窗口准备就绪后显示 }); } }
修改后main.ts代码
import EventEmitter from 'events'; import CustomWindow from './CustomWindow'; const ee = new EventEmitter(); // 监听窗口传来的位置/大小更新 ee.on('window-bounds-update', (data) => { console.log('收到窗口数据:', data); // 此处调用你的自定义Node模块处理保存逻辑 }); ee.on('event', () => { console.log("got an event...!"); }); // 创建窗口时传入EventEmitter实例 const mainWindow = new CustomWindow('main', './preload.js', ee);
方式二:使用全局共享的EventEmitter
创建一个单独模块导出全局EventEmitter,让所有主进程模块共用同一个实例:
创建events.ts模块
import EventEmitter from 'events'; export const globalEmitter = new EventEmitter();
修改后CustomWindow.ts代码
import { BrowserWindow } from "electron"; import { globalEmitter } from './events'; export default class CustomWindow extends BrowserWindow { typeKey: string; constructor(typeKey: string, preloadPath: string) { super({ show: false, webPreferences: { sandbox: true, preload: preloadPath, nodeIntegration: true, } }); this.typeKey = typeKey; this.on('move', () => { const bounds = this.getBounds(); globalEmitter.emit('window-bounds-update', { typeKey: this.typeKey, bounds: bounds }); }); this.on('resize', () => { const bounds = this.getBounds(); globalEmitter.emit('window-bounds-update', { typeKey: this.typeKey, bounds: bounds }); }); this.on("ready-to-show", () => { globalEmitter.emit('event'); this.show(); }); } }
修改后main.ts代码
import { globalEmitter } from './events'; import CustomWindow from './CustomWindow'; globalEmitter.on('window-bounds-update', (data) => { console.log('收到窗口数据:', data); // 处理保存逻辑 }); globalEmitter.on('event', () => { console.log("got an event...!"); }); const mainWindow = new CustomWindow('main', './preload.js');
额外提示
- 若需要在窗口关闭时强制保存一次数据,可以监听
close事件,触发时获取窗口边界并发送 move和resize事件会频繁触发,若要优化性能,可添加防抖逻辑(比如用setTimeout延迟100ms再发送数据),避免频繁执行保存操作
内容的提问来源于stack exchange,提问作者Markstar
相关产品推荐
相关产品推荐

