electron 如何在电子中制作多个细长窗口?

bihw5rsg  于 2022-12-16  发布在  Electron
关注(0)|答案(2)|浏览(265)

对于我的电子应用程序,我想打开另一个小窗口(或根据启动变量加载不同的窗口/组件)。
假设我使用this tutorial来设置一个基本结构,App.svelte看起来像这样:

<script>
    const openLauncher = () => {
        window.api.openWindow("launcher");
    };
</script>

<button on:click={openLauncher}>Open Launcher</button>

如您所见,我添加了一个IPC函数来打开一个新窗口。

const { app, BrowserWindow, ipcMain } = require("electron");
const { join } = require("path");

app.on("ready", () => {
    const mainWindow = new BrowserWindow({
        webPreferences: {
            preload: join(__dirname, "./preload.js"),
        }
    });
    mainWindow.loadFile(join(__dirname, "../public/index.html"));
});

ipcMain.on("openLauncher", (event, args) => {
    const launcher = new BrowserWindow({
        webPreferences: {
            preload: join(__dirname, "./preload.js"),
        }
    });
    launcher.loadFile(join(__dirname, "../public/launcher.html"));
});

preload.js

const { contextBridge, ipcRenderer } = require("electron");

const API = {
    openWindow: (obj) => ipcRenderer.send("openLauncher", obj),
}

contextBridge.exposeInMainWorld("api", API);

这确实有效,并打开了一个包含launcher.html的新窗口,但我不知道如何让Svelte组件在新文件中工作。
我的一个想法是修改main.js文件,使身体组件的变化,如下所示:

import App from './App.svelte';
import LauncherApp from './LauncherApp.svelte';

const bodyID = document.getElementsByTagName('body')[0].id;

const app = {};
if (bodyID == "index") {
    app = new App({
        target: document.body,
    });
}
else if (bodyID == "launcher") {
    app = new LauncherApp({
        target: document.body,
    });
}
export default app;

这适用于主窗口(即,如果我切换ID,它会在启动时加载正确的组件),但由于它在打开新窗口时不会加载任何Svelte,因此这不起作用。
所以我真的很感激任何关于如何让Svelte加载新的/不同的windows/html文件的想法!如果有一种方法可以用SvelteKit做到这一点,那就更好了!
先谢谢你!

lnlaulya

lnlaulya1#

我看到的明显的快速修复方法是在App.svelte中的bodyID上使用一个#if块,其中包含两个组件,MainApp(App.svelte的内容)和LauncherApp,然后根据您所处的模式简单地更改bodyID。
当使用sveltekit时,我认为将LauncherApp作为一个单独的路径是有意义的(我相信这是使用sveltekit“分离”页面的唯一方法,尽管我不是100%)。因此,当打开一个新窗口时,您将应用程序的新示例导航到LauncherApp路径。如果您不希望与主应用程序相同的基本布局,您可以添加一个__layout.reset.svelte文件。
我不知道为什么你的解决方案不起作用,它是相当优雅的。

6mw9ycah

6mw9ycah2#

由于这篇文章帮助我用Svelte和Electron创建了很多独立的窗口,我只是在堆栈溢出潜伏多年后创建了我的帐户。我想我已经破解了你的问题,没有“黑客”的工作区。
在我的原始App.svelte中,我没有使用#IF语句,而是让它正常工作。
我在srcMap中的main.js(渲染器端)如下所示:

import App from './App.svelte';
import Window2 from './Window2.svelte';

let bodyID = document.getElementsByTagName('body')[0].id;

let app;

if (bodyID == "index"){
    app = new App({
        target: document.body,
    });
}
else if (bodyID == "window2"){
    app = new Window2({
        target: document.body,
    });
}

export default app;

然而,我认为真实的的魔力发生在我的indexiderhtml和window2iderhtml中。我是用Tylerlaceby提供的优秀YouTube视频制作的。
基本上,主文件夹中的index.js(因此电子主js)打开包含以下行的窗口:

const main_window = new BrowserWindow({//Your settings
});

main_window.loadFile(join(__dirname, "../public/index.html"));
main_window.on("ready-to-show", main_window.show);

公用文件夹中的index.html包含以下标题:`

<title>Main Window</title>

<link rel='icon' type='image/png' href='./favicon.ico'>
<link rel='stylesheet' href='global.css'>
<link rel='stylesheet' href='build/bundle.css'>
 
<script defer src='build/bundle.js'></script>

主体是空的,但是附加了我在main.js渲染器端脚本中使用的id。
我相信index.html中的头文件在电子应用程序构建完成后会加载build文件夹,其中包含所有转换后的Svelte文件。
Window2.html是相同的。辅助窗口加载它的方式与主窗口在电子端main.js的第二个代码块中加载它的方式相同,但引用Window2.html。Window2.html包含ID为Window2的主体。
如果以上不是解决方案,也可能是因为我使用let而不是const。一旦变量被赋给const,它就不能被更改,这可能解释了为什么它第一次工作,但第二次不工作。
我很抱歉,如果我没有得到所有的格式和参考以前的awnsers正确。我仍然使用学习堆栈溢出,但渴望分享我是如何使它为我工作。

相关问题