首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >即使在调用了新窗口上的show()函数之后,电子js桌面应用程序也不会显示

即使在调用了新窗口上的show()函数之后,电子js桌面应用程序也不会显示
EN

Stack Overflow用户
提问于 2020-09-13 00:30:42
回答 2查看 2.3K关注 0票数 1

我是电子js的新手,但是当我在命令行上运行npm run start时,窗口似乎有时会显示,但有时也不会显示。我不知道是怎么回事。我甚至尝试在新创建的show : false上删除BrowserWindow部分,但是在运行npm run start几次之后仍然会出现同样的问题。当我用电子包装机打包应用程序时,我仍然面临着同样的问题。

编辑:我发现当我删除renderer.js文件中的所有代码时,它工作得很好,但是当我把代码放回去时,它会产生这个问题,所以问题可能在于呈现程序。

In . .app/main.js

代码语言:javascript
运行
复制
  // const {menu_template, save_as_id} = require('./app-menu');
    const {app, BrowserWindow, Menu, dialog, ipcMain} = require('electron');
    const path = require('path');
    
    /**
     * Create a new window when called
     */
    function createWindow() {
      let x; // Window x cordinate or horizontal position on screen
      let y; // Window y cordinate or vertical position on screen
    
      if (BrowserWindow.getAllWindows().length >= 3) return;
    
      const focusedWindow = BrowserWindow.getFocusedWindow();
      if (focusedWindow) {
        let [posX, posY] = focusedWindow.getPosition();
        // Log the window position
        console.log(`   Window position
                    x : ${posX}, y : ${posY}`);
    
        if (!focusedWindow.isNormal())
          posX = posY = 50;
        // Randomly place the window on the screen
        const randX = Math.round(Math.random() * 20);
        const randY = Math.round(Math.random() * 20);
        const _randX = -randX - 5;
        const _randY = -randY - 5;
    
        x = posX + (randX <= 10 ? _randX : randX);
        y = posY + (randY <= 10 ? _randY : randY);
        // check if window is not fully visible
        const isOffScreen = x < 0 || y < 0;
        // then set the window in a specific position: 60
        if (isOffScreen)
          x = y = 60;
      }
    
      // Create a new browser window
      let newWindow = new BrowserWindow({
        x,
        y,
        minWidth: 300,
        minHeight: 300,
        show: false,
        webPreferences: {
          enableRemoteModule: true,
          nodeIntegration: true,
          preload: path.join(__dirname, 'preload.js')
        }
    
      });
    
      newWindow.on('closed', () => {
        newWindow = null;
      });
    
      newWindow.loadFile('./app/index.html');
      newWindow.once('ready-to-show', () => {
        // now show the current window, when GUI has been loaded to the   window
        newWindow.show();
        console.log('Window ready to show');
    
        // set the window title to indicate that the current file is unnamed
        // and needs to be saved
        newWindow.setTitle('Untitled - NoteEditor');
      });
    }
    
    // Create new window on application first startup
    app.whenReady().then(() => {
    //   Menu.setApplicationMenu(menu_template);
      createWindow();
    })
    
    /**
     * Simply sets the `targetWindow`'s title, to `title`
     * @param {*} targetWindow to recipient for title change
     * @param {*} title the new title of window
     */
    const setWindowTitle = (targetWindow, title) =>      targetWindow.setTitle(title);
    
    exports.createWindow = createWindow;
    // exports.chooseFile = chooseFile;
    exports.setWindowTitle = setWindowTitle

./app/renderer.js

代码语言:javascript
运行
复制
 const {ipcRenderer, remote} = require("electron");
const mainProcess = remote.require('./main.js');
const app = remote.app;

var text = document.getElementById('text'); // The TextArea
var initialTextContent;
var g_targetTitle;


// when a key is pressed, display status showing that text has been edited and needs to be saved
text.addEventListener('keyup', () => {
  const target = remote.getCurrentWindow();
  let changedIndicatorChar = '*';
  let _windowTitle = target.getTitle();
  let isWindowStartUp = _windowTitle.startsWith('Untitled');

  // revert the window title to initial title if changes were removed
  if (text.value == initialTextContent)
    mainProcess.setWindowTitle(target, g_targetTitle);

  // should not set window title again based on this constraints  
  if (!isWindowStartUp && !_windowTitle.startsWith('*') && !_windowTitle.endsWith('txt')) {
    let newWindowTitle = changedIndicatorChar + _windowTitle;
    mainProcess.setWindowTitle(target, newWindowTitle);
  }
});

在./app/index.html中

代码语言:javascript
运行
复制
 <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Note Editor</title>
        <link rel="stylesheet" href="style.css">
    </head>
    
    <body>
        <textarea id="text"></textarea>
    </body>
    <script src="./renderer.js"></script>
    
    </html>
EN

回答 2

Stack Overflow用户

发布于 2020-09-15 04:19:28

我建议你先读我的电子介绍帖子,因为这是很好的知识。

这里有几件事让你很难受:

  1. 您正在创建的新窗口正在收集垃圾,因为let newWindowfunction createWindow()中。您需要在此函数之外存储对这些窗口的引用。一个例子
  2. 我不建议使用remotenodeIntegration。这些是处理容易出现安全问题的事情的老方法。这个职位也有一些好的信息。

下面是你想要做的事情,用它作为起点。它不完全处理多个窗口,但我认为您可以扩展这一点,让您开始!

main.js

代码语言:javascript
运行
复制
const {
  app,
  BrowserWindow,
  ipcMain
} = require("electron");
const path = require("path");

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

async function createWindow() {

  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false, // is default value after Electron v5
      contextIsolation: true, // protect against prototype pollution
      enableRemoteModule: false, // turn off remote
      preload: path.join(__dirname, "preload.js") // use a preload script
    }
  });

  // Load app
  win.loadFile("./app/index.html");

  // Emitted when the window is closed.
  win.on("closed", () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null;
  });

  win.once("ready-to-show", () => {
    // now show the current window, when GUI has been loaded to the window
    win.show();
    console.log("Window ready to show");
    
    // set the window title to indicate that the current file is unnamed
    // and needs to be saved
    win.setTitle("Untitled - NoteEditor");
  });
}

app.on("ready", createWindow);

ipcMain.on("toMain", (event, args) => {
  win.setTitle(args);
});

preload.js

代码语言:javascript
运行
复制
const {
    contextBridge,
    ipcRenderer
} = require("electron");

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
    "api", {
        changeTitle: (title) => {
            ipcRenderer.send("toMain", title);
        }
    }
);

index.html

代码语言:javascript
运行
复制
<!doctype html>
<html lang="en-US">
<head>
    <meta charset="utf-8"/>
    <title>Title</title>
</head>
<body>
    <script>
        // Update the title of the window
        window.api.changeTitle("new title");
    </script>
</body>
</html>
票数 1
EN

Stack Overflow用户

发布于 2020-09-13 08:23:07

这可能与窗口不总是显示的问题无关,但无论如何,变量newWindow必须在函数createWindow()之外声明,否则它所代表的BrowserWindow对象在函数退出后将不再有效(即将被垃圾回收).

代码语言:javascript
运行
复制
let newWindow = null; // Declaration moved out of createWindow()

function createWindow() {
  // [...]
  // Create a new browser window
  newWindow = new BrowserWindow({
    x,
    y,
    minWidth: 300,
    minHeight: 300,
    show: false,
    webPreferences: {
      enableRemoteModule: true,
      nodeIntegration: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });
  // [...]
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63866077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档