This commit is contained in:
Irony 2020-11-20 09:55:03 +08:00
commit d3f4e8f815
5 changed files with 159 additions and 5 deletions

BIN
QGraphicsView/Data/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

149
QGraphicsView/ImageView.py Normal file
View file

@ -0,0 +1,149 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2020/11/12
@author: Irony
@site: https://github.com/892768447
@email: 892768447@qq.com
@file: ImageView
@description: 图片查看控件支持移动放大缩小
"""
__Author__ = 'Irony'
__Copyright__ = 'Copyright (c) 2020 Irony'
__Version__ = 1.0
import os
from PyQt5.QtCore import QPointF, Qt, QRectF, QSizeF
from PyQt5.QtGui import QPainter, QColor, QImage, QPixmap
from PyQt5.QtWidgets import QGraphicsView, QGraphicsPixmapItem, QGraphicsScene
class ImageView(QGraphicsView):
"""图片查看控件"""
def __init__(self, *args, **kwargs):
image = kwargs.pop('image', None)
background = kwargs.pop('background', None)
super(ImageView, self).__init__(*args, **kwargs)
self.setCursor(Qt.OpenHandCursor)
self.setBackground(background)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setRenderHints(QPainter.Antialiasing | QPainter.HighQualityAntialiasing |
QPainter.SmoothPixmapTransform)
self.setCacheMode(self.CacheBackground)
self.setViewportUpdateMode(self.SmartViewportUpdate)
self._item = QGraphicsPixmapItem() # 放置图像
self._item.setFlags(QGraphicsPixmapItem.ItemIsFocusable |
QGraphicsPixmapItem.ItemIsMovable)
self._scene = QGraphicsScene(self) # 场景
self.setScene(self._scene)
self._scene.addItem(self._item)
rect = QApplication.instance().desktop().availableGeometry(self)
self.resize(int(rect.width() * 2 / 3), int(rect.height() * 2 / 3))
self.pixmap = None
self._delta = 0.1 # 缩放
self.setPixmap(image)
def setBackground(self, color):
"""设置背景颜色
:param color: 背景颜色
:type color: QColor or str or GlobalColor
"""
if isinstance(color, QColor):
self.setBackgroundBrush(color)
elif isinstance(color, (str, Qt.GlobalColor)):
color = QColor(color)
if color.isValid():
self.setBackgroundBrush(color)
def setPixmap(self, pixmap, fitIn=True):
"""加载图片
:param pixmap: 图片或者图片路径
:param fitIn: 是否适应
:type pixmap: QPixmap or QImage or str
:type fitIn: bool
"""
if isinstance(pixmap, QPixmap):
self.pixmap = pixmap
elif isinstance(pixmap, QImage):
self.pixmap = QPixmap.fromImage(pixmap)
elif isinstance(pixmap, str) and os.path.isfile(pixmap):
self.pixmap = QPixmap(pixmap)
else:
return
self._item.setPixmap(self.pixmap)
self._item.update()
self.setSceneDims()
if fitIn:
self.fitInView(QRectF(self._item.pos(), QSizeF(
self.pixmap.size())), Qt.KeepAspectRatio)
self.update()
def setSceneDims(self):
if not self.pixmap:
return
self.setSceneRect(QRectF(QPointF(0, 0), QPointF(self.pixmap.width(), self.pixmap.height())))
def fitInView(self, rect, flags=Qt.IgnoreAspectRatio):
"""剧中适应
:param rect: 矩形范围
:param flags:
:return:
"""
if not self.scene() or rect.isNull():
return
unity = self.transform().mapRect(QRectF(0, 0, 1, 1))
self.scale(1 / unity.width(), 1 / unity.height())
viewRect = self.viewport().rect()
sceneRect = self.transform().mapRect(rect)
x_ratio = viewRect.width() / sceneRect.width()
y_ratio = viewRect.height() / sceneRect.height()
if flags == Qt.KeepAspectRatio:
x_ratio = y_ratio = min(x_ratio, y_ratio)
elif flags == Qt.KeepAspectRatioByExpanding:
x_ratio = y_ratio = max(x_ratio, y_ratio)
self.scale(x_ratio, y_ratio)
self.centerOn(rect.center())
def wheelEvent(self, event):
if event.angleDelta().y() > 0:
self.zoomIn()
else:
self.zoomOut()
def zoomIn(self):
"""放大"""
self.zoom(1 + self._delta)
def zoomOut(self):
"""缩小"""
self.zoom(1 - self._delta)
def zoom(self, factor):
"""缩放
:param factor: 缩放的比例因子
"""
_factor = self.transform().scale(
factor, factor).mapRect(QRectF(0, 0, 1, 1)).width()
if _factor < 0.07 or _factor > 100:
# 防止过大过小
return
self.scale(factor, factor)
if __name__ == '__main__':
import sys
import cgitb
cgitb.enable(format='text')
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = ImageView(image='Data/bg.jpg', background=Qt.black)
w.show()
sys.exit(app.exec_())

View file

@ -3,6 +3,7 @@
- 目录
- [绘制世界地图](#1绘制世界地图)
- [添加QWidget](#2添加QWidget)
- [图片查看器](#3图片查看器)
## 1、绘制世界地图
[运行 WorldMap.py](WorldMap.py)
@ -17,4 +18,11 @@
通过 `QGraphicsScene.addWidget` 添加自定义QWidget
![AddQWidget](ScreenShot/AddQWidget.png)
![AddQWidget](ScreenShot/AddQWidget.png)
## 3、图片查看器
[运行 ImageView.py](ImageView.py)
支持放大缩小和移动
![ImageView](ScreenShot/ImageView.gif)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

View file

@ -11,10 +11,6 @@ https://pyqt.site 论坛是专门针对PyQt5学习和提升开设的网站
如果您觉得这里的东西对您有帮助,别忘了帮忙点一颗:star:小星星:star:
## 微信博客小程序
<img src="Donate/wxblog.jpg" height="250" width="250">
[客户端下载](https://github.com/PyQt5/PyQtClient/releases)
[自定义控件](https://github.com/PyQt5/CustomWidgets)
@ -117,6 +113,7 @@ https://pyqt.site 论坛是专门针对PyQt5学习和提升开设的网站
- [QGraphicsView](QGraphicsView)
- [绘制世界地图](QGraphicsView/WorldMap.py)
- [添加QWidget](QGraphicsView/AddQWidget.py)
- [图片查看器](QGraphicsView/ImageView.py)
- [QCalendarWidget](QCalendarWidget)
- [QSS美化日历样式](QCalendarWidget/CalendarQssStyle.py)
- [QLCDNumber](QLCDNumber)