PyQt6应用中JavaScript的window.open新窗口能否被程序访问?
在PyQt6的QTabWidget中集成window.open打开的页面并保留JS交互
完全不需要放弃window.open()命令,你可以通过重写QWebEnginePage的createWindow方法,把JS调用window.open()创建的新窗口直接嵌入到QTabWidget中,同时保留主页面JS对新窗口内容的访问能力。
实现步骤
- 自定义QWebEnginePage子类:拦截窗口创建请求,手动创建新的QWebEngineView并添加到QTabWidget中,返回新view的页面对象,让Qt自动完成窗口上下文的关联(包括
window.opener的绑定)。 - 绑定主WebView到自定义Page:将主QWebEngineView的页面替换为自定义的子类实例,确保所有窗口创建请求都被拦截处理。
完整代码示例
from PyQt6.QtWidgets import QApplication, QTabWidget, QWidget, QVBoxLayout from PyQt6.QtWebEngineWidgets import QWebEngineView, QWebEnginePage from PyQt6.QtCore import QUrl class CustomWebEnginePage(QWebEnginePage): def __init__(self, tab_widget, parent=None): super().__init__(parent) self.tab_widget = tab_widget def createWindow(self, window_type): # 创建新的WebView用于承载window.open的内容 new_view = QWebEngineView() # 添加到TabWidget tab_index = self.tab_widget.addTab(new_view, "新窗口") self.tab_widget.setCurrentIndex(tab_index) # 返回新view的页面,让Qt把加载目标指向它 return new_view.page() class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("WebApp集成示例") self.resize(800, 600) # 创建TabWidget作为容器 self.tab_widget = QTabWidget() layout = QVBoxLayout() layout.addWidget(self.tab_widget) self.setLayout(layout) # 主WebView self.main_view = QWebEngineView() # 绑定自定义Page,传入TabWidget用于添加新标签 custom_page = CustomWebEnginePage(self.tab_widget, self.main_view) self.main_view.setPage(custom_page) # 添加主view到第一个标签 self.tab_widget.addTab(self.main_view, "主页面") # 加载一个带window.open测试的本地HTML(也可以替换为你的WebApp地址) test_html = """ <html> <body> <button onclick="openNewWindow()">打开新窗口并访问内容</button> <script> let newWin; function openNewWindow() { newWin = window.open('about:blank', '_blank'); newWin.document.write('<h1>新窗口内容</h1><p id="content">初始内容</p>'); // 测试访问新窗口内容 setTimeout(() => { newWin.document.getElementById('content').textContent = '主页面修改后的内容'; alert('新窗口内容已更新'); }, 1000); } </script> </body> </html> """ self.main_view.setHtml(test_html) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec()
关键说明
createWindow方法的作用:当JS调用window.open()时,Qt会触发这个方法,你可以在这里自定义新窗口的载体,而不是使用Qt默认的独立窗口。- 自动维护
window.opener关联:返回新QWebEngineView的页面后,Qt会自动建立原页面和新页面的上下文关联,所以主页面JS中的newWin对象可以正常访问新窗口的document、调用方法,和在浏览器中的行为完全一致。 - 适配现有WebApp:你不需要修改原有WebApp的
window.open()代码,只需要替换主WebView的Page为自定义子类即可实现Tab集成。
内容的提问来源于stack exchange,提问作者Kostiantyn Ivashchenko
相关产品推荐
相关产品推荐

