如何在打开时创建一个对话框来阻止 BrowserWindow?

Met*_*sis 2 electron

我打电话dialog.showOpenDialog()来寻找文件夹的路径。但问题是这不会阻止mainWindow. 需要在标准路径选择GUI出现时,程序只有路径选择完成才能继续工作。谷歌搜索并意识到您需要使用remote. 但什么也没有发生。

我得到:

无法解构“未定义”或“空”的属性对话框。如果来自electron.remote 进行对话。

我尝试了很多不同的东西(这些并不是所有的尝试,只是我记得的):

const { dialog } = require ('electron').remote;

var remote = electron.remote;

var dialog = remote.dialog;

const dialog = require ('electron').remote.dialog;
Run Code Online (Sandbox Code Playgroud)

我试图连接很多,但。

我的 main.js:

const url = require('url');
const path = require('path');

const {dialog} = electron.remote;

const {app, BrowserWindow, Menu} = electron;

app.on('ready', function () {
    const {start_width, start_height} = electron.screen.getPrimaryDisplay().workAreaSize;
    mainWindow = new BrowserWindow({
        minWidth: 1250,
        minHeight: 800,
        height: start_height,
        width: start_width,
        center: true,
        show: false,
    });

    mainWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'templates/mainWindow.html'),
        protocol: 'file:',
        slashes: true
    }));

    mainWindow.on('closed', function () {
        app.quit();
    });
    // mainWindow.webContents.openDevTools();
    const mainMenu = Menu.buildFromTemplate(mainMenuTemplate);
    Menu.setApplicationMenu(mainMenu);
    mainWindow.maximize();
    mainWindow.show();
});

function createAddWindow() {
    addWindow = new BrowserWindow({
        width: 300,
        height: 200,
        title: 'Add item'
    });

    addWindow.loadURL(url.format({
        pathname: path.join(__dirname, 'templates/addWindow.html'),
        protocol: 'file:',
        slashes: true
    }));
    addWindow.on('close', function () {
        addWindow = null;
    })
}

const mainMenuTemplate = [
    {
        label: 'Analysis',
        submenu: [{
            label: 'Global search',
            accelerator: 'Ctrl+O',
            click() {
                var path = createAddWindow();
                console.log(path);
            }

        },
            {
                label: 'Search for a year',
                accelerator: 'Ctrl+Alt+O',
                click() {
                    console.log(folderSelect());//i need console.log (like the whole program) to continue to work after folderSelect returns some value.
                }
            },
            {
                label: 'Quit',
                accelerator: process.platform == 'darwin' ? 'Command+Q' : 'Ctrl+Q',
                click() {
                    app.quit();
                }
            },
        ]
    }
];

function folderSelect() {
    dialog.showOpenDialog({properties: ['openDirectory']}, function (path) {
        console.log(path[0]);
        if (path === undefined) {
            return 'error';
        }
        else{
            return path[0];
        }
    });
}

Run Code Online (Sandbox Code Playgroud)

我需要console.log(就像整个程序一样)在folderSelect返回一些值后继续工作。

例如,如果我调用了该folderSelect函数,则在选择窗口关闭后的文件夹之前,您无法与程序进行交互。

我在 SO 上看到了很多类似的问题,但是无论我做什么都没有用。

jay*_*rjo 6

为了阻止主窗口,您需要将一个BrowserWindow对象dialog.showOpenDialog作为第一个可选参数传递给该方法,即您希望将对话框附加到的那个(mainWindow我猜是您的情况)。

来自文档的引用:

dialog.showOpenDialog([browserWindow, ]options)

browserWindow参数允许对话框将自身附加到父窗口,使其成为模态。

现在,你如何让它发生是完全不同的事情。它可以通过多种方式完成,但如果您希望从renderer进程中调用对话框,最简单的方法是这样的:

import { remote } from 'electron'

remote.dialog.showOpenDialog(
  remote.getCurrentWindow(), // <- notice this one
  { properties: ['openDirectory'] }
).then(result => {
  // prefer promised API
})
Run Code Online (Sandbox Code Playgroud)

整个事情正常工作的关键部分是nodeIntegration在你的BrowserWindow选项中启用,这取决于你使用的电子版本,你可能有也可能没有(他们已经在版本 4中将默认值从 切换truefalse)。无论如何,最好从现在开始明确设置它。所以这就是你通常会如何启动你的mainwindow现在:

mainWindow = new BrowserWindow({
  // ...
  show: false,
  webPreferences: {
    nodeIntegration: true // <- this one
  }
});
Run Code Online (Sandbox Code Playgroud)