I'm writing an application in PyQt5 with webkit, and I'd like to access a Python class via JavaScript, inside a Web Worker.
My code, right now, does this:
import sys
import time
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWebKit import *
from PyQt5.QtWebKitWidgets import *
from PyQt5.QtWidgets import *
class Foo(QObject):
@pyqtSlot(result=str)
def bar(self):
return "baz"
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.view = QWebView(self)
self.setupInspector()
self.splitter = QSplitter(self)
self.splitter.setContentsMargins(800, 600, 0, 0)
self.splitter.setOrientation(Qt.Vertical)
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(800, 600, 0, 0)
self.layout.addWidget(self.splitter)
self.view.setLayout(self.layout)
self.foo = Foo(self)
self.view.page().mainFrame().addToJavaScriptWindowObject("foo", self.foo)
def setupInspector(self):
page = self.view.page()
page.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
self.webInspector = QWebInspector(self)
self.webInspector.setPage(page)
shortcut = QShortcut(self)
shortcut.setKey(Qt.Key_F12)
shortcut.activated.connect(self.toggleInspector)
self.webInspector.setVisible(False)
def toggleInspector(self):
self.webInspector.setVisible(not self.webInspector.isVisible())
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
window.view.load(QUrl(sys.argv[1]))
app.exec_()
if __name__ == "__main__":
main()
I load an html file, with a file:/
URL, like this: python3 browser.py file:/path-to-html/file.html
.
If I run the inspector, I can run foo.bar()
and I get "baz"
in return.
I'd like to run that inside a worker. If I create a javascript file with:
self.postMessage(foo.test());
and, in the inspector, I create a worker with:
var worker = new Worker('file:/same-path-as-the-html/file.js');
I get ReferenceError: Can't find variable: foo
, which, to me, seems like it means foo
wasn't added by Qt to the worker's scope.
Looks like it is indeed impossible to add Qt objects to web-workers, as they live in their own scope, while the Qt objects are always added to the page DOM.
See also this answer.