[PyQt] QWebEnginePage.LifecycleState doesn't work as expected in PyQt while the official C++ lifecyle example works
Phil Thompson
phil at riverbankcomputing.com
Sat Apr 18 12:33:06 BST 2020
On 17/04/2020 17:31, Coiby Xu wrote:
> Hi all,
>
> QT 5.14 introduced the QWebEnginePage.LifecycleState API. While playing
> with this API to try to suspend inactive browser tabs after certain
> time,
> I noticed an issue. Re-focusing on an inactive tab for the first time
> won't show the HTML content and a blank page is shown instead. But Web
> Inspector shows HTML source was already there and I can even to select
> an invisible element somewhere in the page to inspect it.
> Only switching to another tab then switching back will make the page
> shown.
>
> But the official WebEngine Lifecycle Example[1] which can be downloaded
> via [2]
> doesn't have this problem. The chosen tab will show the rendered page
> immediately.
>
> I wonder if this problem is caused by PyQt or I just miss something. I
> also
> output the chosen tab's life-cycle state in my code which shows the tab
> is
> indeed in LifecycleState.Active again.
>
> Discard tab#1, its lifecyclestate is LifecycleState.Discarded now
> Discard tab#2, its lifecyclestate is LifecycleState.Discarded now
> Tab#1 active, its lifecyle state is LifecycleState.Active now
> Tab#2 active, its lifecyle state is LifecycleState.Active now
>
> The following is my full code for suspending 2/3 inactive tabs,
>
> import sys
> from time import sleep
> from PyQt5.QtCore import *
> from PyQt5.QtWidgets import *
> from PyQt5.QtWebEngineWidgets import *
> import functools
>
> qurl = QUrl("http://example.com/")
>
> def discard_tab(webs, tab):
> for i, web in enumerate(webs):
> # skip the current tab
> if i == tab.currentIndex():
> continue
> page = web.page()
> page.setLifecycleState(QWebEnginePage.LifecycleState.Discarded)
> state = str(page.lifecycleState())
> print("Discard tab#{}, its lifecyclestate is {} now".format(i,
> state))
>
> @pyqtSlot(int)
> def current_tab(i):
> page = webs[i].page()
> state = str(page.lifecycleState())
> print("Tab#{} active, its lifecyle state is {} now".format(i,
> state))
>
> webs = []
> app = QApplication(sys.argv)
> tab = QTabWidget()
>
> def main():
> for i in range(3):
> web = QWebEngineView()
> web.load(qurl)
> i = tab.addTab(web, "load")
> web.loadFinished.connect(lambda _, i=i, web=web:
> tab.setTabText(i, web.page().title()))
> webs.append(web)
>
> tab.show()
>
> # trigger current_tab for chosen tab
> tab.currentChanged.connect(current_tab)
>
> # put all invisible tabs into LifecycleState.Dsicarded state after
> 2s
> timerCallback = functools.partial(discard_tab, webs=webs, tab=tab)
> timer = QTimer()
> timer.timeout.connect(timerCallback)
> timer.setSingleShot(True)
> timer.start(2000)
> sys.exit(app.exec_())
>
>
> if __name__ == '__main__':
> main()
>
> [1] https://doc.qt.io/qt-5/qtwebengine-webengine-lifecycle-example.html
> [2
> ]https://github.com/qt/qtwebengine/tree/5.14.2/examples/webengine/lifecycle
The only way I can determine if there is a PyQt-specific problem is to
compare it with a C++ equivalent of the above code that behaves
differently.
Phil
More information about the PyQt
mailing list