简体   繁体   中英

How to import QtWebEngineWidgets after QApplication has been created

I am trying to get around this error:

QtWebEngineWidgets must be imported before a QCoreApplication instance is created.

It is pretty self-explanatory, but I am trying to make a GUI to be used within iPython which may be imported after a QApplication instance has been created.

How can I get around this error and create a PyQt5 GUI that can show HTML pages and is able to be imported even after the user has used a QApplication instance (such as through matplotlib)?

I tried this but still get the same error:

from PyQt5 import QtWidgets
import seaborn as sns
sns.boxplot([1],[1])
QtWidgets.QApplication.instance().quit()
from PyQt5 import QtWidgets, QtWebEngineWidgets

There is a hack for working around this problem, but it may not be totally robust.

The idea is to delete all C++ references to the QApplication (if it exists), so that the web-engine module can be imported safely. This can be done using sip , but there are some caveats: if a third-party module has saved a python reference to the old QApplication and then tries to use it, it will raise an error like this:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QApplication has been deleted

In practice, it's hard to predict how likely this is to happen, since you cannot legislate for how other python libraries are written. The webengine_hack function in the script below tries to do as much as possible to reduce the likelihood of the problems mentioned above:

def webengine_hack():
    from PyQt5 import QtWidgets
    app = QtWidgets.QApplication.instance()
    if app is not None:
        import sip
        app.quit()
        sip.delete(app)
    import sys
    from PyQt5 import QtCore, QtWebEngineWidgets
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts)
    app = QtWidgets.qApp = QtWidgets.QApplication(sys.argv)
    return app

try:
    # just for testing
    from PyQt5 import QtWidgets
    app = QtWidgets.QApplication([''])
    from PyQt5 import QtWebEngineWidgets
except ImportError as exception:
    print('\nRetrying webengine import...')
    app = webengine_hack()
    from PyQt5 import QtWebEngineWidgets

view = QtWebEngineWidgets.QWebEngineView()
view.setHtml('<h1>Hello World</h1>')
view.show()

app.exec()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM