PDA

View Full Version : Closing QWebEngineView (QtWebEngineProcess.exe)



Kasea
5th May 2017, 19:53
So I'm trying to make a Webkit of sorts, however sometimes the pages stops to load(ideally I'd fix this problem, but can't seem to sort it out), so I've decided to come up with a hackish way of handling that issue. I want to close the current QWebEngineView then recreate it, this works as the view starts loading again, however it doesn't close itself properly. In task manager under processes i find several QtWebEngineProcess.exe processes if the program goes for a long time, which indicates that it isn't being closed properly. How if sip.delete(QWebEngineView) doesn't work what would help?


def _render(url, wait):
try:
from PyQt5.QtCore import QEventLoop, QUrl, QTimer
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication
from sip import delete

class Render():
page_load_timeout = 15

def __init__(self, url, wait):
self.url = QUrl(url)
self.wait = wait
self.html = None
self.app = QApplication(sys.argv)
self._createView()
while self.html is None:
self.app.processEvents(
QEventLoop.ExcludeUserInputEvents |
QEventLoop.ExcludeSocketNotifiers |
QEventLoop.WaitForMoreEvents)
self.app.quit()

def _createView(self):
self.view = QWebEngineView()
self.view.loadFinished.connect(self._loadFinished)
self.view.loadProgress.connect(self._loadProgress)
self.view.load(self.url)

def _checkProgress(self):
cur = time.clock()
if self._lastProg + self.page_load_timeout < cur:
self._lastProg = time.clock()
with open(os.getcwd() + "\\files\\wk_log.txt", "a") as f:
f.write("Recreating view\n")
delete(self.view)
self._createView()

def _loadProgress(self, prog):
with open(os.getcwd() + "\\files\\wk_log.txt", "a") as f:
f.write("{}\n".format(prog))
if prog != 100:
self._lastProg = time.clock()
QTimer.singleShot((self.page_load_timeout + 0.5) * 1000, self._checkProgress)


def _loadFinished(self, result):
QTimer.singleShot(self.wait * 1000, self._timer_for_html)

def _timer_for_html(self):
self.view.page().toHtml(self._callable)

def _callable(self, data):
self.html = data
except:
print("Exception occured")

#with devnull():
return Render(url, wait).html

Never mind the layout of the code, it's just to get my problem across. The webview will load fine a couple of times, then suddenly break. Now the current code fixes this, however it doesn't close the previous view properly. I've thought about running del self.view However I don't think that would change anything as it would just delete the reference of the view and not the actual view itself.

Running PyQt5-5.8.2 on windows 10 64 bit, python 64 bit

Kasea
6th May 2017, 17:22
Seems like i found the culprite. It would seem that deleting the QWebEngineView wasn't enough, because the QWebEngineView generates a QWebEnginePage.

I would assume that closing the view would close the page aswell, but wouldn't seem so... The fix was to get the page (or initlize as a page) and close that then the view.

I've been running this for about 40 minutes now without any problems.

Kasea
6th May 2017, 21:12
Scratch that, it broke, however it does seem more stable now.

JohannesMunk
26th March 2019, 21:56
Migrating from Qt5.7 to Qt5.12 and from MSVC2015 to MSVC2017 we ran into a similar situation, where QWebEngineProcess.exes would stay open after our application closed. It turned out, we did not properly specify the parent for our custom page for it to be autodeleted with the view on destruction! Hope this helps someone to avoid some debugging :-)