|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +""" |
| 5 | +Created on 2020/6/3 |
| 6 | +@author: Irony |
| 7 | +@site: https://pyqt.site https://github.com/PyQt5 |
| 8 | + |
| 9 | +@file: DynamicRes |
| 10 | +@description: |
| 11 | +""" |
| 12 | +from threading import Thread |
| 13 | + |
| 14 | +import requests |
| 15 | +from PyQt5.QtCore import QUrl, QByteArray |
| 16 | +from PyQt5.QtGui import QImage, QTextDocument |
| 17 | +from PyQt5.QtWidgets import QTextBrowser, QWidget, QVBoxLayout, QPushButton |
| 18 | + |
| 19 | +__Author__ = 'Irony' |
| 20 | +__Copyright__ = 'Copyright (c) 2020' |
| 21 | +__Version__ = 'Version 1.0' |
| 22 | + |
| 23 | + |
| 24 | +class TextBrowser(QTextBrowser): |
| 25 | + NetImages = {} |
| 26 | + |
| 27 | + def __init__(self, *args, **kwargs): |
| 28 | + super(TextBrowser, self).__init__(*args, **kwargs) |
| 29 | + self.setOpenLinks(False) # 禁止打开URL |
| 30 | + |
| 31 | + def downloadImage(self, url): |
| 32 | + try: |
| 33 | + self.NetImages[url] = [QByteArray(requests.get(url.toString()).content), 1] |
| 34 | + print('下载完成', url) |
| 35 | + except Exception as e: |
| 36 | + print('下载失败', url, e) |
| 37 | + self.NetImages[url] = [QByteArray(), 1] |
| 38 | + |
| 39 | + def loadResource(self, rtype, url): |
| 40 | + ret = super(TextBrowser, self).loadResource(rtype, url) |
| 41 | + # 加载图片资源 |
| 42 | + if rtype == QTextDocument.ImageResource: |
| 43 | + if ret: |
| 44 | + return ret |
| 45 | + if url.toString().startswith('irony'): # 自定义的协议头 |
| 46 | + print('加载本地', '../Donate/zhifubao.png', url) |
| 47 | + return QImage('../Donate/zhifubao.png') # 或者 QByteArray(open('../Donate/zhifubao.png', 'rb').read()) |
| 48 | + elif url.toString().startswith('http'): # 加载网络图片 |
| 49 | + img, status = self.NetImages.get(url, [None, None]) |
| 50 | + if url not in self.NetImages or status is None: |
| 51 | + # 子线程下载 |
| 52 | + self.NetImages[url] = [None, 1] |
| 53 | + print('download ', url) |
| 54 | + Thread(target=self.downloadImage, args=(url,), daemon=True).start() |
| 55 | + elif img: |
| 56 | + return img |
| 57 | + return ret |
| 58 | + |
| 59 | + def mouseDoubleClickEvent(self, event): |
| 60 | + # 双击图片得到图片的URL,也可以用来放大显示 |
| 61 | + super(TextBrowser, self).mouseDoubleClickEvent(event) |
| 62 | + url = self.anchorAt(event.pos()) |
| 63 | + if url: |
| 64 | + print('url:', url, self.document().resource(QTextDocument.ImageResource, QUrl(url))) |
| 65 | + |
| 66 | + |
| 67 | +class Window(QWidget): |
| 68 | + |
| 69 | + def __init__(self, *args, **kwargs): |
| 70 | + super(Window, self).__init__(*args, **kwargs) |
| 71 | + layout = QVBoxLayout(self) |
| 72 | + |
| 73 | + self.textBrowser = TextBrowser(self) |
| 74 | + self.downButton = QPushButton('加载网络图片', self) |
| 75 | + |
| 76 | + layout.addWidget(self.textBrowser) |
| 77 | + layout.addWidget(self.downButton) |
| 78 | + |
| 79 | + # 加载本地图片 |
| 80 | + img = QImage('../Donate/weixin.png') |
| 81 | + # 第二个参数为任意唯一的url类似于qrc方式 |
| 82 | + self.textBrowser.document().addResource(QTextDocument.ImageResource, QUrl('dynamic:/images/weixin.png'), img) |
| 83 | + |
| 84 | + # 设置html |
| 85 | + # 需要注意里面的图片地址 |
| 86 | + self.textBrowser.setHtml( |
| 87 | + '<p><a href="../Donate/weixin.png"><img src="../Donate/weixin.png"></a></p>' # 方式一直接加载本地图片 |
| 88 | + '<p><a href="dynamic:/images/weixin.png"><img src="dynamic:/images/weixin.png"></a></p>' # 方式二通过addResource添加资源 |
| 89 | + '<p><a href="irony://zhifubao.png"><img src="irony://zhifubao.png"></a></p>' # 方式三定义自定义的协议头通过loadResource动态加载 |
| 90 | + '<p><a href="https://blog.pyqt5.com/img/avatar.png"><img ' # 方式四类似方式三,只不过需要从网络中下载 |
| 91 | + 'src="https://blog.pyqt5.com/img/avatar.png"></a></p>') |
| 92 | + |
| 93 | + |
| 94 | +if __name__ == '__main__': |
| 95 | + import sys |
| 96 | + import cgitb |
| 97 | + |
| 98 | + cgitb.enable(1, None, 5, '') |
| 99 | + from PyQt5.QtWidgets import QApplication |
| 100 | + |
| 101 | + app = QApplication(sys.argv) |
| 102 | + w = Window() |
| 103 | + w.show() |
| 104 | + sys.exit(app.exec_()) |
0 commit comments