首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtWebView中的页内href无法显示任何内容。

QtWebView中的页内href无法显示任何内容。
EN

Stack Overflow用户
提问于 2018-03-05 18:18:36
回答 1查看 404关注 0票数 1

所以,试着把它归结为简单的部分。我有这样的href条目:

代码语言:javascript
复制
<a href="#section_8">
linktext
</a>

如果我通过Qts setContent加载页面,这些页面链接可以工作,但是,由于我的内容经常超过2MB,所以我必须使用urlhandler方法。因此,快速概述,如下所示:

代码语言:javascript
复制
    scheme.SchemeHandler.register(lambda: webpage, "reportstext")
    self.loader = QWebEngineView()
    self.loader.setUrl(QUrl("conapp://reportstext"))

SchemeHandler保存了应用程序内部内容的字典,并将其全部保存在conapp://<contentname>后面。

现在,这是可行的。我可以向WebView提供网络内容。也就是说,直到我尝试使用页面中的链接,正如前面提到的。我得到的只是一个空白页,没有调试消息,没有崩溃,没有任何东西。只是空白。也没有向架构处理程序发出任何请求。

我怎么才能让这些东西起作用?

如果我将内容导出到一个.html文件中并在浏览器中打开它,它就会像预期的那样工作,所以Qt端有一些东西不像我期望的那样工作。

完整的示例,需要PyQt5:

代码语言:javascript
复制
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)

如果你现在拿着这个开关

代码语言:javascript
复制
self.loader.setUrl(QUrl("conapp://reportstext"))

代码语言:javascript
复制
self.loader.setHtml(webpage())

这将提供预期的效果,页面内的urls工作,然而,这有2MB的内容限制,我经常超过。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-05 23:14:02

这似乎是由底层Chrome引擎如何处理base-url的问题引起的。示例中的书签锚点是相对的,但是如果您将其变为绝对的,如下所示:

代码语言:javascript
复制
<a href="conapp://reportstext#section_0">
  MVZ Arztfallzähler
</a>
<p style="margin-top: 1500px">
  <a name="section_0">HELLO WORLD</a>
</p>

您的示例将如预期的那样起作用。有鉴于此,我希望通过添加这样一个<base>标记,可以使相对书签自动工作:

代码语言:javascript
复制
<head>
  <base href="conapp://reportstext">
</head>

但令人遗憾的是,Chrome对<base>标签的实现似乎已经中断。可以通过在href中添加一个尾斜杠来部分地工作:

代码语言:javascript
复制
<base href="conapp://reportstext/">

然后,您的自定义方案处理程序将获得页面上所有相关urls的请求。但是这样做的一个不需要的副作用是,Chrome然后解释相关书签锚的引用,比如:conapp://reportstext/#section_0。因此,不再导航到书签,方案处理程序将得到一个无效url的请求。

AFAICS,似乎没有任何其他方式来拦截书签锚的导航请求。我尝试了QWebEngineUrlRequestInterceptor类并重新实现了QWebEnginePage.acceptNavigationRequest(),但是与自定义方案处理程序一样,它们只是没有被调用书签锚。似乎所有的处理都发生在Chrome内。

解决上述问题的一种有点麻烦的方法是在页面加载上运行一些javascript,只需重写所有书签锚,这样它们就有了绝对的hrefs。

下面是一个与您的示例一起工作的基本实现:

代码语言:javascript
复制
class ReportMenu(QMainWindow):
    ...
    def load_completed(self, ok):
        if ok:
            page = self.loader.page()
            page.runJavaScript("""
            url = window.location.href
            links = document.querySelectorAll('a')
            for (index = 0; index < links.length; ++index) {
                link = links[index]
                href = link.getAttribute('href')
                if (href && href[0] == '#') {
                    link.href = url + href
                }
            }
            """)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49116986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档