2

I used to do it by attaching an object

self.page().mainFrame().addToJavaScriptWindowObject("js_interface", self.jsi)

In 5.7 I do:

self.page().setWebChannel(self.jsi)

But I understandibly get a JavaScript error when I try to access exposed functions:

js: Uncaught ReferenceError: js_interface is not defined

Googling around I found that I should use qwebchannel.js, but I couldn't find the file or instructions on how to use it anywhere (there was some info, but only in some examples provided when installing QT, not PyQT).

3 Answers 3

12

You can include qwebchannel.js into html page using the script tag:

<script src="qrc:///qtwebchannel/qwebchannel.js"></script>

Then, create a web channel on the python side:

from PyQt5.QtCore import QObject, pyqtSlot
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView

class CallHandler(QObject):
    @pyqtSlot()
    def test(self):
        print('call received')

view = QWebEngineView()
channel = QWebChannel()
handler = CallHandler()
channel.registerObject('handler', handler)
view.page().setWebChannel(channel)

JS code that interacts with the web channel:

new QWebChannel(qt.webChannelTransport, function (channel) {
    window.handler = channel.objects.handler;
    window.handler.test();
});
Sign up to request clarification or add additional context in comments.

2 Comments

As addition: Please make sure that the channel, handler and so on are not garbage collected. I was initializing them in in class-method and I could not figure out why it did not work or even segfaulted. The trick was to keep a reference to channel and handler in the class (e.g. self.handler = CallHandler() etc
@devsnd , I was getting Segmentation fault (core dumped) for weeks and I was nearly on verge of giving up on the project , you have not Idea how much your comment has helped me. Thank You!
1

Take a look at this page. It contains a useful example (in c++ but easily translatable into python).

First of all, you have to use a websocket to communicate from html to your app and viceversa.

Then you can set up your QWebChannel.

Comments

0

I think it's big drawback, JS cannot directly communicate with Python in PyQT5.9+ like it used to with "addToJavaScriptWindowObject" command. And using websockets... what if Firewall is heavy and all ports blocked.

I guess I will rely on simple callback (long pooling type from Python to JS checking for changes/commands) method and no QTWebChannel usage.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.