Search code examples
pythonpyqtparent-childpyqt5qwebengineview

Odd behavior when trying to assign parentless widget in Qt


I have the following code:

from PyQt5 import QtWebEngineWidgets, QtWidgets


class Q(QtWebEngineWidgets.QWebEnginePage):
    pass


app = QtWidgets.QApplication([])

l = QtWebEngineWidgets.QWebEngineView()
print(type(l.page()))

l.setPage(Q(l))
print(type(l.page()))

p = Q()
l.setPage(p)
print(type(l.page()))

l.setPage(Q())
print(type(l.page()))

app.exec_()

And here's the output:

<class 'PyQt5.QtWebEngineWidgets.QWebEnginePage'>
<class '__main__.Q'>
<class '__main__.Q'>
<class 'PyQt5.QtWebEngineWidgets.QWebEnginePage'>

First I create a new instance of the QWebEnginePage-derived Q-class, set the view as its parent and assign it as the view's page. It works as expected.

Next I do the same, but without giving the parent. Instead, I create a temporary variable that holds a new Q and assign it. It still works as expected.

Finally, I directly assign a dynamically created parentless Q. For some reason this doesn't work and the page resets to the default class.

Why does this happen?


Solution

  • The QWebEngineView does not take ownership of the QWebEnginePage, and it does not re-parent it.

    For the third example, the page has no parent, but it's kept alive because python holds a global reference to it.

    For the last example, there is no parent and no external reference, so the page gets garbage-collected before it is set. It is effectively equivalent to calling setPage(None), which will remove the previously set page and restore the default.