如何在创建 QApplication 后导入 QtWebEngineWidgets
How to import QtWebEngineWidgets after QApplication has been created
我正在尝试解决这个错误:
QtWebEngineWidgets must be imported before a QCoreApplication instance is created.
这是不言自明的,但我正在尝试制作一个在 iPython 中使用的 GUI,它可以在创建 QApplication 实例后导入。
我如何解决这个错误并创建一个 PyQt5 GUI,它可以显示 HTML 页面,并且即使在用户使用 QApplication 实例(例如通过 matplotlib)之后也能被导入?
我试过了,但仍然出现同样的错误:
from PyQt5 import QtWidgets
import seaborn as sns
sns.boxplot([1],[1])
QtWidgets.QApplication.instance().quit()
from PyQt5 import QtWidgets, QtWebEngineWidgets
有解决此问题的 hack,但它可能并不完全可靠。
想法是删除对 QApplication
(如果存在)的所有 C++ 引用,以便可以安全地导入网络引擎模块。这可以使用 sip 来完成,但有一些注意事项:如果第三方模块保存了对旧 QApplication
的 python 引用然后尝试使用它,它会引发这样的错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QApplication has been deleted
实际上,很难预测这种情况发生的可能性有多大,因为您无法对其他 python 库的编写方式进行立法。下面脚本中的 webengine_hack
函数尝试尽可能地减少上述问题的可能性:
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()
我正在尝试解决这个错误:
QtWebEngineWidgets must be imported before a QCoreApplication instance is created.
这是不言自明的,但我正在尝试制作一个在 iPython 中使用的 GUI,它可以在创建 QApplication 实例后导入。
我如何解决这个错误并创建一个 PyQt5 GUI,它可以显示 HTML 页面,并且即使在用户使用 QApplication 实例(例如通过 matplotlib)之后也能被导入?
我试过了,但仍然出现同样的错误:
from PyQt5 import QtWidgets
import seaborn as sns
sns.boxplot([1],[1])
QtWidgets.QApplication.instance().quit()
from PyQt5 import QtWidgets, QtWebEngineWidgets
有解决此问题的 hack,但它可能并不完全可靠。
想法是删除对 QApplication
(如果存在)的所有 C++ 引用,以便可以安全地导入网络引擎模块。这可以使用 sip 来完成,但有一些注意事项:如果第三方模块保存了对旧 QApplication
的 python 引用然后尝试使用它,它会引发这样的错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QApplication has been deleted
实际上,很难预测这种情况发生的可能性有多大,因为您无法对其他 python 库的编写方式进行立法。下面脚本中的 webengine_hack
函数尝试尽可能地减少上述问题的可能性:
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()