在关闭窗口

时间:2016-09-19 13:38:40

标签: electron

  • 我正在写一个写作申请。用户可以打开应用程序,写一些文本,保存他们的工作等。
  • 我想点击window close按钮会提示用户(a)保存他们的工作(如有必要)或(b)退出。
  • 我正在尝试使用window.beforeunload来实现这一目标,但发现我陷入了一个循环中,尝试“退出”会让无限期出现相同的提示。

以下是一些代码:

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是一个只包装电子对话框的功能,弹出显示有两个选项和各自的功能来调用每个选项。

如果我(可能)遗漏了必要的信息,其余的代码是available。如果我不是很清楚,我会很乐意澄清。

7 个答案:

答案 0 :(得分:18)

请在已定义浏览器窗口的函数内添加以下块(在我的情况下,它是在main.js中声明的createWindow()函数)

  // Create the browser window.
  mainWindow = new BrowserWindow({width: 400, height: 400})


  mainWindow.on('close', function(e){
    var choice = require('electron').dialog.showMessageBox(this,
        {
          type: 'question',
          buttons: ['Yes', 'No'],
          title: 'Confirm',
          message: 'Are you sure you want to quit?'
       });
       if(choice == 1){
         e.preventDefault();
       }
    });

答案 1 :(得分:11)

电子7+的答案

以下是基于 awijeet 的回答和 Sergio Mazzoleni 的评论的最新电子的可行解决方案。

createWindow()底部,win = new BrowserWindow(...)下方,使用:

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();
  }
});

Close Electron app confirm dialog

答案 2 :(得分:2)

你可以添加一个局部变量来避免使用mainWindow.destroy(),例如:

  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();
  })

答案 3 :(得分:1)

我最终使用window.destroy()将渲染过程粉碎到位(来自主进程):

ipcMain.on('quitter', (e) => {
  mainWindow.destroy(); // necessary to bypass the repeat-quit-check in the render process.
  app.quit()
})

不确定是否建议这样做,因为似乎有更好的方法来正确退出电子应用程序。如果你知道更好的答案,仍然很乐意得到任何反馈!

/耸肩!

答案 4 :(得分:1)

Awijeet的解决方案非常完美! Bth,thx Awijeet:它节省了我几个小时! ; - )

此外,如果您需要更进一步,请注意e.preventDefault()正在代码中的任何地方传播。正确管理preventDefault()后,您需要将变量e.defaultPrevented = false设置为恢复应用的自然行为。

实际上,在您更改其值之前,似乎e.preventDefault()函数将变量e.defaultPrevented变为true

答案 5 :(得分:0)

如果用户选择保存按钮,那么我们应该保存数据并使用window.close()关闭窗口。 但是,使用这种方法,我们将得到一个无限循环,该循环要求保存未保存的工作,因为window.close()将再次发出窗口的close事件。

要解决此问题,我们必须声明一个新的布尔变量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();
            }
        }
    });
});

答案 6 :(得分:0)

 // 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
        }
      }
    });

请注意,dialog.showMessageBox根据Electron Doc返回Promise<Object>

然后将this更改为mainWindow

这是对Awijeet原始答案的修改后答案