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
事件

为了解决这个问题,我们必须声明一个新的布尔值var
forceQuit
,该值最初设置为
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();
  }
});