0

I am working on a PyQt5 application that uses QWebEngineView, and I want to call a Python function from JavaScript. I found an example here, and I've implemented the code as follows:

main.py

from os.path import abspath, dirname, join
import sys

from PyQt5.QtCore import QUrl, pyqtSlot 
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from PyQt5.QtWebChannel import QWebChannel

HTML_PATH = join(dirname(abspath(__file__)), 'page.html')

class WebEngineView(QWebEngineView):
    def __init__(self):
        super().__init__()

    @pyqtSlot()
    def foo(self):
        print('bar')



class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.browser = WebEngineView()
        self.channel = QWebChannel()
        self.channel.registerObject('backend', self.browser)
        self.browser.page().setWebChannel(self.channel)

        self.browser.setPage(WebEnginePage(self.browser))
        url = QUrl.fromLocalFile(HTML_PATH)
        self.browser.load(url)

        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)
        layout.addWidget(self.browser)
        self.setCentralWidget(central_widget)
        

class WebEnginePage(QWebEnginePage):
    def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
        print(f"[JS Message] Line-{lineNumber}:",message)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.showMaximized()
    sys.exit(app.exec_())

page.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
    <h1>PyQt5 and QWebEngineView Example</h1>
    <button onclick="callPython()">Call Python</button>
    <script>
        function callPython(){
            backend.foo();
        }
        var backend;
        new QWebChannel(qt.webChannelTransport, function (channel) {
            backend = channel.objects.backend;
        });
    </script>
</body>
</html>

However, I am encountering the following error in my browser console:

Uncaught ReferenceError: qt is not defined

Python version 3.8.0, PyQt5==5.15.10, PyQtWebEngine==5.15.6

3
  • 1
    You're setting a new QWebEnginePage, but you set the channel on the previous one. Move self.browser.setPage() before self.browser.page().setWebChannel(self.channel). Commented Dec 10, 2023 at 13:04
  • @musicamante Thank you. That fixed the error. Now I'm getting Property 'X'' of object 'WebEngineView' has no notify signal and is not constant, value updates in HTML will be broken! warnings. What causes it? Commented Dec 10, 2023 at 13:15
  • 1
    See this post: Warnings when instantiating QWebChannel object in javascript. Either install a dummy message handler (QtCore.qInstallMessageHandler(lambda *args: None)) or use a separate backend (subclassing QObject) and eventually implement proper signals to communicate with the view. Commented Dec 10, 2023 at 13:31

0

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.