PySide6 通过 QWebEngineView 组件与 JavaScript 实现双向通信

在 PySide6 中,可以通过 QWebEngineView 组件与 JavaScript 实现双向通信。这种通信主要通过以下两种方式实现:

  1. JavaScript 调用 Python :通过 QWebChannel 注册 Python 对象,使 JavaScript 可以调用其方法
  2. 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())

代码解析

  1. 通信桥梁 (Bridge 类)

    • 继承自 QObject,用于在 Python 和 JavaScript 之间传递消息
    • from_js 方法:使用 @Slot 装饰器,允许 JavaScript 调用
    • send_to_js 信号:用于从 Python 向 JavaScript 发送消息
  2. Web 通道 (QWebChannel)

    • 负责建立 Python 和 JavaScript 之间的通信通道
    • 通过 registerObject 方法将 Python 对象暴露给 JavaScript
  3. JavaScript 部分

    • 使用 qwebchannel.js 库建立与 Python 的连接
    • 通过 bridge 对象调用 Python 方法
    • 注册回调函数接收 Python 发送的消息
  4. 双向通信

    • JavaScript 调用 Python:通过 bridge.from_js() 方法
    • Python 调用 JavaScript:通过 send_to_js 信号触发 JavaScript 回调

运行此示例后,实现:

  • 在输入框中输入文本并点击按钮向 Python 发送消息
  • 看到 Python 定期向 JavaScript 发送消息
  • 在控制台查看 Python 收到的消息
相关推荐
Wiktok2 天前
Pyside6加载本地html文件并实现与Javascript进行通信
前端·javascript·html·pyside6
mahuifa4 个月前
Qt图表绘制(QtCharts)- 性能优化(13)
python·qt·pyside6·开发经验·qtchart
mahuifa4 个月前
(7)python开发经验
python·qt·pyside6·开发经验
不爱吃鱼的猫-5 个月前
Pyside6 开发 使用Qt Designer
python·pyqt·pyside6
不爱吃鱼的猫-5 个月前
PySide6控件:QFont设置、QColor调色板、QPixmap图像处理与QCursor光标自定义
python·pyqt·个人开发·pyside6
不爱吃鱼的猫-5 个月前
Pyside6 信号与槽
python·个人开发·pyside6
Logintern095 个月前
分享一个Pyside6实现web数据展示界面的效果图
python·学习·web·数据·pyside6
人才程序员8 个月前
【PySide6快速入门】QFileDialog 文件选择对话框
c语言·c++·qt·microsoft·pyside6·python3.11
jyl_sh8 个月前
使用Python和Qt6创建GUI应用程序--前言
python·mvc·客户端·pyside6