在多个WebContentsViews(Electron)之间进行通信 我有一个我正在处理的电子应用程序,它使用了此布局,首先是主要的webcontentsview,然后是工具栏。

问题描述 投票:0回答:0

here browserapp.ts代码

import { BrowserWindow, WebContentsView } from 'electron'; import { createToolbar } from '../toolbar/toolbar'; // Import the toolbar creation function interface BrowserTabView { id: number; webContentsView: WebContentsView; url: string; } const tabViews: BrowserTabView[] = []; let activeTabId: number | null = null; // Track the active tab's ID // Constants for heights const TITLEBAR_HEIGHT = 30; const TOOLBAR_HEIGHT = 37; const TOOLBAR_OFFSET = 3.8; export function createWebContentsView(mainWindow: BrowserWindow, id: number, url = 'https://google.com/'): WebContentsView { const windowBounds = mainWindow.getBounds(); // Create the toolbar const toolbarView = createToolbar(mainWindow); // Calculate the y-position for the toolbar (directly below the titlebar with a small offset) const toolbarY = TITLEBAR_HEIGHT + TOOLBAR_OFFSET; // Toolbar is directly below the titlebar with a small offset // Position the toolbar toolbarView.setBounds({ x: 0, y: toolbarY, // Position directly below the titlebar with a small offset width: windowBounds.width, height: TOOLBAR_HEIGHT, }); // Calculate the y-position for the main WebContentsView (below the toolbar) const webContentsY = toolbarY + TOOLBAR_HEIGHT; // Create and position the main WebContentsView const webContentsView = new WebContentsView(); mainWindow.contentView.addChildView(webContentsView); webContentsView.setBounds({ x: 0, y: webContentsY, // Position below the toolbar width: windowBounds.width, height: windowBounds.height - webContentsY, // Adjust height to account for titlebar and toolbar }); // Load the initial URL webContentsView.webContents.loadURL(url); // Add the new tab view to the list tabViews.push({ id, webContentsView, url }); // If this is the first tab, select it if (tabViews.length === 1) { selectWebContentsView(mainWindow, id); } // Handle navigation events webContentsView.webContents.on('did-navigate', (_, updatedURL) => { const tab = tabViews.find(view => view.id === id); if (tab) { tab.url = updatedURL; } updateAddressBar(updatedURL); }); // Handle window resize events mainWindow.on('resize', () => { const newBounds = mainWindow.getBounds(); // Resize the toolbar toolbarView.setBounds({ x: 0, y: toolbarY, // Maintain position directly below the titlebar with a small offset width: newBounds.width, height: TOOLBAR_HEIGHT, }); // Resize the active tab's WebContentsView const activeTab = tabViews.find(view => view.id === id); if (activeTab) { activeTab.webContentsView.setBounds({ x: 0, y: webContentsY, // Maintain position below the toolbar width: newBounds.width, height: newBounds.height - webContentsY, // Adjust height dynamically }); } }); return webContentsView; } export function selectWebContentsView(mainWindow: BrowserWindow, id: number) { const activeTab = tabViews.find(view => view.id === id); if (activeTab) { // Hide all views first tabViews.forEach(view => { view.webContentsView.setBounds({ x: 0, y: 0, width: 0, height: 0 }); }); // Show the selected view const windowBounds = mainWindow.getBounds(); activeTab.webContentsView.setBounds({ x: 0, y: TITLEBAR_HEIGHT + TOOLBAR_OFFSET + TOOLBAR_HEIGHT, // Position below titlebar and toolbar with offset width: windowBounds.width, height: windowBounds.height - (TITLEBAR_HEIGHT + TOOLBAR_OFFSET + TOOLBAR_HEIGHT), // Adjust height dynamically }); // Update the active tab ID activeTabId = id; updateAddressBar(activeTab.url); } } export function closeWebContentsView(mainWindow: BrowserWindow, id: number) { const index = tabViews.findIndex(view => view.id === id); if (index !== -1) { const view = tabViews[index]; view.webContentsView.webContents.close(); // Close the webContents mainWindow.contentView.removeChildView(view.webContentsView); // Remove the view from the window tabViews.splice(index, 1); // If there are remaining tabs, select the first one if (tabViews.length > 0) { selectWebContentsView(mainWindow, tabViews[0].id); } else { activeTabId = null; // No active tab } } } export function updateWebContentsURL(id: number, url: string) { const view = tabViews.find(v => v.id === id); if (view) { view.webContentsView.webContents.loadURL(url); view.url = url; updateAddressBar(url); } } function updateAddressBar(url: string) { // Assuming there's a way to communicate with the renderer process to update the address bar // This can be done using Electron's IPC // Example: mainWindow.webContents.send('update-address-bar', url); } // Navigation functions export function navigateBack() { if (activeTabId !== null) { const activeTab = tabViews.find(view => view.id === activeTabId); if (activeTab) { activeTab.webContentsView.webContents.goBack(); } } } export function navigateForward() { if (activeTabId !== null) { const activeTab = tabViews.find(view => view.id === activeTabId); if (activeTab) { activeTab.webContentsView.webContents.goForward(); } } } export function navigateRefresh() { if (activeTabId !== null) { const activeTab = tabViews.find(view => view.id === activeTabId); if (activeTab) { activeTab.webContentsView.webContents.reload(); } } } export function navigateTo(url: string) { if (activeTabId !== null) { const activeTab = tabViews.find(view => view.id === activeTabId); if (activeTab) { activeTab.webContentsView.webContents.loadURL(url); } } }

