You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:25:19