我想在 Electron.js 应用程序中制作一个包含“是”和“否”按钮的消息框。我尝试用电子内部的dialog来做到这一点。但没有成功:
const electron = require('electron')
const { dialog } = electron
console.log(dialog) // undefined
const electron = require('electron')
const dialog = electron.remote.dialog
console.log(dialog) // Uncaught Error: Cannot read "dialog" of undefined (remote is undefined)
然后,我尝试使用 dialog 来实现,它是 npm 中的一个模块。但它没有做我想做的事情。没有任何是或否按钮,当我单击“确定”或关闭窗口时,它也返回相同的响应:
const electron = require('electron')
const dialog = require('dialog')
dialog.info('Are you sure?', 'Confirmation', function(exitCode) {
if (exitCode == 0) {
// Should clicked OK (always response)
}
if (exitCode == 1) {
// Should closed window (but never works)
}
})
我做错了什么?
dialog.showMessageBox();
方法。
dialog.showMessageBoxSync(); 方法会阻塞你的主进程,直到收到响应,所以除非有意,否则你不会想使用它。
我已将对话框的创建和管理放在
main.js
文件中。如果你想把它移到它的
自己的文件,这不是问题。如果您想要对话框,您需要做的就是 get()
(主)窗口实例
框成为主窗口的子窗口。
main.js
(主要流程)
// Import required Electron modules
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronDialog = require('electron').dialog;
const electronIpcMain = require('electron').ipcMain;
// Import required Node modules
const nodePath = require('path');
// Prevent garbage collection
let window;
function createWindow() {
const 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;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
electronIpcMain.on('openDialog', () => {
electronDialog.showMessageBox(window, {
'type': 'question',
'title': 'Confirmation',
'message': "Are you sure?",
'buttons': [
'Yes',
'No'
]
})
// Dialog returns a promise so let's handle it correctly
.then((result) => {
// Bail if the user pressed "No" or escaped (ESC) from the dialog box
if (result.response !== 0) { return; }
// Testing.
if (result.response === 0) {
console.log('The "Yes" button was pressed (main process)');
}
// Reply to the render process
window.webContents.send('dialogResponse', result.response);
})
})
为了进程之间的正确通信,我们必须 使用进程间通信。
preload.js
(主要流程)
// Import the necessary Electron modules
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// Exposed protected methods in the render process
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods
'ipcRenderer', {
// From render to main
openDialog: () => {
ipcRenderer.send('openDialog');
},
// From main to render
dialogResponse: (response) => {
ipcRenderer.on('dialogResponse', response);
}
}
);
最后,您的
index.html
文件将监听按钮单击。点击后,发送消息给主进程打开
这
对话框。
一旦从对话框收到有效响应,响应就会被发送回渲染进程进行处理。
可以用来代替ipcRenderer.invoke()
方法。 但如果是这样,您将需要在渲染过程中处理“否”或转义 (ESC) 响应。ipcRenderer.send()
index.html
(渲染过程)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
</head>
<body>
<input type="button" id="openDialog" value="Show Dialog">
<hr>
<div id="response"></div>
</body>
<script>
// Open dialog (in main process) when "Show Dialog" button is clicked
document.getElementById('openDialog').addEventListener('click', () => {
window.ipcRenderer.openDialog('openDialog');
})
// Response from main process
window.ipcRenderer.dialogResponse((event, response) => {
if (response === 0) {
// Perform your render action here
document.getElementById('response').innerText = 'The "Yes" button was clicked';
}
});
</script>
</html>
要在对话框中使用 2 个以上按钮,在创建对话框时您可能需要指定 a
cancelId
并在执行任何操作之前检查所有有效的返回值。