我一直在寻找一段时间通过文档来找到实现这一目标的方法,但尚未成功。基本的想法是,我有一段html,我通过Qt的webview加载。可以将相同的内容导出到单个html文件中。
此文件使用Bootstrap和jQuery等库。目前我通过CDN加载它们,这在网上很好用。但是,我的应用程序还需要脱机运行。因此,我正在寻找一种方法来拦截Qt中的库加载并改为提供本地保存的文件。我尝试过安装https QWebEngineUrlSchemeHandler,但似乎从未触发过requestStarted方法。
(PyQT example follows)
QWebEngineProfile.defaultProfile().installUrlSchemeHandler(b'https', self)
如果我为该方案使用不同的文本并将其嵌入到它有效的页面中,那么我的假设是它不起作用,因为Qt已经注册了它的默认处理程序。但是这种不同的方案在文件导出中会失败。
无论如何,回到核心问题;有没有办法拦截库的加载,或仅在Qt内专门更改url方案?
进一步使用QWebEngineUrlRequestInterceptor,现在将https请求重定向到我自己的uri,它有一个uri处理程序。但是,请求永远不会通过它,因为:重定向位置' conapp://webresource/bootstrap.min.css'有一个不允许的跨源请求方案。 如何将我自己的conapp uri计划列入白名单?
答案 0 :(得分:2)
以下示例显示了我是如何完成的。它使用QWebEngineUrlRequestInterceptor将内容重定向到本地服务器。
举个例子,我拦截stacksflow的stacks.css并做出明显的改变。
import requests
import sys
import threading
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import ThreadingMixIn
# Set these to the address you want your local patch server to run
HOST = '127.0.0.1'
PORT = 1235
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def patch_css(self, url):
print('patching', url)
r = requests.get(url)
new_css = r.text + '#mainbar {background-color: cyan;}' # Example of some css change
with open('local_stacks.css', 'w') as outfile:
outfile.write(new_css)
def interceptRequest(self, info: QWebEngineUrlRequestInfo):
url = info.requestUrl().url()
if url == "https://cdn.sstatic.net/Shared/stacks.css?v=596945d5421b":
self.patch_css(url)
print('Using local file for', url)
info.redirect(QtCore.QUrl('http:{}:{}/local_stacks.css'.format(HOST, PORT)))
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Threaded HTTPServer"""
app = QtWidgets.QApplication(sys.argv)
# Start up thread to server patched content
server = ThreadingHTTPServer((HOST, PORT), SimpleHTTPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
# Install an interceptor to redirect to patched content
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile.defaultProfile()
profile.setRequestInterceptor(interceptor)
w = QWebEngineView()
w.load(QtCore.QUrl('https://stackoverflow.com'))
w.show()
app.exec_()
答案 1 :(得分:0)
所以,我最终采用的解决方案是,首先介绍jinja模板。然后,使用这些模板将根据导出或内部使用设置变量和块,从那里我不再需要拦截器。