图片查看器
This commit is contained in:
parent
045cdbfb29
commit
d43e4aea1d
6 changed files with 159 additions and 144 deletions
|
@ -1,139 +0,0 @@
|
||||||
#!/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 QPoint, QPointF, Qt
|
|
||||||
from PyQt5.QtGui import QPainter, QColor, QImage, QPixmap
|
|
||||||
from PyQt5.QtWidgets import QWidget
|
|
||||||
|
|
||||||
|
|
||||||
class ImageView(QWidget):
|
|
||||||
"""图片查看控件"""
|
|
||||||
|
|
||||||
def __init__(self, image, *args, **kwargs):
|
|
||||||
super(ImageView, self).__init__(*args, **kwargs)
|
|
||||||
self.setCursor(Qt.OpenHandCursor)
|
|
||||||
self._image = None
|
|
||||||
self._pos = QPoint(0, 0) # 移动图片偏移
|
|
||||||
self._p_pos = None # 鼠标按下点
|
|
||||||
self._scale = 1 # 缩放
|
|
||||||
self._max_scale = 20 # 最大放大级别
|
|
||||||
self._background = kwargs.pop('background', None)
|
|
||||||
self.setPixmap(image)
|
|
||||||
|
|
||||||
def setMaxScale(self, scale):
|
|
||||||
"""设置最大放大级别,默认为20
|
|
||||||
:param scale: 最大缩放
|
|
||||||
:type scale: int
|
|
||||||
"""
|
|
||||||
self._max_scale = scale
|
|
||||||
|
|
||||||
def setBackground(self, color):
|
|
||||||
"""设置背景颜色
|
|
||||||
:param color: 背景颜色
|
|
||||||
:type color: QColor or str
|
|
||||||
"""
|
|
||||||
if isinstance(color, QColor):
|
|
||||||
self._background = color
|
|
||||||
elif isinstance(color, str):
|
|
||||||
color = QColor(color)
|
|
||||||
if color.isValid():
|
|
||||||
self._background = color
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def setPixmap(self, image):
|
|
||||||
"""加载图片
|
|
||||||
:param image: 图片或者图片路径
|
|
||||||
:type image: QPixmap or QImage or str
|
|
||||||
"""
|
|
||||||
if isinstance(image, QPixmap):
|
|
||||||
self._image = image
|
|
||||||
elif isinstance(image, QImage):
|
|
||||||
self._image = QPixmap.fromImage(image)
|
|
||||||
elif isinstance(image, str) and os.path.isfile(image):
|
|
||||||
self._image = QPixmap(image)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
self._pos = QPoint(0, 0)
|
|
||||||
self._p_pos = None
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
|
||||||
"""鼠标按下修改鼠标样式以及记录初始移动点"""
|
|
||||||
super(ImageView, self).mousePressEvent(event)
|
|
||||||
self.setCursor(Qt.ClosedHandCursor)
|
|
||||||
if event.button() == Qt.LeftButton:
|
|
||||||
self._p_pos = event.pos()
|
|
||||||
|
|
||||||
def mouseReleaseEvent(self, event):
|
|
||||||
"""鼠标释放修改鼠标样式"""
|
|
||||||
super(ImageView, self).mouseReleaseEvent(event)
|
|
||||||
self.setCursor(Qt.OpenHandCursor)
|
|
||||||
self._p_pos = None
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, event):
|
|
||||||
"""鼠标移动图片"""
|
|
||||||
super(ImageView, self).mouseMoveEvent(event)
|
|
||||||
if event.buttons() == Qt.LeftButton and self._p_pos:
|
|
||||||
offset = event.pos() - self._p_pos
|
|
||||||
self._p_pos += offset
|
|
||||||
self._pos += offset
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def wheelEvent(self, event):
|
|
||||||
super(ImageView, self).wheelEvent(event)
|
|
||||||
step = 0.4 if self._scale > 1.1 else 0.1
|
|
||||||
if event.angleDelta().y() > 0:
|
|
||||||
# 放大
|
|
||||||
self._scale += step
|
|
||||||
self._scale = min(self._scale, self._max_scale)
|
|
||||||
else:
|
|
||||||
# 缩小
|
|
||||||
self._scale -= step
|
|
||||||
self._scale = max(self._scale, 0.1)
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def paintEvent(self, event):
|
|
||||||
super(ImageView, self).paintEvent(event)
|
|
||||||
painter = QPainter(self)
|
|
||||||
painter.setRenderHint(QPainter.Antialiasing)
|
|
||||||
painter.setRenderHint(QPainter.SmoothPixmapTransform)
|
|
||||||
if self._background:
|
|
||||||
painter.fillRect(self.rect(), self._background)
|
|
||||||
if not self._image or self._image.isNull():
|
|
||||||
return
|
|
||||||
# 变换坐标中心为窗口中点
|
|
||||||
painter.translate(self.width() / 2, self.height() / 2)
|
|
||||||
# 缩放
|
|
||||||
painter.scale(self._scale, self._scale)
|
|
||||||
painter.drawPixmap(QPointF(-self._image.width() / 2 + self._pos.x(), -self._image.height() / 2 + self._pos.y()),
|
|
||||||
self._image)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import sys
|
|
||||||
import cgitb
|
|
||||||
|
|
||||||
cgitb.enable(format='text')
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
w = ImageView('ScreenShot/CallVirtualKeyboard2.png')
|
|
||||||
w.show()
|
|
||||||
sys.exit(app.exec_())
|
|
BIN
QGraphicsView/Data/bg.jpg
Normal file
BIN
QGraphicsView/Data/bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 231 KiB |
149
QGraphicsView/ImageView.py
Normal file
149
QGraphicsView/ImageView.py
Normal 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_())
|
|
@ -3,6 +3,7 @@
|
||||||
- 目录
|
- 目录
|
||||||
- [绘制世界地图](#1绘制世界地图)
|
- [绘制世界地图](#1绘制世界地图)
|
||||||
- [添加QWidget](#2添加QWidget)
|
- [添加QWidget](#2添加QWidget)
|
||||||
|
- [图片查看器](#3图片查看器)
|
||||||
|
|
||||||
## 1、绘制世界地图
|
## 1、绘制世界地图
|
||||||
[运行 WorldMap.py](WorldMap.py)
|
[运行 WorldMap.py](WorldMap.py)
|
||||||
|
@ -18,3 +19,10 @@
|
||||||
通过 `QGraphicsScene.addWidget` 添加自定义QWidget
|
通过 `QGraphicsScene.addWidget` 添加自定义QWidget
|
||||||
|
|
||||||
![AddQWidget](ScreenShot/AddQWidget.png)
|
![AddQWidget](ScreenShot/AddQWidget.png)
|
||||||
|
|
||||||
|
## 3、图片查看器
|
||||||
|
[运行 ImageView.py](ImageView.py)
|
||||||
|
|
||||||
|
支持放大缩小和移动
|
||||||
|
|
||||||
|
![ImageView](ScreenShot/ImageView.gif)
|
BIN
QGraphicsView/ScreenShot/ImageView.gif
Normal file
BIN
QGraphicsView/ScreenShot/ImageView.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1 MiB |
|
@ -11,10 +11,6 @@ https://pyqt.site 论坛是专门针对PyQt5学习和提升开设的网站,分
|
||||||
|
|
||||||
如果您觉得这里的东西对您有帮助,别忘了帮忙点一颗:star:小星星:star:
|
如果您觉得这里的东西对您有帮助,别忘了帮忙点一颗:star:小星星:star:
|
||||||
|
|
||||||
## 微信博客小程序
|
|
||||||
|
|
||||||
<img src="Donate/wxblog.jpg" height="250" width="250">
|
|
||||||
|
|
||||||
[客户端下载](https://github.com/PyQt5/PyQtClient/releases)
|
[客户端下载](https://github.com/PyQt5/PyQtClient/releases)
|
||||||
|
|
||||||
[自定义控件](https://github.com/PyQt5/CustomWidgets)
|
[自定义控件](https://github.com/PyQt5/CustomWidgets)
|
||||||
|
@ -117,6 +113,7 @@ https://pyqt.site 论坛是专门针对PyQt5学习和提升开设的网站,分
|
||||||
- [QGraphicsView](QGraphicsView)
|
- [QGraphicsView](QGraphicsView)
|
||||||
- [绘制世界地图](QGraphicsView/WorldMap.py)
|
- [绘制世界地图](QGraphicsView/WorldMap.py)
|
||||||
- [添加QWidget](QGraphicsView/AddQWidget.py)
|
- [添加QWidget](QGraphicsView/AddQWidget.py)
|
||||||
|
- [图片查看器](QGraphicsView/ImageView.py)
|
||||||
- [QCalendarWidget](QCalendarWidget)
|
- [QCalendarWidget](QCalendarWidget)
|
||||||
- [QSS美化日历样式](QCalendarWidget/CalendarQssStyle.py)
|
- [QSS美化日历样式](QCalendarWidget/CalendarQssStyle.py)
|
||||||
- [QLCDNumber](QLCDNumber)
|
- [QLCDNumber](QLCDNumber)
|
||||||
|
|
Loading…
Reference in a new issue