QWebEngineView创建的多个QWebEngineProcess占用内存

Multiple QWebEngineProcesses created by QWebEngineView eats up memory

提问人:Lizzzz90 提问时间:4/29/2023 最后编辑:mahkitahLizzzz90 更新时间:4/29/2023 访问量:65

问:

在我的应用程序中,我有一个按钮列表,单击每个按钮会在 QMainWindow 中创建一个新的 QWebEngineView。在关闭 QMainWindow 时,我希望销毁 QWebEngineView(以及它生成的 QWebEngineProcess)。但这不会发生 - 如果我单击多个按钮,就会创建多个 QWebEngineProcesses,从而占用内存。为什么这些进程在破坏 Web 视图后没有被杀死?谁能帮我解决这个问题?

enter image description here

这是我在尝试解决此问题时尝试的示例代码。我这里有一个按钮,每次单击它都会创建一个带有 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() # => This does not kill background process 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())

我遇到了这个:https://doc.qt.io/qtforpython-6/overviews/qtwebengine-features.html#process-models 和“每个站点的进程”可能是这个问题的可能解决方案,但我真的不明白如何以及在哪里使用命令行参数。仅仅将它们作为参数传递给 QApplication() 是行不通的。

python pyside6 qtwebengine qtwebview

评论

1赞 musicamante 4/29/2023
首先,使用 ,而不是 ,然后您应该删除整个窗口,而不仅仅是视图。从理论上讲,这应该可以处理任何剩余的参考。如果这还不够,请尝试删除该页面,但理论上应该不会发生这种情况(除非您在其他地方保留引用)deleteLater()destroy()
0赞 Lizzzz90 4/30/2023
deleteLater() 有效!它删除了 QtWebEngineProcess。谢谢你@musicmante
0赞 musicamante 4/30/2023
请注意,只需在窗口上设置属性即可避免所有这些(包括覆盖)。参见 QWidget.setAttribute()。closeEvent()WA_DeleteOnClose
0赞 Lizzzz90 5/2/2023
由于某种原因,该属性对我不起作用。我在继承QMainWindow的PlotWindow类中添加了self.setAtrribute(QtCore.Qt.WA_DeleteOnClose, True)
0赞 musicamante 5/2/2023
请解释一下你所说的“不起作用”是什么意思。

答: 暂无答案