mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
In Qt6 QWebEnginepage and QWebEngineView can be imported separately before constructing the QApplication
This commit is contained in:
parent
1c0c88a2f9
commit
8eb7706b8a
@ -16,7 +16,7 @@ from qt.webengine import (
|
|||||||
from calibre import detect_ncpus as cpu_count, prints
|
from calibre import detect_ncpus as cpu_count, prints
|
||||||
from calibre.ebooks.oeb.polish.check.base import ERROR, WARN, BaseError
|
from calibre.ebooks.oeb.polish.check.base import ERROR, WARN, BaseError
|
||||||
from calibre.gui2 import must_use_qt
|
from calibre.gui2 import must_use_qt
|
||||||
from calibre.gui2.webengine import secure_webengine
|
from calibre.utils.webengine import secure_webengine
|
||||||
|
|
||||||
|
|
||||||
class CSSParseError(BaseError):
|
class CSSParseError(BaseError):
|
||||||
|
@ -31,7 +31,7 @@ from calibre.ebooks.pdf.image_writer import (
|
|||||||
)
|
)
|
||||||
from calibre.ebooks.pdf.render.serialize import PDFStream
|
from calibre.ebooks.pdf.render.serialize import PDFStream
|
||||||
from calibre.gui2 import setup_unix_signals
|
from calibre.gui2 import setup_unix_signals
|
||||||
from calibre.gui2.webengine import secure_webengine
|
from calibre.utils.webengine import secure_webengine
|
||||||
from calibre.srv.render_book import check_for_maths
|
from calibre.srv.render_book import check_for_maths
|
||||||
from calibre.utils.fonts.sfnt.container import Sfnt, UnsupportedFont
|
from calibre.utils.fonts.sfnt.container import Sfnt, UnsupportedFont
|
||||||
from calibre.utils.fonts.sfnt.errors import NoGlyphs
|
from calibre.utils.fonts.sfnt.errors import NoGlyphs
|
||||||
|
@ -12,7 +12,7 @@ from qt.webengine import QWebEnginePage, QWebEngineScript
|
|||||||
|
|
||||||
from calibre.ebooks.metadata.pdf import page_images
|
from calibre.ebooks.metadata.pdf import page_images
|
||||||
from calibre.gui2 import must_use_qt
|
from calibre.gui2 import must_use_qt
|
||||||
from calibre.gui2.webengine import secure_webengine
|
from calibre.utils.webengine import secure_webengine
|
||||||
from calibre.utils.filenames import atomic_rename
|
from calibre.utils.filenames import atomic_rename
|
||||||
from calibre.utils.monotonic import monotonic
|
from calibre.utils.monotonic import monotonic
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from qt.webengine import QWebEnginePage, QWebEngineScript, QWebEngineView
|
|||||||
|
|
||||||
from calibre.gui2 import error_dialog, gprefs, is_dark_theme, question_dialog
|
from calibre.gui2 import error_dialog, gprefs, is_dark_theme, question_dialog
|
||||||
from calibre.gui2.palette import dark_color, dark_link_color, dark_text_color
|
from calibre.gui2.palette import dark_color, dark_link_color, dark_text_color
|
||||||
from calibre.gui2.webengine import secure_webengine
|
from calibre.utils.webengine import secure_webengine
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
from calibre.utils.short_uuid import uuid4
|
from calibre.utils.short_uuid import uuid4
|
||||||
|
|
||||||
|
@ -33,10 +33,11 @@ from calibre.gui2.palette import dark_color, dark_link_color, dark_text_color
|
|||||||
from calibre.gui2.tweak_book import TOP, actions, current_container, editors, tprefs
|
from calibre.gui2.tweak_book import TOP, actions, current_container, editors, tprefs
|
||||||
from calibre.gui2.tweak_book.file_list import OpenWithHandler
|
from calibre.gui2.tweak_book.file_list import OpenWithHandler
|
||||||
from calibre.gui2.viewer.web_view import handle_mathjax_request, send_reply
|
from calibre.gui2.viewer.web_view import handle_mathjax_request, send_reply
|
||||||
from calibre.gui2.webengine import (
|
from calibre.utils.webengine import (
|
||||||
Bridge, RestartingWebEngineView, create_script, from_js, insert_scripts,
|
Bridge, create_script, from_js, insert_scripts,
|
||||||
secure_webengine, to_js
|
secure_webengine, to_js
|
||||||
)
|
)
|
||||||
|
from calibre.gui2.webengine import RestartingWebEngineView
|
||||||
from calibre.gui2.widgets2 import HistoryLineEdit2
|
from calibre.gui2.widgets2 import HistoryLineEdit2
|
||||||
from calibre.utils.ipc.simple_worker import offload_worker
|
from calibre.utils.ipc.simple_worker import offload_worker
|
||||||
from polyglot.builtins import iteritems
|
from polyglot.builtins import iteritems
|
||||||
|
@ -28,7 +28,8 @@ from calibre.ebooks.oeb.polish.report import (
|
|||||||
gather_data, CSSEntry, CSSFileMatch, MatchLocation, ClassEntry,
|
gather_data, CSSEntry, CSSFileMatch, MatchLocation, ClassEntry,
|
||||||
ClassFileMatch, ClassElement, CSSRule, LinkLocation)
|
ClassFileMatch, ClassElement, CSSRule, LinkLocation)
|
||||||
from calibre.gui2 import error_dialog, question_dialog, choose_save_file, open_url
|
from calibre.gui2 import error_dialog, question_dialog, choose_save_file, open_url
|
||||||
from calibre.gui2.webengine import secure_webengine, RestartingWebEngineView
|
from calibre.utils.webengine import secure_webengine
|
||||||
|
from calibre.gui2.webengine import RestartingWebEngineView
|
||||||
from calibre.gui2.tweak_book import current_container, tprefs, dictionaries
|
from calibre.gui2.tweak_book import current_container, tprefs, dictionaries
|
||||||
from calibre.gui2.tweak_book.widgets import Dialog
|
from calibre.gui2.tweak_book.widgets import Dialog
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
|
@ -18,7 +18,7 @@ from calibre import prints, random_user_agent
|
|||||||
from calibre.constants import cache_dir
|
from calibre.constants import cache_dir
|
||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
from calibre.gui2.viewer.web_view import apply_font_settings, vprefs
|
from calibre.gui2.viewer.web_view import apply_font_settings, vprefs
|
||||||
from calibre.gui2.webengine import create_script, insert_scripts, secure_webengine
|
from calibre.utils.webengine import create_script, insert_scripts, secure_webengine
|
||||||
from calibre.gui2.widgets2 import Dialog
|
from calibre.gui2.widgets2 import Dialog
|
||||||
|
|
||||||
vprefs.defaults['lookup_locations'] = [
|
vprefs.defaults['lookup_locations'] = [
|
||||||
|
@ -30,10 +30,11 @@ from calibre.gui2 import choose_images, error_dialog, safe_open_url, config
|
|||||||
from calibre.gui2.viewer import link_prefix_for_location_links, performance_monitor
|
from calibre.gui2.viewer import link_prefix_for_location_links, performance_monitor
|
||||||
from calibre.gui2.viewer.config import viewer_config_dir, vprefs
|
from calibre.gui2.viewer.config import viewer_config_dir, vprefs
|
||||||
from calibre.gui2.viewer.tts import TTS
|
from calibre.gui2.viewer.tts import TTS
|
||||||
from calibre.gui2.webengine import (
|
from calibre.utils.webengine import (
|
||||||
Bridge, RestartingWebEngineView, create_script, from_js, insert_scripts,
|
Bridge, create_script, from_js, insert_scripts,
|
||||||
secure_webengine, to_js
|
secure_webengine, to_js
|
||||||
)
|
)
|
||||||
|
from calibre.gui2.webengine import RestartingWebEngineView
|
||||||
from calibre.srv.code import get_translations_data
|
from calibre.srv.code import get_translations_data
|
||||||
from calibre.utils.localization import localize_user_manual_link
|
from calibre.utils.localization import localize_user_manual_link
|
||||||
from calibre.utils.serialize import json_loads
|
from calibre.utils.serialize import json_loads
|
||||||
|
@ -1,140 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
from qt.core import Qt, pyqtSignal
|
||||||
import json
|
from qt.webengine import QWebEnginePage, QWebEngineView
|
||||||
|
|
||||||
from qt.core import QObject, Qt, pyqtSignal
|
|
||||||
from qt.webengine import QWebEnginePage, QWebEngineScript, QWebEngineView, QWebEngineSettings
|
|
||||||
|
|
||||||
from calibre import prints
|
from calibre import prints
|
||||||
from calibre.utils.monotonic import monotonic
|
from calibre.utils.monotonic import monotonic
|
||||||
from calibre.utils.rapydscript import special_title
|
|
||||||
from polyglot.builtins import iteritems
|
|
||||||
|
|
||||||
|
|
||||||
def secure_webengine(view_or_page_or_settings, for_viewer=False):
|
|
||||||
s = view_or_page_or_settings.settings() if hasattr(
|
|
||||||
view_or_page_or_settings, 'settings') else view_or_page_or_settings
|
|
||||||
a = s.setAttribute
|
|
||||||
a(QWebEngineSettings.WebAttribute.PluginsEnabled, False)
|
|
||||||
if not for_viewer:
|
|
||||||
a(QWebEngineSettings.WebAttribute.JavascriptEnabled, False)
|
|
||||||
s.setUnknownUrlSchemePolicy(QWebEngineSettings.UnknownUrlSchemePolicy.DisallowUnknownUrlSchemes)
|
|
||||||
if hasattr(view_or_page_or_settings, 'setAudioMuted'):
|
|
||||||
view_or_page_or_settings.setAudioMuted(True)
|
|
||||||
a(QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows, False)
|
|
||||||
a(QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard, False)
|
|
||||||
# ensure javascript cannot read from local files
|
|
||||||
a(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, False)
|
|
||||||
a(QWebEngineSettings.WebAttribute.AllowWindowActivationFromJavaScript, False)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def insert_scripts(profile, *scripts):
|
|
||||||
sc = profile.scripts()
|
|
||||||
for script in scripts:
|
|
||||||
for existing in sc.find(script.name()):
|
|
||||||
sc.remove(existing)
|
|
||||||
for script in scripts:
|
|
||||||
sc.insert(script)
|
|
||||||
|
|
||||||
|
|
||||||
def create_script(
|
|
||||||
name, src, world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
|
|
||||||
injection_point=QWebEngineScript.InjectionPoint.DocumentReady,
|
|
||||||
on_subframes=True
|
|
||||||
):
|
|
||||||
script = QWebEngineScript()
|
|
||||||
if isinstance(src, bytes):
|
|
||||||
src = src.decode('utf-8')
|
|
||||||
script.setSourceCode(src)
|
|
||||||
script.setName(name)
|
|
||||||
script.setWorldId(world)
|
|
||||||
script.setInjectionPoint(injection_point)
|
|
||||||
script.setRunsOnSubFrames(on_subframes)
|
|
||||||
return script
|
|
||||||
|
|
||||||
|
|
||||||
from_js = pyqtSignal
|
|
||||||
|
|
||||||
|
|
||||||
class to_js(str):
|
|
||||||
|
|
||||||
def __call__(self, *a):
|
|
||||||
prints(f'WARNING: Calling {self.name}() before the javascript bridge is ready')
|
|
||||||
emit = __call__
|
|
||||||
|
|
||||||
|
|
||||||
class to_js_bound(QObject):
|
|
||||||
|
|
||||||
def __init__(self, bridge, name):
|
|
||||||
QObject.__init__(self, bridge)
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
def __call__(self, *args):
|
|
||||||
self.parent().page.runJavaScript('if (window.python_comm) python_comm._from_python({}, {})'.format(
|
|
||||||
json.dumps(self.name), json.dumps(args)), QWebEngineScript.ScriptWorldId.ApplicationWorld)
|
|
||||||
emit = __call__
|
|
||||||
|
|
||||||
|
|
||||||
class Bridge(QObject):
|
|
||||||
|
|
||||||
bridge_ready = pyqtSignal()
|
|
||||||
|
|
||||||
def __init__(self, page):
|
|
||||||
QObject.__init__(self, page)
|
|
||||||
self._signals = json.dumps(tuple({k for k, v in iteritems(self.__class__.__dict__) if isinstance(v, pyqtSignal)}))
|
|
||||||
self._signals_registered = False
|
|
||||||
page.titleChanged.connect(self._title_changed)
|
|
||||||
for k, v in iteritems(self.__class__.__dict__):
|
|
||||||
if isinstance(v, to_js):
|
|
||||||
v.name = k
|
|
||||||
|
|
||||||
@property
|
|
||||||
def page(self):
|
|
||||||
return self.parent()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ready(self):
|
|
||||||
return self._signals_registered
|
|
||||||
|
|
||||||
def _title_changed(self, title):
|
|
||||||
if title.startswith(special_title):
|
|
||||||
self._poll_for_messages()
|
|
||||||
|
|
||||||
def _register_signals(self):
|
|
||||||
self._signals_registered = True
|
|
||||||
for k, v in iteritems(self.__class__.__dict__):
|
|
||||||
if isinstance(v, to_js):
|
|
||||||
setattr(self, k, to_js_bound(self, k))
|
|
||||||
self.page.runJavaScript('python_comm._register_signals(' + self._signals + ')', QWebEngineScript.ScriptWorldId.ApplicationWorld)
|
|
||||||
self.bridge_ready.emit()
|
|
||||||
|
|
||||||
def _poll_for_messages(self):
|
|
||||||
self.page.runJavaScript('python_comm._poll()', QWebEngineScript.ScriptWorldId.ApplicationWorld, self._dispatch_messages)
|
|
||||||
|
|
||||||
def _dispatch_messages(self, messages):
|
|
||||||
try:
|
|
||||||
for msg in messages:
|
|
||||||
if isinstance(msg, dict):
|
|
||||||
mt = msg.get('type')
|
|
||||||
if mt == 'signal':
|
|
||||||
signal = getattr(self, msg['name'], None)
|
|
||||||
if signal is None:
|
|
||||||
prints('WARNING: No js-to-python signal named: ' + msg['name'])
|
|
||||||
else:
|
|
||||||
args = msg['args']
|
|
||||||
if args:
|
|
||||||
signal.emit(*args)
|
|
||||||
else:
|
|
||||||
signal.emit()
|
|
||||||
elif mt == 'qt-ready':
|
|
||||||
self._register_signals()
|
|
||||||
except Exception:
|
|
||||||
if messages:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
|
|
||||||
class RestartingWebEngineView(QWebEngineView):
|
class RestartingWebEngineView(QWebEngineView):
|
||||||
@ -161,29 +32,3 @@ class RestartingWebEngineView(QWebEngineView):
|
|||||||
self._last_reload_at = monotonic()
|
self._last_reload_at = monotonic()
|
||||||
self.render_process_restarted.emit()
|
self.render_process_restarted.emit()
|
||||||
prints('Restarting Qt WebEngine')
|
prints('Restarting Qt WebEngine')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
from calibre.gui2 import Application
|
|
||||||
from calibre.gui2.tweak_book.preview import WebPage
|
|
||||||
from qt.core import QMainWindow
|
|
||||||
app = Application([])
|
|
||||||
view = QWebEngineView()
|
|
||||||
page = WebPage(view)
|
|
||||||
view.setPage(page)
|
|
||||||
w = QMainWindow()
|
|
||||||
w.setCentralWidget(view)
|
|
||||||
|
|
||||||
class Test(Bridge):
|
|
||||||
s1 = from_js(object)
|
|
||||||
j1 = to_js()
|
|
||||||
t = Test(view.page())
|
|
||||||
t.s1.connect(print)
|
|
||||||
w.show()
|
|
||||||
view.setHtml('''
|
|
||||||
<p>hello</p>
|
|
||||||
''')
|
|
||||||
app.exec()
|
|
||||||
del t
|
|
||||||
del page
|
|
||||||
del app
|
|
||||||
|
@ -59,7 +59,7 @@ def compiler():
|
|||||||
|
|
||||||
from calibre import walk
|
from calibre import walk
|
||||||
from calibre.gui2 import must_use_qt
|
from calibre.gui2 import must_use_qt
|
||||||
from calibre.gui2.webengine import secure_webengine
|
from calibre.utils.webengine import secure_webengine
|
||||||
must_use_qt()
|
must_use_qt()
|
||||||
|
|
||||||
with lzma.open(P(COMPILER_PATH, allow_user_override=False)) as lzf:
|
with lzma.open(P(COMPILER_PATH, allow_user_override=False)) as lzf:
|
||||||
@ -340,7 +340,7 @@ def run_rapydscript_tests():
|
|||||||
from calibre.constants import FAKE_HOST, FAKE_PROTOCOL
|
from calibre.constants import FAKE_HOST, FAKE_PROTOCOL
|
||||||
from calibre.gui2 import must_use_qt
|
from calibre.gui2 import must_use_qt
|
||||||
from calibre.gui2.viewer.web_view import send_reply
|
from calibre.gui2.viewer.web_view import send_reply
|
||||||
from calibre.gui2.webengine import secure_webengine, insert_scripts, create_script
|
from calibre.utils.webengine import secure_webengine, insert_scripts, create_script
|
||||||
must_use_qt()
|
must_use_qt()
|
||||||
scheme = QWebEngineUrlScheme(FAKE_PROTOCOL.encode('ascii'))
|
scheme = QWebEngineUrlScheme(FAKE_PROTOCOL.encode('ascii'))
|
||||||
scheme.setSyntax(QWebEngineUrlScheme.Syntax.Host)
|
scheme.setSyntax(QWebEngineUrlScheme.Syntax.Host)
|
||||||
|
134
src/calibre/utils/webengine.py
Normal file
134
src/calibre/utils/webengine.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
|
import json
|
||||||
|
from qt.core import QObject, pyqtSignal
|
||||||
|
from qt.webengine import QWebEngineScript, QWebEngineSettings
|
||||||
|
|
||||||
|
from calibre.utils.rapydscript import special_title
|
||||||
|
|
||||||
|
|
||||||
|
def secure_webengine(view_or_page_or_settings, for_viewer=False):
|
||||||
|
s = view_or_page_or_settings.settings() if hasattr(
|
||||||
|
view_or_page_or_settings, 'settings') else view_or_page_or_settings
|
||||||
|
a = s.setAttribute
|
||||||
|
a(QWebEngineSettings.WebAttribute.PluginsEnabled, False)
|
||||||
|
if not for_viewer:
|
||||||
|
a(QWebEngineSettings.WebAttribute.JavascriptEnabled, False)
|
||||||
|
s.setUnknownUrlSchemePolicy(QWebEngineSettings.UnknownUrlSchemePolicy.DisallowUnknownUrlSchemes)
|
||||||
|
if hasattr(view_or_page_or_settings, 'setAudioMuted'):
|
||||||
|
view_or_page_or_settings.setAudioMuted(True)
|
||||||
|
a(QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows, False)
|
||||||
|
a(QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard, False)
|
||||||
|
# ensure javascript cannot read from local files
|
||||||
|
a(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, False)
|
||||||
|
a(QWebEngineSettings.WebAttribute.AllowWindowActivationFromJavaScript, False)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def insert_scripts(profile, *scripts):
|
||||||
|
sc = profile.scripts()
|
||||||
|
for script in scripts:
|
||||||
|
for existing in sc.find(script.name()):
|
||||||
|
sc.remove(existing)
|
||||||
|
for script in scripts:
|
||||||
|
sc.insert(script)
|
||||||
|
|
||||||
|
|
||||||
|
def create_script(
|
||||||
|
name, src, world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
|
||||||
|
injection_point=QWebEngineScript.InjectionPoint.DocumentReady,
|
||||||
|
on_subframes=True
|
||||||
|
):
|
||||||
|
script = QWebEngineScript()
|
||||||
|
if isinstance(src, bytes):
|
||||||
|
src = src.decode('utf-8')
|
||||||
|
script.setSourceCode(src)
|
||||||
|
script.setName(name)
|
||||||
|
script.setWorldId(world)
|
||||||
|
script.setInjectionPoint(injection_point)
|
||||||
|
script.setRunsOnSubFrames(on_subframes)
|
||||||
|
return script
|
||||||
|
|
||||||
|
|
||||||
|
from_js = pyqtSignal
|
||||||
|
|
||||||
|
|
||||||
|
class to_js(str):
|
||||||
|
|
||||||
|
def __call__(self, *a):
|
||||||
|
print(f'WARNING: Calling {self.name}() before the javascript bridge is ready')
|
||||||
|
emit = __call__
|
||||||
|
|
||||||
|
|
||||||
|
class to_js_bound(QObject):
|
||||||
|
|
||||||
|
def __init__(self, bridge, name):
|
||||||
|
QObject.__init__(self, bridge)
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __call__(self, *args):
|
||||||
|
self.parent().page.runJavaScript('if (window.python_comm) python_comm._from_python({}, {})'.format(
|
||||||
|
json.dumps(self.name), json.dumps(args)), QWebEngineScript.ScriptWorldId.ApplicationWorld)
|
||||||
|
emit = __call__
|
||||||
|
|
||||||
|
|
||||||
|
class Bridge(QObject):
|
||||||
|
|
||||||
|
bridge_ready = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, page):
|
||||||
|
QObject.__init__(self, page)
|
||||||
|
self._signals = json.dumps(tuple({k for k, v in self.__class__.__dict__.items() if isinstance(v, pyqtSignal)}))
|
||||||
|
self._signals_registered = False
|
||||||
|
page.titleChanged.connect(self._title_changed)
|
||||||
|
for k, v in self.__class__.__dict__.items():
|
||||||
|
if isinstance(v, to_js):
|
||||||
|
v.name = k
|
||||||
|
|
||||||
|
@property
|
||||||
|
def page(self):
|
||||||
|
return self.parent()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ready(self):
|
||||||
|
return self._signals_registered
|
||||||
|
|
||||||
|
def _title_changed(self, title):
|
||||||
|
if title.startswith(special_title):
|
||||||
|
self._poll_for_messages()
|
||||||
|
|
||||||
|
def _register_signals(self):
|
||||||
|
self._signals_registered = True
|
||||||
|
for k, v in self.__class__.__dict__.items():
|
||||||
|
if isinstance(v, to_js):
|
||||||
|
setattr(self, k, to_js_bound(self, k))
|
||||||
|
self.page.runJavaScript('python_comm._register_signals(' + self._signals + ')', QWebEngineScript.ScriptWorldId.ApplicationWorld)
|
||||||
|
self.bridge_ready.emit()
|
||||||
|
|
||||||
|
def _poll_for_messages(self):
|
||||||
|
self.page.runJavaScript('python_comm._poll()', QWebEngineScript.ScriptWorldId.ApplicationWorld, self._dispatch_messages)
|
||||||
|
|
||||||
|
def _dispatch_messages(self, messages):
|
||||||
|
try:
|
||||||
|
for msg in messages:
|
||||||
|
if isinstance(msg, dict):
|
||||||
|
mt = msg.get('type')
|
||||||
|
if mt == 'signal':
|
||||||
|
signal = getattr(self, msg['name'], None)
|
||||||
|
if signal is None:
|
||||||
|
print('WARNING: No js-to-python signal named: ' + msg['name'])
|
||||||
|
else:
|
||||||
|
args = msg['args']
|
||||||
|
if args:
|
||||||
|
signal.emit(*args)
|
||||||
|
else:
|
||||||
|
signal.emit()
|
||||||
|
elif mt == 'qt-ready':
|
||||||
|
self._register_signals()
|
||||||
|
except Exception:
|
||||||
|
if messages:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
Loading…
x
Reference in New Issue
Block a user