在Electron.js中进行确认

w8ntj3qf  于 2022-12-16  发布在  Electron
关注(0)|答案(1)|浏览(195)

我想在electron.js应用程序中创建一个包含yes和no按钮的消息框,我尝试在electron中使用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中的一个模块,但是它没有做我想做的事情。没有任何是或否按钮,当我点击OK或关闭窗口时,它也返回了相同的响应:

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


我做错了什么?

c2e8gylq

c2e8gylq1#

您将需要使用Electron的dialog.showMessageBox();方法。
对话框.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);
        })
})

为了在进程之间进行正确的通信,我们必须使用Inter-Process Communication
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');
        },
        dialogResponse: (response) => {
            ipcRenderer.on('dialogResponse', response);
        }
    }
);

最后,index.html文件将侦听按钮单击,单击后,向主进程发送消息以打开对话框。
从对话框接收到有效响应后,该响应将发送回渲染进程进行处理。
PS:渲染方法ipcRenderer.invoke()可以用来代替ipcRenderer.send()方法。但是如果是这样的话,你需要在渲染过程中处理“No”或者escape(ESC)响应。
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个以上的按钮,在创建对话框时,您可能需要指定一个cancelId,并在执行任何操作之前检查所有有效的返回值。

相关问题