如何在QWebEngineView的文档完全加载前运行JavaScript代码
在QWebEngineView中实现页面脚本执行前的JS注入
你之前使用loadStarted、loadProgress事件注入脚本不生效,是因为这两个事件触发时调用runJavaScript的任务会被Qt排入队列,等待页面上下文完全初始化、页面自带脚本执行完成后才会运行,无法满足前置执行的需求。
Qt 5.10及以上版本已经内置了对应Page.addScriptToEvaluateOnNewDocument的原生能力,通过QWebEngineScript配置注入时机即可实现需求,具体实现方式如下:
- 构造
QWebEngineScript实例,将注入时机设置为DocumentCreation,该时机正好对应DOM构造完成、页面自带脚本执行前的时间节点 - 将配置好的脚本添加到页面对象的脚本集合中,后续所有新页面加载都会自动在指定时机执行该脚本,无需绑定页面加载事件
PyQt/PySide 示例代码
from PyQt5.QtCore import QUrl from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineScript view = QWebEngineView() target_page = view.page() # 配置注入脚本 pre_inject_script = QWebEngineScript() # 填写你需要执行的JS代码 pre_inject_script.setSourceCode(""" window.injectedFlag = 'executed before page scripts'; console.log('前置注入脚本执行完成'); """) # 设置注入时机为文档创建完成、页面脚本执行前 pre_inject_script.setInjectionPoint(QWebEngineScript.DocumentCreation) # 设置运行上下文:MainWorld代表和页面脚本共享上下文,需要隔离可改为ApplicationWorld pre_inject_script.setWorldId(QWebEngineScript.MainWorld) # 设置是否在页面的所有子iframe中都执行 pre_inject_script.setRunsOnSubFrames(True) # 将脚本加入页面的脚本集合 target_page.scripts().insert(pre_inject_script) # 正常加载目标页面即可 view.load(QUrl("https://example.com"))
C++ 示例代码
#include <QWebEngineView> #include <QWebEnginePage> #include <QWebEngineScript> #include <QUrl> QWebEngineView *view = new QWebEngineView; QWebEnginePage *targetPage = view->page(); QWebEngineScript preInjectScript; preInjectScript.setSourceCode(R"( window.injectedFlag = 'executed before page scripts'; console.log('前置注入脚本执行完成'); )"); preInjectScript.setInjectionPoint(QWebEngineScript::DocumentCreation); preInjectScript.setWorldId(QWebEngineScript::MainWorld); preInjectScript.setRunsOnSubFrames(true); targetPage->scripts().insert(preInjectScript); view->load(QUrl("https://example.com"));
如果需要移除已注入的脚本,调用target_page.scripts().remove(pre_inject_script)即可,也可以通过setName()给脚本设置唯一标识后按名称查找删除。
内容的提问来源于stack exchange,提问作者hldev
相关产品推荐
相关产品推荐