并发了工具栏。TS

import { BrowserWindow, WebContentsView } from 'electron'; import { getToolbarStyles } from './toolbarstyle'; import * as path from 'path'; import * as fs from 'fs'; import { navigateBack, navigateForward, navigateRefresh, navigateTo } from '../browserapp/browserapp'; // Import navigation functions export function createToolbar(mainWindow: BrowserWindow): WebContentsView { const toolbarHeight = 37; // Height of the toolbar const windowBounds = mainWindow.getBounds(); const toolbarView = new WebContentsView(); mainWindow.contentView.addChildView(toolbarView); toolbarView.setBounds({ x: 0, y: 0, width: windowBounds.width, height: toolbarHeight, }); // Read SVG files as base64 (Fixes file:// loading issues) function getBase64Icon(iconPath: string): string { try { const iconData = fs.readFileSync(iconPath, 'base64'); return `data:image/svg+xml;base64,${iconData}`; } catch (error) { console.error(`Failed to load icon: ${iconPath}`, error); return ''; } } // Convert SVGs to base64 const backIconData = getBase64Icon(path.resolve(__dirname, 'toolbar-icons', 'back.svg')); const forwardIconData = getBase64Icon(path.resolve(__dirname, 'toolbar-icons', 'forward.svg')); const refreshIconData = getBase64Icon(path.resolve(__dirname, 'toolbar-icons', 'refresh.svg')); // Inject CSS to style the toolbar toolbarView.webContents.on('dom-ready', () => { const css = getToolbarStyles(); toolbarView.webContents.insertCSS(css); // Pass icon data safely using JSON.stringify toolbarView.webContents.executeJavaScript(` (() => { document.body.innerHTML = ''; const toolbar = document.createElement('div'); toolbar.className = 'toolbar'; const backButton = document.createElement('button'); backButton.className = 'toolbar-button'; backButton.innerHTML = '<img src="${backIconData}" alt="Back">'; backButton.addEventListener('click', () => { window.toolbarCallbacks.navigateBack(); }); const forwardButton = document.createElement('button'); forwardButton.className = 'toolbar-button'; forwardButton.innerHTML = '<img src="${forwardIconData}" alt="Forward">'; forwardButton.addEventListener('click', () => { window.toolbarCallbacks.navigateForward(); }); const refreshButton = document.createElement('button'); refreshButton.className = 'toolbar-button'; refreshButton.innerHTML = '<img src="${refreshIconData}" alt="Refresh">'; refreshButton.addEventListener('click', () => { window.toolbarCallbacks.navigateRefresh(); }); const addressBar = document.createElement('input'); addressBar.className = 'address-bar'; addressBar.type = 'text'; addressBar.placeholder = 'Enter address or search'; addressBar.addEventListener('keypress', (event) => { if (event.key === 'Enter') { window.toolbarCallbacks.navigateTo(event.target.value); } }); toolbar.appendChild(backButton); toolbar.appendChild(forwardButton); toolbar.appendChild(refreshButton); toolbar.appendChild(addressBar); document.body.appendChild(toolbar); })(); `); // Expose the callbacks to the toolbar's WebContentsView toolbarView.webContents.executeJavaScript(` window.toolbarCallbacks = { navigateBack: ${navigateBack.toString()}, navigateForward: ${navigateForward.toString()}, navigateRefresh: ${navigateRefresh.toString()}, navigateTo: ${navigateTo.toString()}, }; `); }); // Load a blank page to apply the CSS toolbarView.webContents.loadURL('about:blank'); return toolbarView; }

i我通过将所需的事件添加到副总量中来解决了问题。
    

typescript electron
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.