千家信息网

Python+PyQt5如何制作一个图片查看器

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,这篇文章将为大家详细讲解有关Python+PyQt5如何制作一个图片查看器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。实现方式一个最基本的照片查看器应该具有以下功
千家信息网最后更新 2024年11月28日Python+PyQt5如何制作一个图片查看器

这篇文章将为大家详细讲解有关Python+PyQt5如何制作一个图片查看器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

实现方式

一个最基本的照片查看器应该具有以下功能:

  • 载入图像

  • 缩放图像

  • 在窗口尺寸小于图像时允许拖拽图像

载入图像可以使用 QGraphicsPixmapItem 来解决,缩放图像使用 QGraphicsViewscale(sx, sy) 解决,移动图像只需将 QGraphicsViewdragMode 设置为 QGraphicsView.ScrollHandDrag 即可。因为常常使用鼠标滚轮来缩放图像,所以还需要重写重写以下 QGraphicsViewwheelEvent

实际上由于窗口的缩放导致视口大小变化,还有一些细枝末节需要处理。具体代码如下:

# coding:utf-8import sysfrom PyQt5.QtCore import QRect, QRectF, QSize, Qtfrom PyQt5.QtGui import QPainter, QPixmap, QWheelEventfrom PyQt5.QtWidgets import (QApplication, QGraphicsItem, QGraphicsPixmapItem,                             QGraphicsScene, QGraphicsView)class ImageViewer(QGraphicsView):    """ 图片查看器 """    def __init__(self, parent=None):        super().__init__(parent=parent)        self.zoomInTimes = 0        self.maxZoomInTimes = 22        # 创建场景        self.graphicsScene = QGraphicsScene()        # 图片        self.pixmap = QPixmap(r'D:\hzz\图片\硝子\硝子 (2).jpg')        self.pixmapItem = QGraphicsPixmapItem(self.pixmap)        self.displayedImageSize = QSize(0, 0)        # 初始化小部件        self.__initWidget()    def __initWidget(self):        """ 初始化小部件 """        self.resize(1200, 900)        # 隐藏滚动条        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)        # 以鼠标所在位置为锚点进行缩放        self.setTransformationAnchor(self.AnchorUnderMouse)        # 平滑缩放        self.pixmapItem.setTransformationMode(Qt.SmoothTransformation)        self.setRenderHints(QPainter.Antialiasing |                            QPainter.SmoothPixmapTransform)        # 设置场景        self.graphicsScene.addItem(self.pixmapItem)        self.setScene(self.graphicsScene)    def wheelEvent(self, e: QWheelEvent):        """ 滚动鼠标滚轮缩放图片 """        if e.angleDelta().y() > 0:            self.zoomIn()        else:            self.zoomOut()    def resizeEvent(self, e):        """ 缩放图片 """        super().resizeEvent(e)        if self.zoomInTimes > 0:            return        # 调整图片大小        ratio = self.__getScaleRatio()        self.displayedImageSize = self.pixmap.size()*ratio        if ratio < 1:            self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)        else:            self.resetTransform()    def setImage(self, imagePath: str):        """ 设置显示的图片 """        self.resetTransform()        # 刷新图片        self.pixmap = QPixmap(imagePath)        self.pixmapItem.setPixmap(self.pixmap)        # 调整图片大小        self.setSceneRect(QRectF(self.pixmap.rect()))        ratio = self.__getScaleRatio()        self.displayedImageSize = self.pixmap.size()*ratio        if ratio < 1:            self.fitInView(self.pixmapItem, Qt.KeepAspectRatio)    def resetTransform(self):        """ 重置变换 """        super().resetTransform()        self.zoomInTimes = 0        self.__setDragEnabled(False)    def __isEnableDrag(self):        """ 根据图片的尺寸决定是否启动拖拽功能 """        v = self.verticalScrollBar().maximum() > 0        h = self.horizontalScrollBar().maximum() > 0        return v or h    def __setDragEnabled(self, isEnabled: bool):        """ 设置拖拽是否启动 """        self.setDragMode(            self.ScrollHandDrag if isEnabled else self.NoDrag)    def __getScaleRatio(self):        """ 获取显示的图像和原始图像的缩放比例 """        if self.pixmap.isNull():            return 1        pw = self.pixmap.width()        ph = self.pixmap.height()        rw = min(1, self.width()/pw)        rh = min(1, self.height()/ph)        return min(rw, rh)    def fitInView(self, item: QGraphicsItem, mode=Qt.KeepAspectRatio):        """ 缩放场景使其适应窗口大小 """        super().fitInView(item, mode)        self.displayedImageSize = self.__getScaleRatio()*self.pixmap.size()        self.zoomInTimes = 0    def zoomIn(self, viewAnchor=QGraphicsView.AnchorUnderMouse):        """ 放大图像 """        if self.zoomInTimes == self.maxZoomInTimes:            return        self.setTransformationAnchor(viewAnchor)        self.zoomInTimes += 1        self.scale(1.1, 1.1)        self.__setDragEnabled(self.__isEnableDrag())        # 还原 anchor        self.setTransformationAnchor(self.AnchorUnderMouse)    def zoomOut(self, viewAnchor=QGraphicsView.AnchorUnderMouse):        """ 缩小图像 """        if self.zoomInTimes == 0 and not self.__isEnableDrag():            return        self.setTransformationAnchor(viewAnchor)        self.zoomInTimes -= 1        # 原始图像的大小        pw = self.pixmap.width()        ph = self.pixmap.height()        # 实际显示的图像宽度        w = self.displayedImageSize.width()*1.1**self.zoomInTimes        h = self.displayedImageSize.height()*1.1**self.zoomInTimes        if pw > self.width() or ph > self.height():            # 在窗口尺寸小于原始图像时禁止继续缩小图像比窗口还小            if w <= self.width() and h <= self.height():                self.fitInView(self.pixmapItem)            else:                self.scale(1/1.1, 1/1.1)        else:            # 在窗口尺寸大于图像时不允许缩小的比原始图像小            if w <= pw:                self.resetTransform()            else:                self.scale(1/1.1, 1/1.1)        self.__setDragEnabled(self.__isEnableDrag())        # 还原 anchor        self.setTransformationAnchor(self.AnchorUnderMouse)if __name__ == '__main__':    app = QApplication(sys.argv)    w = ImageViewer()    w.show()    sys.exit(app.exec_())

测试

来看一下实际的使用效果:

关于"Python+PyQt5如何制作一个图片查看器"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0