QWebEngineView中本地HTML的href链接点击无响应问题求助
问题描述
测试文件与目录结构
test.html内容
<!DOCTYPE html> <html> <head> </head> <body> <a style="padding-right:5px" target="_blank" href="data/">Datadir</a> </body> </html>
目录结构
test.html data\ a.txt b.txt
浏览器正常表现
通过Firefox和Chrome访问地址 file:///remote/us01home19/ktc/public_html/testLocalHref/test.html,点击Datadir链接可正常打开data目录。
问题代码(PySide2)
from PySide2 import QtCore, QtWidgets, QtWebEngineWidgets import os import sys class CustomWebEnginePage(QtWebEngineWidgets.QWebEnginePage): # Store second window. external_window = None def acceptNavigationRequest(self, url, _type, isMainFrame): print(url, _type, isMainFrame) if _type == QtWebEngineWidgets.QWebEnginePage.NavigationTypeLinkClicked: if not self.external_window: self.external_window = QtWebEngineWidgets.QWebEngineView() self.external_window.setUrl(url) self.external_window.show() return False return super().acceptNavigationRequest(url, _type, isMainFrame) class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.browser = QtWebEngineWidgets.QWebEngineView() self.browser.setPage(CustomWebEnginePage(self)) # self.browser.setUrl(QtCore.QUrl("https://code.visualstudio.com")) self.browser.setUrl(QtCore.QUrl("file:///remote/us01home19/ktc/public_html/testLocalHref/test.html")) # self.browser.setUrl(QtCore.QUrl("file:///remote/tw_rnd1/ktc/prog/python/pyside2/WebEngine/data/aaa.ava.summary.html")) #self.browser.setUrl(QtCore.QUrl("file:///remote/tw_rnd1/ktc/prog/python/pyside2/WebEngine/data/aaa_ava_corners/C_1")) self.setCentralWidget(self.browser) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
异常表现
运行代码后能正常加载test.html,但点击Datadir链接无任何响应,甚至QWebEnginePage.acceptNavigationRequest都未触发。需要让QWebEngine的行为与Firefox和Chrome一致。
环境信息
- Python 3.9.0
- CentOS Linux 7
- Qt 5.15(自定义编译版本)
解决方案
原因分析
- 带
target="_blank"的链接会触发createWindow方法,而非acceptNavigationRequest,这是原代码未触发目标方法的核心原因。 - QWebEngine默认限制本地页面访问本地目录,需要手动开启相关权限。
修改后代码
from PySide2 import QtCore, QtWidgets, QtWebEngineWidgets import os import sys class CustomWebEnginePage(QtWebEngineWidgets.QWebEnginePage): def createWindow(self, window_type): # 处理target="_blank"的链接,创建新窗口 new_view = QtWebEngineWidgets.QWebEngineView() new_view.setPage(CustomWebEnginePage(new_view)) new_view.show() return new_view.page() def acceptNavigationRequest(self, url, _type, isMainFrame): print(url, _type, isMainFrame) # 允许本地目录的导航请求 if url.scheme() == "file" and url.path().endswith('/'): return True return super().acceptNavigationRequest(url, _type, isMainFrame) class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) # 启用本地文件访问权限 settings = QtWebEngineWidgets.QWebEngineSettings.globalSettings() settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls, True) settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled, True) self.browser = QtWebEngineWidgets.QWebEngineView() self.browser.setPage(CustomWebEnginePage(self)) self.browser.setUrl(QtCore.QUrl("file:///remote/us01home19/ktc/public_html/testLocalHref/test.html")) self.setCentralWidget(self.browser) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
关键修改说明
- 重写
createWindow:针对target="_blank"的链接创建新窗口,确保点击链接后能弹出新页面加载目标地址。 - 开启本地文件权限:设置
LocalContentCanAccessFileUrls为True,解除QWebEngine对本地页面访问本地目录的默认限制。 - 调整导航请求逻辑:明确允许本地目录的导航请求,确保目录路径能被正确解析加载。
内容的提问来源于stack exchange,提问作者柯德清
相关产品推荐
相关产品推荐

