网站建设总结材料2021营业执照年检网上申报
2026/2/22 10:54:48 网站建设 项目流程
网站建设总结材料,2021营业执照年检网上申报,wordpress备份插件中文,广东各地最新病例使用 QWebChannel 实现 JS 与 C 双向通信#xff08;超详细 踩坑总结 Demo#xff09; 在基于 QWebEngine 的项目中#xff0c;要让 前端 JavaScript 与 后端 C 互相通信#xff0c;是非常关键的能力。 Qt 官方提供的方案就是 QWebChannel#xff0c;它能让你像调用本地…使用 QWebChannel 实现 JS 与 C 双向通信超详细 踩坑总结 Demo在基于QWebEngine的项目中要让前端 JavaScript与后端 C互相通信是非常关键的能力。 Qt 官方提供的方案就是QWebChannel它能让你像调用本地对象一样从 JS 访问 C并且支持信号/槽、异步回调等。但实际项目中常见各种问题JS 侧无法拿到对象信号不触发跨线程导致闪退对象销毁后 JS 仍然在调用Page/Page再创建导致 channel 失效本文将带你彻底搞懂 QWebChannel 的机制避坑并给出可运行的 Demo。一、QWebChannel 的通信原理JS 与 C 的交互流程如下C QObject ←→ WebChannel Transport (QWebEngine) ←→ JS 对象实际通信依赖两部分① C 侧QObject QWebChannelQObject 必须继承自 QObject想暴露给 JS 的属性/方法必须加 Q_INVOKABLE 或 Q_PROPERTY信号可以直接给 JS 发送事件将 QObject 注册进 QWebChannelchannel-registerObject(bridge, myBridgeObject);② JS 侧qwebchannel.js网页加载后必须初始化new QWebChannel(qt.webChannelTransport, function(channel) { window.bridge channel.objects.bridge; });然后// 调用 C bridge.sendMessage(hello); // 接收 C 信号 bridge.messageChanged.connect(function(msg){ console.log(C emit:, msg); });二、一个可跑的双向通信 Demo最小可运行1. C 端代码bridge.h#pragma once #include QObject class Bridge :public QObject { Q_OBJECT public: explicit Bridge(QObject* parent nullptr) : QObject(parent) {} // JS 调用 C Q_INVOKABLE void sendMessage(const QString msg) { qDebug() JS 调用 C msg; emit messageChanged(C 收到 msg); } signals: // C → JS void messageChanged(const QString msg); };mainwindow.cpp#include mainwindow.h #include QWebEngineView #include QWebEnginePage #include QWebChannel MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { auto* view new QWebEngineView(this); auto* page new QWebEnginePage(this); view-setPage(page); setCentralWidget(view); // 创建 C 对象 auto* bridge new Bridge(this); // 创建 QWebChannel auto* channel new QWebChannel(this); channel-registerObject(bridge, bridge); page-setWebChannel(channel); view-load(QUrl(qrc:/index.html)); // 模拟 3 秒后给 JS 发消息 QTimer::singleShot(3000, [bridge]() { emit bridge-messageChanged(来自 C 的问候); }); }2. 前端index.html!DOCTYPE html html head meta charsetUTF-8 / script srcqrc:///qtwebchannel/qwebchannel.js/script /head body h2QWebChannel Demo/h2 input idmsg placeholder发送给 C 的消息 button onclickcallCpp()发送/button p idlog/p script new QWebChannel(qt.webChannelTransport, function (channel) { window.bridge channel.objects.bridge; // C → JS bridge.messageChanged.connect(function (msg) { log(收到 C msg); }); }); function callCpp() { const msg document.getElementById(msg).value; bridge.sendMessage(msg); } function log(msg) { document.getElementById(log).innerHTML msg br; } /script /body /html这个 Demo 能实现JS 调 CC 调 JS信号异步通信页面加载自动初始化 WebChannel三、QWebChannel 常见问题与避坑指南非常重要1. JS 侧总是拿不到对象undefined典型错误console.log(bridge); // undefined正确做法所有 JS 调用必须在 QWebChannel 初始化之后new QWebChannel(qt.webChannelTransport, function(channel){ window.bridge channel.objects.bridge; });⚠不要在window.onload或顶层就调用 bridge。2. 跨线程访问导致崩溃最常见若你把Bridge放到子线程会直接崩溃。原因 QWebChannel 通信必须在 UI / WebEngine 所在线程使用否则 QObject 会被跨线程访问。正确方案bridge 必须在主线程如果你需要跨线程可在 Bridge 中封装信号转发Q_INVOKABLE void updateDataFromWorkerThread(const QString msg) { emit messageChanged(msg); // 仍然在主线程发 }Qt 会自动通过 queued connection 切回主线程。3. 页面重新加载后 channel 失效当你 reload()、load() 新页面后 之前的 JS 对象全部失效。必须在每次页面加载后重新建立 WebChannel示例connect(page, QWebEnginePage::loadFinished, this, [](bool ok){ if(ok) { page-setWebChannel(channel); } });⚠ Qt 5 必做Qt 6 已自动处理但建议仍写上。4.C 信号没有触发 JS 回调常见原因Bridge 对象被销毁信号签名不匹配JS 回调写在 WebChannel 初始化外部信号参数为自定义类型但未 qRegisterMetaType排查顺序C 打印信号是否发出JS log 是否有回调参数类型是否是 QVariant 能转的基本类型Bridge 是否挂靠在 MainWindow不要让其随 WebPage 销毁5.复杂参数对象/数组导致 JS 不接收支持QStringint/double/boolQVariantListJS ArrayQVariantMapJS Object但不支持 C 自定义结构体。解决QVariantMap obj; obj[name] Tom; obj[age] 12; emit messageChanged(obj);JSbridge.messageChanged.connect(function (obj) { console.log(obj.name); });五、总结QWebChannel 是 Qt WebEngine 中最可靠、最强大的前后端通信方式但需要注意Bridge 必须在主线程JS 必须在初始化回调后才能使用对象参数使用 QVariant 可序列化页面刷新后必须重新 setWebChannel跨线程调用需谨慎信号转发往期精彩回顾☞QWebEngine 实战自定义右键菜单、文件下载、Cookie 管理与 User-Agent 设置☞ QWebEngine 常用 API 全面梳理☞ QWebEngine 系列组件全关系梳理

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询