首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PyQt5渲染标记

用PyQt5渲染标记
EN

Stack Overflow用户
提问于 2021-02-05 15:36:10
回答 1查看 2.9K关注 0票数 3

如何在我的PyQt5应用程序中呈现一个标记文件?

这里我读到我应该使用QWebEngineView而不是QTextEdit,因为QTextEdit不能呈现外部图像。

在评论中,有人引用了示例。不过,它是一个完整的标记文本用户,并且是用c++编写的。我试图将所需的部分转换为Python,但我不太明白它是如何工作的。我只需要一个最小的例子。

我现在的情况如下:

代码语言:javascript
复制
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
import sys

app = QApplication(sys.argv)

web_widget = QWebEngineView()  
webChannel = QWebChannel()    # ?
page = QWebEnginePage()       # ?
web_widget.setPage(page)      # ? 
my_url = QUrl("/index.html")
web_widget.load(my_url)

# now somehow replace the placeholder in the loaded html page with file contents?

file_url = QUrl("file.md")

# help 


web_widget.show()
app.exec_()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-05 16:58:27

从Qt5.14开始的QTextEdit可以呈现标记,但是正如OP所指出的,它有一个限制:它不能呈现远程图像。因此,另一种选择是使用QWebEngineView + js库(如markdown.js和marked.js ),这是官方示例所示。您还可以使用QNetworkAccessManager下载远程.md文件。

代码语言:javascript
复制
import os.path
import sys

from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTextCodec, QUrl
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWidgets import QApplication

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))


class Document(QObject):
    textChanged = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.m_text = ""

    def get_text(self):
        return self.m_text

    def set_text(self, text):
        if self.m_text == text:
            return
        self.m_text = text
        self.textChanged.emit(self.m_text)

    text = pyqtProperty(str, fget=get_text, fset=set_text, notify=textChanged)


class DownloadManager(QObject):
    finished = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)

        self._manager = QNetworkAccessManager()
        self.manager.finished.connect(self.handle_finished)

    @property
    def manager(self):
        return self._manager

    def start_download(self, url):
        self.manager.get(QNetworkRequest(url))

    def handle_finished(self, reply):
        if reply.error() != QNetworkReply.NoError:
            print("error: ", reply.errorString())
            return
        codec = QTextCodec.codecForName("UTF-8")
        raw_data = codec.toUnicode(reply.readAll())
        self.finished.emit(raw_data)


def main():

    app = QApplication(sys.argv)

    filename = os.path.join(CURRENT_DIR, "index.html")

    document = Document()
    download_manager = DownloadManager()

    channel = QWebChannel()
    channel.registerObject("content", document)

    # remote file
    markdown_url = QUrl.fromUserInput(
        "https://raw.githubusercontent.com/eyllanesc/stackoverflow/master/README.md"
    )
    # local file
    # markdown_url = QUrl.fromUserInput(/path/of/markdown.md)

    download_manager.finished.connect(document.set_text)
    download_manager.start_download(markdown_url)

    view = QWebEngineView()
    view.page().setWebChannel(channel)
    url = QUrl.fromLocalFile(filename)
    view.load(url)
    view.resize(640, 480)
    view.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

index.html

代码语言:javascript
复制
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<head>
  <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css">
  <script src="3rdparty/marked.js"></script>
  <script src="qrc:/qtwebchannel/qwebchannel.js"></script>
</head>
<body>
  <div id="placeholder"></div>
  <script>
  'use strict';

  var placeholder = document.getElementById('placeholder');

  var updateText = function(text) {
      placeholder.innerHTML = marked(text);
  }

  new QWebChannel(qt.webChannelTransport,
    function(channel) {
      var content = channel.objects.content;
      updateText(content.text);
      content.textChanged.connect(updateText);
    }
  );
  </script>
</body>
</html>
代码语言:javascript
复制
├── 3rdparty
│   ├── markdown.css
│   ├── MARKDOWN-LICENSE.txt
│   ├── marked.js
│   ├── MARKED-LICENSE.txt
│   └── qt_attribution.json
├── index.html
└── main.py

注意:3 3rdparty文件夹中的文件在官方的Qt存储库。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66066115

复制
相关文章

相似问题

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