Итак, попробуем свести это к простым битам. У меня есть такие записи href:
<a href="#section_8">
linktext
</a>
Эти ссылки на странице работают, если я загружаю страницу через Qts setContent, однако, поскольку мой контент часто превышает 2 МБ, мне приходится использовать методы urlhandler. Итак, краткий обзор выглядит примерно так:
scheme.SchemeHandler.register(lambda: webpage, "reportstext")
self.loader = QWebEngineView()
self.loader.setUrl(QUrl("conapp://reportstext"))
SchemeHandler хранит словарь внутреннего содержимого приложения и хранит все это conapp://<contentname>
Теперь это работает. Я могу передавать веб-контент в WebView. То есть, пока я не попытаюсь использовать ссылки на странице, как упоминалось в начале. То, что я получаю, это просто пустая страница, никаких отладочных сообщений, никаких сбоев, ничего. Просто пусто. Также нет запроса, исходящего к обработчику схемы.
Как заставить их работать?
Если я экспортирую содержимое в файл .html и открою его в браузере, он будет работать, как и ожидалось, так что что-то в Qt работает не так, как я ожидаю.
Полный пример, требуется PyQt5:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QSize, QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QBuffer, QIODevice
from PyQt5.QtWebEngineCore import (QWebEngineUrlSchemeHandler,
QWebEngineUrlRequestJob)
from PyQt5.QtWebEngineWidgets import QWebEngineProfile
import sys
app = QApplication(sys.argv)
class SchemeHandler(QWebEngineUrlSchemeHandler):
def __init__(self):
super(SchemeHandler, self).__init__()
QWebEngineProfile.defaultProfile().installUrlSchemeHandler(b'conapp', self)
self._handlers = {}
def requestStarted(self, job):
url = job.requestUrl()
print("Got request for {}".format(url.toDisplayString()))
request = url.toString().split("//")[1]
buf = QBuffer(parent=self)
buf.open(QIODevice.WriteOnly)
buf.write(self._handlers[request]().encode("utf-8"))
buf.seek(0)
buf.close()
job.reply("text/html".encode("ascii"), buf)
def register(self, contentgenerator, contentname):
self._handlers[contentname] = contentgenerator
return contentname
SchemeHandler = SchemeHandler()
class ReportMenu(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(800, 600))
self.late_init()
def late_init(self):
def webpage():
return """<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>
ConParser Output
</title>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
</head>
<body>
<div class="navbar">
<a href="#section_0">
MVZ Arztfallzähler
</a>
</div>
</body>
</html>"""
SchemeHandler.register(webpage, "reportstext")
self.loader = QWebEngineView()
self.loader.setUrl(QUrl("conapp://reportstext"))
self.report_loader = QWebEngineView()
self.gridLayout = QGridLayout(self)
self.gridLayout.addWidget(self.loader, 0, 0)
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
centralWidget.setLayout(self.gridLayout)
self.showMaximized()
self.loader.loadFinished.connect(self.load_completed)
def load_completed(self, *args):
if not args[0]:
print("Load failed:", args)
menu = ReportMenu()
ret_code = app.exec_()
sys.exit(ret_code)
Если вы сейчас возьмете это и переключитесь
self.loader.setUrl(QUrl("conapp://reportstext"))
за
self.loader.setHtml(webpage())
Это даст ожидаемый эффект работы URL-адресов на странице, однако у этого есть ограничение на содержимое 2 МБ, которое я часто превышаю.