这个问题我看了很多答案,但还是不明白。 我制作了两个文件,一个是带有 qrc 定义的 html + 新的 QWebChannel,第二个是带有 Object 和 QWebEngineView 的 python 文件。 JS 脚本似乎不起作用。它不会将通道对象绑定到本地变量。 我已经尝试了许多页面上的许多示例,寻找原生 QT 语言或 C++,我无法弄清楚。 找到 QWebChannel 定义和 qt 对象。
也许 PySide6 有什么问题?请帮我解决一下。
我的代码:
index.html
<head>
<title>Test</title>
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script type="text/javascript">
let dataSource = null
window.onload = function () {
alert('before') //works
new QWebChannel(qt.webChannelTransport, function (channel) {
alert('inside') //not working
dataSource = channel.objects.backend;
}
);
alert('after') //works
alert(dataSource) //null
}
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
主.py
import sys, os
from PySide6.QtCore import Signal, QUrl, Slot, QObject
from PySide6.QtWidgets import QMainWindow, QApplication, QVBoxLayout, QWidget
from PySide6.QtWebEngineWidgets import *
from PySide6.QtWebEngineCore import *
from PySide6.QtWebChannel import QWebChannel
class Backend(QObject):
@Slot(result=int)
def getValue(self):
return 1
@Slot(int)
def printValue(self, val):
print(val)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow,self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
backend = Backend()
channel = QWebChannel()
channel.registerObject("backend", backend)
self.browser.page().setWebChannel(channel)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QUrl.fromLocalFile(filename)
self.browser.load(url)
self.setCentralWidget(self.browser)
self.resize(1200,900)
self.show()
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
更新:
我扩展了视图,添加了开发工具和 jquery 来检查对象 - 这就是我所拥有的:
更新2: 我删除了 PySide6,安装了 PyQt5 并使用了这里的示例: 如何使用QWebChannel从python接收数据到js?
一切正常:/ 我花了一整天的时间来弄清楚。我不知道为什么它不起作用。
我最近遇到了同样的问题,结果发现QWebChannel无法在QMainWindow内工作。按照这个示例,我尝试了解 QWebChannel 如何与 PySide6 配合使用。当然,下面的示例可以按预期工作:
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script type="text/javascript">
var backend = null;
window.onload = function()
{
new QWebChannel(qt.webChannelTransport, function(channel) {
backend = channel.objects.backend;
var x = {a: "1000", b: ["Hello", "From", "JS"]}
backend.getRef(JSON.stringify(x), function(y) {
js_obj = JSON.parse(y);
js_obj["f"] = false;
backend.printRef(JSON.stringify(js_obj));
});
});
}
</script>
</head>
</html>
import json
from PySide6 import QtCore, QtWidgets, QtWebEngineWidgets, QtWebChannel
class Backend(QtCore.QObject):
@QtCore.Slot(str, result=str)
def getRef(self, o):
print("inside getRef", o)
py_obj = json.loads(o)
py_obj["c"] = ("Hello", "from", "Python")
return json.dumps(py_obj)
@QtCore.Slot(str)
def printRef(self, o):
py_obj = json.loads(o)
print("inside printRef", py_obj)
if __name__ == "__main__":
import os
import sys
app = QtWidgets.QApplication(sys.argv)
backend = Backend()
view = QtWebEngineWidgets.QWebEngineView()
channel = QtWebChannel.QWebChannel()
view.page().setWebChannel(channel)
channel.registerObject("backend", backend)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QtCore.QUrl.fromLocalFile(filename)
view.load(url)
view.show()
sys.exit(app.exec())
但是,当我尝试将 QWebChannel 引入 QMainWindow 时,它不起作用:
import json
import os
import sys
from PySide6.QtCore import Slot, QUrl, QObject
from PySide6 import QtWebChannel
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PySide6.QtWebEngineWidgets import QWebEngineView
class Backend(QObject):
@Slot(str, result=str)
def getRef(self, o):
print("inside getRef", o)
py_obj = json.loads(o)
py_obj["c"] = ("Hello", "from", "Python")
return json.dumps(py_obj)
@Slot(str)
def printRef(self, o):
py_obj = json.loads(o)
print("inside printRef", py_obj)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.widget = QWidget()
self.browser = QWebEngineView()
backend = Backend()
channel = QtWebChannel.QWebChannel()
self.browser.page().setWebChannel(channel)
channel.registerObject("backend", backend)
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QUrl.fromLocalFile(filename)
self.browser.load(url)
self.layout = QVBoxLayout()
self.layout.addWidget(self.browser)
self.setLayout(self.layout)
self.setCentralWidget(self.widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
我找到的解决方案是引入 QWebChannel,它的工作原理与上面的第一个 Python 代码相同。
import json
import os
import sys
from PySide6.QtCore import Slot, QUrl, QObject
from PySide6 import QtWebChannel
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PySide6.QtWebEngineWidgets import QWebEngineView
class Backend(QObject):
@Slot(str, result=str)
def getRef(self, o):
print("inside getRef", o)
py_obj = json.loads(o)
py_obj["c"] = ("Hello", "from", "Python")
return json.dumps(py_obj)
@Slot(str)
def printRef(self, o):
py_obj = json.loads(o)
print("inside printRef", py_obj)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.widget = QWidget()
self.browser = QWebEngineView()
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "index.html")
url = QUrl.fromLocalFile(filename)
self.browser.load(url)
self.layout = QVBoxLayout()
self.layout.addWidget(self.browser)
self.setLayout(self.layout)
self.setCentralWidget(self.widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
backend = Backend()
channel = QtWebChannel.QWebChannel()
window.browser.page().setWebChannel(channel)
channel.registerObject("backend", backend)
window.show()
app.exec()
我不知道为什么会这样,我希望其他人可以对此提供一些见解。