-
-
Save mphuie/63e964e9ff8ae25d16a949389392e0d7 to your computer and use it in GitHub Desktop.
| <html> | |
| <head> | |
| <script src="qrc:///qtwebchannel/qwebchannel.js"></script> | |
| <style> | |
| ::selection { | |
| background:transparent; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>Hi!</h1> | |
| </div> | |
| <script language="JavaScript"> | |
| new QWebChannel(qt.webChannelTransport, function (channel) { | |
| window.handler = channel.objects.handler; | |
| handler.test(function(retVal) { | |
| // console.error as console.log message don't show up in the python console | |
| console.error(JSON.stringify(retVal)); | |
| }) | |
| }); | |
| </script> | |
| </body> | |
| </html> |
| from PyQt5.QtWidgets import QApplication | |
| from PyQt5.QtWebEngineWidgets import QWebEngineView | |
| from PyQt5.QtWebChannel import QWebChannel | |
| from PyQt5.QtCore import QObject, pyqtSlot, QUrl, QVariant | |
| import os | |
| class CallHandler(QObject): | |
| @pyqtSlot(result=QVariant) | |
| def test(self): | |
| print('call received') | |
| return QVariant({"abc": "def", "ab": 22}) | |
| # take an argument from javascript - JS: handler.test1('hello!') | |
| @pyqtSlot(QVariant, result=QVariant) | |
| def test1(self, args): | |
| print('i got') | |
| print(args) | |
| return "ok" | |
| class WebView(QWebEngineView): | |
| def __init__(self): | |
| super(WebView, self).__init__() | |
| self.channel = QWebChannel() | |
| self.handler = CallHandler() | |
| self.channel.registerObject('handler', self.handler) | |
| self.page().setWebChannel(self.channel) | |
| file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "index.html")) | |
| local_url = QUrl.fromLocalFile(file_path) | |
| self.load(local_url) | |
| if __name__ == "__main__": | |
| app = QApplication([]) | |
| view = WebView() | |
| view.show() | |
| app.exec_() |
How to send data from Python to JS & back from JS to Python ...???
You can communicate between Python and JavaScript code in a QWebEngineView in PyQt5 using the WebChannel API.
To send data from Python to JavaScript:
- Create a QWebChannel object:
channel = QWebChannel()- Add a Python object to expose to JavaScript:
class PyObj:
def sendData(self, data):
print(f"Received from JS: {data}")
obj = PyObj()
channel.registerObject("pyObj", obj)- Set the channel on the QWebEngineView:
view.page().setWebChannel(channel)- In JavaScript, access the Python object:
var pyObj = new QWebChannel(qt.webChannelTransport);
pyObj.objects.pyObj.sendData("Data from JS!");- The
sendData()method in Python will be called.
To send data from Python to JavaScript, call a JavaScript function:
view.page().runJavaScript("jsFunction(data);")And define the jsFunction() in JavaScript:
function jsFunction(data) {
console.log(data);
}Hope this helps!
Thank you.
updated code for PySide6
<script language="JavaScript">
new QWebChannel(qt.webChannelTransport, function (channel) {
window.handler = channel.objects.handler;
handler.test(function(retVal) {
// console.error as console.log message don't show up in the python console
console.error(JSON.stringify(retVal));
})
handler.send_to_server('hello')
});
</script>import json
from PySide6.QtCore import QObject, Slot, QUrl, QJsonValue
class CallHandler(QObject):
@Slot(result=str)
def test(self):
print('call received')
return json.dumps({"abc": "def", "ab": 22})
# take an argument from javascript - JS: handler.send_to_server('hello!')
@Slot(QJsonValue)
def send_to_server(self, *args):
print('i got')
print(args)
for arg in args:
print(arg.toString())Thanks, this helps a lot. I am using it to communicate with an embedded webapp inside python (inside the QWebEngineView). This was necessary because the webapp was sandboxed by the older engine inside QWebEngineView. So far I was able to restore Save/Load and retaining webapp internal settings after connecting the webapp and the python program.
https://github.com/Krambrek/inject
here a small enhancement with added demonstration of injecting JS into (remote) page and how to run JS on Python side.
I got an error: