QWebEngineView创建多QWebEngineProcess致内存过高求助
QWebEngineView销毁后QWebEngineProcess未终止的问题
我的应用里有一组按钮,点击每个按钮会在QMainWindow中创建新的QWebEngineView。关闭QMainWindow时,我希望销毁QWebEngineView及其衍生的QWebEngineProcess,但实际没做到——多次点击按钮会生成多个占用内存的QWebEngineProcess。为什么销毁Web视图后这些进程还没终止?

以下是用于排查问题的示例代码,点击按钮会创建带QWebEngineView的新主窗口:
import sys from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QMainWindow) from PySide6 import QtCore from PySide6.QtWebEngineWidgets import QWebEngineView class PlotWindow(QMainWindow): def __init__(self, parent): """Constructor.""" super(PlotWindow, self).__init__(parent) self.webV = QWebEngineView() self.webV.load('https://en.wikipedia.org/') self.setCentralWidget(self.webV) def closeEvent(self, event): self.webV.destroy() # => 这不会终止后台的QWebEngineProcess进程 class webView(QWidget): def __init__(self): super(webView, self).__init__() self.layout = QVBoxLayout(self) btn = QPushButton('Click') btn.clicked.connect(lambda: self.create_plot(self)) self.layout.addWidget(btn) self.setLayout(self.layout) @QtCore.Slot() def create_plot(self, widget): win = PlotWindow(widget) win.show() if __name__ == "__main__": app = QApplication() web = webView() web.show() sys.exit(app.exec())
我了解到Qt文档中的“Process Per Site”模式可能是解决方案,但不知道怎么正确使用命令行参数,直接传入QApplication()无效。
问题原因
- Qt WebEngine的进程管理是独立于Qt控件生命周期的,默认进程模型会复用或保留进程资源,不会随视图销毁立刻终止进程
destroy()仅销毁Qt控件对象,不会主动触发WebEngine进程的终止逻辑
解决方案
方案1:正确释放WebEngine资源并清理页面
修改PlotWindow的closeEvent方法,先清理页面资源再释放控件:
def closeEvent(self, event): # 加载空白页面,清理当前页面的资源占用 self.webV.load(QtCore.QUrl("about:blank")) # 等待页面加载完成,确保资源清理完毕 loop = QtCore.QEventLoop() self.webV.loadFinished.connect(loop.quit) loop.exec() # 解除父控件关联并延迟销毁 self.webV.setParent(None) self.webV.deleteLater() # 确认关闭窗口 event.accept()
方案2:配置"Process Per Site"进程模型
需要在QApplication初始化之前添加命令行参数,而不是直接传入初始化方法:
if __name__ == "__main__": # 添加进程模型配置参数 sys.argv.append("--process-model=process-per-site") app = QApplication(sys.argv) web = webView() web.show() sys.exit(app.exec())
该模式会将同一站点的页面归到同一个进程中,减少进程数量,当该站点的所有视图都关闭后,对应的进程会自动终止。
方案3:使用独立Profile控制进程生命周期
为每个视图创建独立的QWebEngineProfile,关闭视图时销毁Profile,触发进程终止:
from PySide6.QtWebEngineWidgets import QWebEnginePage, QWebEngineProfile class PlotWindow(QMainWindow): def __init__(self, parent): super(PlotWindow, self).__init__(parent) # 创建独立的Profile self.profile = QWebEngineProfile() self.webV = QWebEngineView() # 为视图绑定独立Profile的页面 self.webV.setPage(QWebEnginePage(self.profile, self.webV)) self.webV.load('https://en.wikipedia.org/') self.setCentralWidget(self.webV) def closeEvent(self, event): self.webV.load(QtCore.QUrl("about:blank")) loop = QtCore.QEventLoop() self.webV.loadFinished.connect(loop.quit) loop.exec() self.webV.deleteLater() # 销毁Profile,触发对应进程终止 self.profile.deleteLater() event.accept()
内容的提问来源于stack exchange,提问作者Lizzzz90
相关产品推荐
相关产品推荐

