在 PySide6 中,可以通过 QWebEngineView
组件与 JavaScript 实现双向通信。这种通信主要通过以下两种方式实现:
- JavaScript 调用 Python :通过
QWebChannel
注册 Python 对象,使 JavaScript 可以调用其方法 - Python 调用 JavaScript :通过
runJavaScript()
方法执行 JavaScript 代码

下面是一个完整的示例,展示了 PySide6 与 JavaScript 的双向通信实现:
python
import sys
# QtCore 模块提供核心功能:
# QObject: 所有Qt对象的基类,提供信号槽机制
# Slot: 装饰器,用于定义可从QML或JavaScript调用的方法
# Signal: 用于定义信号,实现对象间通信
# QTimer: 定时器,用于定时执行任务
from PySide6.QtCore import QObject, Slot, Signal, QTimer
# QtWidgets 模块提供GUI组件:
# QApplication: 应用程序主类,管理应用程序的控制流和设置
from PySide6.QtWidgets import QApplication
# QtWebEngineWidgets 模块提供Web视图组件:
# QWebEngineView: 用于显示网页内容的可视化组件
from PySide6.QtWebEngineWidgets import QWebEngineView
# QtWebEngineCore 模块提供Web引擎核心功能:
# QWebEnginePage: 管理Web内容、处理导航和与网页交互
from PySide6.QtWebEngineCore import QWebEnginePage
# QtWebChannel 模块提供Qt与Web内容通信功能:
# QWebChannel: 实现Qt C++/Python代码与JavaScript之间的通信
from PySide6.QtWebChannel import QWebChannel
# 创建供JavaScript调用的Python对象
class Bridge(QObject):
# 定义信号,用于向JavaScript发送消息
send_to_js = Signal(str)
@Slot(str, result=str)
def from_js(self, message):
"""接收来自JavaScript的消息并返回响应"""
print(f"收到JavaScript消息: {message}")
return f"Python已收到: {message}"
def send_message(self, message):
"""发送消息到JavaScript"""
self.send_to_js.emit(message)
if __name__ == "__main__":
app = QApplication(sys.argv)
# 创建WebView
view = QWebEngineView()
# 创建通道并注册桥梁对象
channel = QWebChannel()
bridge = Bridge()
channel.registerObject("bridge", bridge)
# 设置页面并关联通道
page = QWebEnginePage()
page.setWebChannel(channel)
view.setPage(page)
# 定义HTML内容,包含JavaScript代码
html = '''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PySide6与JS通信</title>
<!-- qtwebchannel.js 是PySide6提供的JavaScript库,用于实现Qt Python代码与JavaScript代码之间的通信 -->
<!-- "qrc:///" 是Qt资源系统的URL协议,指向内置的Qt资源 -->
<!-- 这个脚本提供了QWebChannel API,使JavaScript能够访问通过QWebChannel注册的Python对象 -->
<!-- 在这个例子中,它允许JavaScript代码调用Python中定义的Bridge对象的方法和接收其发送的信号 -->
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
</head>
<body>
<h1>PySide6与JavaScript通信示例</h1>
<div>
<input type="text" id="messageInput" placeholder="输入要发送的消息">
<button onclick="sendToPython()">发送到Python</button>
</div>
<div id="pythonResponse"></div>
<div id="pythonMessages"></div>
<script>
// 等待WebChannel初始化
var bridge;
new QWebChannel(qt.webChannelTransport, function(channel) {
bridge = channel.objects.bridge;
console.log("连接到Python桥接对象");
// 注册接收Python消息的回调
bridge.send_to_js.connect(function(message) {
const div = document.getElementById('pythonMessages');
div.innerHTML += `<p>Python发送: ${message}</p>`;
});
// 测试向Python发送消息
bridge.from_js("Hello from JavaScript!", function(response) {
document.getElementById('pythonResponse').innerHTML =
`<p>Python响应: ${response}</p>`;
});
});
// 向Python发送消息的函数
function sendToPython() {
const input = document.getElementById('messageInput');
const message = input.value;
if (bridge && message) {
bridge.from_js(message, function(response) {
document.getElementById('pythonResponse').innerHTML =
`<p>Python响应: ${response}</p>`;
input.value = '';
});
}
}
</script>
</body>
</html>
'''
# 加载HTML内容
view.setHtml(html)
view.resize(800, 600)
view.show()
# 示例:Python主动向JavaScript发送消息
def send_periodic_messages():
bridge.send_message("这是来自Python的消息")
# 1秒后再次发送
app.sendPostedEvents(None, 0)
app.processEvents()
QTimer.singleShot(1000, send_periodic_messages)
# QTimer已在文件顶部导入,无需再次导入
QTimer.singleShot(2000, send_periodic_messages)
sys.exit(app.exec())
代码解析
-
通信桥梁 (Bridge 类):
- 继承自
QObject
,用于在 Python 和 JavaScript 之间传递消息 from_js
方法:使用@Slot
装饰器,允许 JavaScript 调用send_to_js
信号:用于从 Python 向 JavaScript 发送消息
- 继承自
-
Web 通道 (QWebChannel):
- 负责建立 Python 和 JavaScript 之间的通信通道
- 通过
registerObject
方法将 Python 对象暴露给 JavaScript
-
JavaScript 部分:
- 使用
qwebchannel.js
库建立与 Python 的连接 - 通过
bridge
对象调用 Python 方法 - 注册回调函数接收 Python 发送的消息
- 使用
-
双向通信:
- JavaScript 调用 Python:通过
bridge.from_js()
方法 - Python 调用 JavaScript:通过
send_to_js
信号触发 JavaScript 回调
- JavaScript 调用 Python:通过
运行此示例后,实现:
- 在输入框中输入文本并点击按钮向 Python 发送消息
- 看到 Python 定期向 JavaScript 发送消息
- 在控制台查看 Python 收到的消息