Electron:如何跨多个文件共享 BrowserWindow 实例?
Electron: How to share BrowserWindow instance across multiple files?
我想要一个 js 文件,比方说 window.js
,它负责创建和导出 BrowserWindow
的唯一实例,这样我就可以在多个 js 文件中重用这个实例。
直到现在我试过这个:
const { app, BrowserWindow } = require("electron");
let window = null;
const createWindow = () => {
if (window) return;
window = new BrowserWindow({
minWidth: 820,
minHeight: 620,
width: 820,
height: 620,
resizable: false,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
enableRemoteModule: true,
},
});
window.removeMenu();
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
// showRecorderWindow();
}
});
});
module.exports = {
window
}
然而,当我需要 window 时使用:
const { window } = require("./window.js");
window 变量始终为空。有什么办法可以实现吗?
当您使用 module.exports = <object>
时,您创建的是对象的副本,没有 link 回到原始对象。在您的代码中,在 app.whenReady()
部分中创建 window 之前,module.exports
部分是 运行。这是因为 app.whenReady()
部分中的函数是 运行 异步的。所以此时 module.exports = { window }
是 运行,window
仍然等于 null
。要解决此问题,您需要在 createWindow()
之后将 module.exports
移动到 app.whenReady()
中,或者为了修复范围,将其移动到 createWindow()
中(我还更正了缩进):
const { app, BrowserWindow } = require("electron");
const createWindow = () => {
if (window) return;
const window = new BrowserWindow({
minWidth: 820,
minHeight: 620,
width: 820,
height: 620,
resizable: false,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
enableRemoteModule: true,
},
});
window.removeMenu();
module.exports = {
window
}
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
// showRecorderWindow();
}
});
});
现在,当您需要 windows.js
时,它将 return 最新的 window
对象。只需确保在应用准备就绪后执行 const { window } = require("./window.js");
:
// file2.js
const { app, BrowserWindow } = require("electron");
let window = null;
app.whenReady().then(() => {
app.on("activate", () => {
if (window == null) {
{ window } = require("./window.js");
}
});
});
请注意,您不能多次 require("./window.js")
来获取最新的 window,因为 node.js 会在您需要时保留一份 window.js。您可能还想查看 inter-process 通信:https://www.electronjs.org/docs/latest/tutorial/ipc
使用“setter”和“getter”将解决您的问题。
您的 main.js
文件应该 require
您的 window.js
模块和 create()
window.
如果任何其他 Javascript 文件需要访问 window 实例,那么在该文件中您可以 require
window.js
模块,然后只需调用get()
函数。
在您的 main.js
(主线程)文件中:
require
window.js
文件,其中包含 create
和 get
函数。
- 声明
window
变量,使其不被垃圾回收。
- 在
electronApp.on('ready', ...)
上将创建的 window 实例分配给 window 变量。
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const nodePath = require("path");
const appWindow = require(nodePath.join(__dirname, 'window'));
// Prevent garbage collection
let window;
electronApp.on('ready', () => {
window = appWindow.create();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
appWindow.create();
}
});
在您的 window.js
(主线程)文件中:
- 创建 2 个函数 - 一个到
create
window,一个到 get
window 实例。
- 导出这两个函数以便在别处使用。
const electronBrowserWindow = require('electron').BrowserWindow;
const nodePath = require('path');
let window; // Top level scope within the module
function create() {
window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window; // Return the instance of the window
}
function get() {
return window; // Return the instance of the window
}
// Export the publicly available functions.
module.exports = {create, get};
最后,当你需要在another.js
(主线程)文件中引用window
的实例时:
require
window.js
文件。
- 调用
get()
函数。
const nodePath = require('path');
const appWindow = require(nodePath.join(__dirname, 'window'));
let window = appWindow.get();
当您需要使用特定 window 作为子 window 或对话框的父级时,这非常方便。
我想要一个 js 文件,比方说 window.js
,它负责创建和导出 BrowserWindow
的唯一实例,这样我就可以在多个 js 文件中重用这个实例。
直到现在我试过这个:
const { app, BrowserWindow } = require("electron");
let window = null;
const createWindow = () => {
if (window) return;
window = new BrowserWindow({
minWidth: 820,
minHeight: 620,
width: 820,
height: 620,
resizable: false,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
enableRemoteModule: true,
},
});
window.removeMenu();
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
// showRecorderWindow();
}
});
});
module.exports = {
window
}
然而,当我需要 window 时使用:
const { window } = require("./window.js");
window 变量始终为空。有什么办法可以实现吗?
当您使用 module.exports = <object>
时,您创建的是对象的副本,没有 link 回到原始对象。在您的代码中,在 app.whenReady()
部分中创建 window 之前,module.exports
部分是 运行。这是因为 app.whenReady()
部分中的函数是 运行 异步的。所以此时 module.exports = { window }
是 运行,window
仍然等于 null
。要解决此问题,您需要在 createWindow()
之后将 module.exports
移动到 app.whenReady()
中,或者为了修复范围,将其移动到 createWindow()
中(我还更正了缩进):
const { app, BrowserWindow } = require("electron");
const createWindow = () => {
if (window) return;
const window = new BrowserWindow({
minWidth: 820,
minHeight: 620,
width: 820,
height: 620,
resizable: false,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
enableRemoteModule: true,
},
});
window.removeMenu();
module.exports = {
window
}
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
// showRecorderWindow();
}
});
});
现在,当您需要 windows.js
时,它将 return 最新的 window
对象。只需确保在应用准备就绪后执行 const { window } = require("./window.js");
:
// file2.js
const { app, BrowserWindow } = require("electron");
let window = null;
app.whenReady().then(() => {
app.on("activate", () => {
if (window == null) {
{ window } = require("./window.js");
}
});
});
请注意,您不能多次 require("./window.js")
来获取最新的 window,因为 node.js 会在您需要时保留一份 window.js。您可能还想查看 inter-process 通信:https://www.electronjs.org/docs/latest/tutorial/ipc
使用“setter”和“getter”将解决您的问题。
您的 main.js
文件应该 require
您的 window.js
模块和 create()
window.
如果任何其他 Javascript 文件需要访问 window 实例,那么在该文件中您可以 require
window.js
模块,然后只需调用get()
函数。
在您的 main.js
(主线程)文件中:
require
window.js
文件,其中包含create
和get
函数。- 声明
window
变量,使其不被垃圾回收。 - 在
electronApp.on('ready', ...)
上将创建的 window 实例分配给 window 变量。
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const nodePath = require("path");
const appWindow = require(nodePath.join(__dirname, 'window'));
// Prevent garbage collection
let window;
electronApp.on('ready', () => {
window = appWindow.create();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
appWindow.create();
}
});
在您的 window.js
(主线程)文件中:
- 创建 2 个函数 - 一个到
create
window,一个到get
window 实例。 - 导出这两个函数以便在别处使用。
const electronBrowserWindow = require('electron').BrowserWindow;
const nodePath = require('path');
let window; // Top level scope within the module
function create() {
window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window; // Return the instance of the window
}
function get() {
return window; // Return the instance of the window
}
// Export the publicly available functions.
module.exports = {create, get};
最后,当你需要在another.js
(主线程)文件中引用window
的实例时:
require
window.js
文件。- 调用
get()
函数。
const nodePath = require('path');
const appWindow = require(nodePath.join(__dirname, 'window'));
let window = appWindow.get();
当您需要使用特定 window 作为子 window 或对话框的父级时,这非常方便。