Electron 关闭窗口前提示保存/退出 我正在写申请书。用户可以打开应用程序,编写一些文本,保存他们的工作,等等 我正试图这样做,点击窗口关闭按钮将提示用户(a)保存他们的工作(如有必要)或(b)退出 我试图使用窗口。在卸载之前来实现这一点,但发现我陷入了一个循环中,尝试“退出”会使相同的提示无限出现
下面是一些代码:Electron 关闭窗口前提示保存/退出 我正在写申请书。用户可以打开应用程序,编写一些文本,保存他们的工作,等等 我正试图这样做,点击窗口关闭按钮将提示用户(a)保存他们的工作(如有必要)或(b)退出 我试图使用窗口。在卸载之前来实现这一点,但发现我陷入了一个循环中,尝试“退出”会使相同的提示无限出现,electron,Electron,下面是一些代码: windowCloseCheck() { window.onbeforeunload = function(e) { e.returnValue = false; // window.alert('try to close me'); if(file.isUnsaved() || file.hasChanged()) { // prompt - save or just quit? file.fileWarning('You have unsaveeed w
windowCloseCheck() {
window.onbeforeunload = function(e) {
e.returnValue = false;
// window.alert('try to close me');
if(file.isUnsaved() || file.hasChanged()) {
// prompt - save or just quit?
file.fileWarning('You have unsaveeed work.', 'Save', 'Quit', function(){
// OPTION A - save
file.save();
}, function() {
// OPTION B: Quit.
ipcRenderer.send('quitter')
})
}
else {
// file is saved and no new work has been done:
ipcRenderer.send('quitter')
}
windowCloseCheck
在安装应用程序时调用,启动事件侦听器以关闭窗口。我的条件是检查文件是否未保存或已从原始文件更改
fileWarning
是一个只包装“电子”对话框的函数,使弹出窗口显示两个选项,并为每个选项调用相应的函数
代码的其余部分是我是否(可能)遗漏了必要的信息。如果我不是很清楚,我很乐意澄清
最后,我使用了
window.destroy()
将渲染过程粉碎为位(从主进程):
不确定是否建议这样做,因为似乎有更好的方法可以正确退出electron应用程序。如果你知道一个更好的答案,仍然很高兴得到任何反馈
/耸耸肩 请在定义浏览器窗口的函数中添加以下块(在我的例子中,它是main.js中声明的createWindow()函数)
Awijeet的解决方案非常完美!顺便说一句,这节省了我几个小时 此外,如果您需要进一步了解,请注意
e.preventDefault()
正在代码中到处传播。正确管理preventDefault()
后,需要将变量e.defaultPrevented=false
转到应用程序的自然行为
实际上,似乎
e.preventDefault()
函数将变量e.defaultPrevented
变为true
,直到您更改其值。您可以添加一个局部变量以避免mainWindow.destroy(),如:
如果用户选择保存按钮,那么我们应该保存数据并使用
window.close()
关闭窗口。
但是,使用这种方法,我们将得到一个无限循环,要求保存未保存的工作,因为window.close()
将再次发出window的close
事件
为了解决这个问题,我们必须声明一个新的布尔值varforceQuit
,该值最初设置为false
,然后在保存数据后或如果用户决定关闭而不保存数据,我们将其设置为true
import { app, BrowserWindow, dialog } from 'electron';
let win = null;
let forceQuit = false;
app.on('ready', () => {
win = new BrowserWindow({
// Your window options..
});
mainWindow.on('close', e => {
if (!forceQuit) {
const clickedButtonId = dialog.showMessageBox(mainWindow, {
type: 'warning',
buttons: ['Save', 'Cancel', `Don't save`],
cancelId: 1,
title: 'Confirm',
message: 'You have unsaved work!'
});
if (clickedButtonId === 0) {
e.preventDefault();
console.log('Saving...');
/** Here do your data saving logic */
forceQuit = true;
win.close();
} else if (clickedButtonId === 1) {
e.preventDefault();
} else if (clickedButtonId === 2) {
forceQuit = true;
win.close();
}
}
});
});
请注意,dialog.showMessageBox
根据
并将此
更改为主窗口
这是对Awijeet原始答案的修改答案电子7的答案+
以下是根据awijeet的回答和Sergio Mazzoleni的评论为最新的Electron提供的工作解决方案
在createWindow()
的底部,在您的win=newbrowserwindow(…)
下面,使用:
win.on('close', function(e) {
const choice = require('electron').dialog.showMessageBoxSync(this,
{
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
if (choice === 1) {
e.preventDefault();
}
});
这是迄今为止解决这一问题的最佳方式。几天来我一直在尝试不同的方法,总有一些东西需要绕过。然而,这种方法非常有效,而且它几乎是在不遇到问题的情况下完成此任务的唯一方法。。。至少在Electron版本1.4.15中,这很好,但是如果我想在对话框中显示一个复选框,比如
不要再显示它?
,那么我必须向showMessageBox传递一个回调,这会导致非阻塞行为,这使得此代码可用。请回答好的工作:)我尝试在渲染器中使用onbeforeunload这个过程我失败了。我也尝试过使用app.on('before-quit'),但没有成功。使用浏览器窗口是最好的解决方案!建议的解决方案似乎不再适用于Electron 7,因为dialog.showMessageBox
是一种异步方法。只需通过对话框替换调用即可。showMessageBoxSync
将修复此问题
let showExitPrompt = true;
// ask renderer process whether should close the app (mainWindow)
mainWindow.on('close', e => {
if (showExitPrompt) {
e.preventDefault(); // Prevents the window from closing
mainWindow.webContents.send('on-app-closing');
}
});
// renderer allows the app to close
ipcMain.on('quitter', (e) => {
showExitPrompt = false;
mainWindow.close();
})
import { app, BrowserWindow, dialog } from 'electron';
let win = null;
let forceQuit = false;
app.on('ready', () => {
win = new BrowserWindow({
// Your window options..
});
mainWindow.on('close', e => {
if (!forceQuit) {
const clickedButtonId = dialog.showMessageBox(mainWindow, {
type: 'warning',
buttons: ['Save', 'Cancel', `Don't save`],
cancelId: 1,
title: 'Confirm',
message: 'You have unsaved work!'
});
if (clickedButtonId === 0) {
e.preventDefault();
console.log('Saving...');
/** Here do your data saving logic */
forceQuit = true;
win.close();
} else if (clickedButtonId === 1) {
e.preventDefault();
} else if (clickedButtonId === 2) {
forceQuit = true;
win.close();
}
}
});
});
// Create the browser window.
mainWindow = new BrowserWindow({width: 400, height: 400})
mainWindow.on('close', function(e){
e.preventDefault();
var choice = require('electron').dialog.showMessageBox(mainWindow,
{
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
choice.then(function(res){
// 0 for Yes
if(res.response== 0){
// Your Code
}
// 1 for No
if(res.response== 1){
// Your Code
}
}
});
win.on('close', function(e) {
const choice = require('electron').dialog.showMessageBoxSync(this,
{
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
if (choice === 1) {
e.preventDefault();
}
});