使用Python快速编写一个图片浏览器

目录

1. 概述

2. 功能点

         3.完整代码


在这篇博客中,我们将一步步探索如何使用Python和PyQt5库来创建一个简单的图片浏览器。这个项目非常适合初学者学习GUI编程和文件处理。

1. 概述

我们的目标是制作一个能够浏览电脑上图片文件的应用程序。用户可以在文件系统树中选择一个文件夹,应用程序随后展示该文件夹内的所有图片。此外,我们的图片浏览器将提供基本的导航功能,如查看上一张或下一张图片,并显示当前查看图片的信息。

2. 功能点

  1. 文件系统访问:使用QTreeView和QFileSystemModel浏览本地文件系统。
  2. 图片展示:通过QLabel展示选中的图片。
  3. 图片缩放:保持图片的长宽比例正确缩放。
  4. 导航功能:实现“上一张”和“下一张”按钮,用于图片间的导航。
  5. 显示图片信息:展示当前图片的序号、总图片数和文件名。
  6. 右键菜单:右键点击图片可复制图片的完整路径。

3.完整代码

import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeView, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QFileSystemModel, QSplitter, QMenu
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QModelIndex, Qt, QSize

class ImagePreviewer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.currentImageIndex = 0
        self.imageFiles = []
        self.initUI()

    def initUI(self):
        self.setWindowTitle('图片预览工具')
        self.setGeometry(100, 100, 800, 600)

        # 主布局
        mainLayout = QHBoxLayout()

        # 文件系统树
        self.treeView = QTreeView()
        self.model = QFileSystemModel()
        self.model.setRootPath('')
        self.treeView.setModel(self.model)
        self.treeView.clicked.connect(self.on_treeView_clicked)

        # 图片显示区域
        self.imageLabel = QLabel("请选择一个文件夹")
        self.imageLabel.setScaledContents(True)
        self.imageLabel.setContextMenuPolicy(Qt.CustomContextMenu)
        self.imageLabel.customContextMenuRequested.connect(self.openMenu)

        # 图片信息标签
        self.imageInfoLabel = QLabel("图片信息")
        self.imageInfoLabel.setFixedHeight(30)

        # 上一张、下一张按钮
        self.prevButton = QPushButton("上一张")
        self.nextButton = QPushButton("下一张")
        self.prevButton.clicked.connect(self.showPrevImage)
        self.nextButton.clicked.connect(self.showNextImage)

        # 布局设置
        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(self.prevButton)
        buttonLayout.addWidget(self.nextButton)

        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.imageLabel)
        rightLayout.addWidget(self.imageInfoLabel)
        rightLayout.addLayout(buttonLayout)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(self.treeView)
        rightWidget = QWidget()
        rightWidget.setLayout(rightLayout)
        splitter.addWidget(rightWidget)
        splitter.setSizes([200, 600])

        mainLayout.addWidget(splitter)

        # 中心窗口
        centralWidget = QWidget()
        centralWidget.setLayout(mainLayout)
        self.setCentralWidget(centralWidget)

    def on_treeView_clicked(self, index: QModelIndex):
        path = self.model.filePath(index)
        if os.path.isdir(path):
            self.imageFiles = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) and f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
            self.currentImageIndex = 0
            self.showImageByIndex(self.currentImageIndex)

    def showImageByIndex(self, index):
        if 0 <= index < len(self.imageFiles):
            self.currentImageIndex = index
            pixmap = QPixmap(self.imageFiles[index])
            scaledPixmap = self.scalePixmapToLabel(pixmap, self.imageLabel)
            self.imageLabel.setScaledContents(False)
            self.imageLabel.setPixmap(scaledPixmap)
            self.updateImageInfo()

    def scalePixmapToLabel(self, pixmap, label):
        labelSize = label.size()
        pixmapSize = pixmap.size()
        if labelSize.width() / labelSize.height() > pixmapSize.width() / pixmap.height():  # 高度缩放
            ratio = labelSize.height() / pixmapSize.height()
        else:
            ratio = labelSize.width() / pixmapSize.width()
        new_size = pixmapSize * ratio

        scaledSize = pixmapSize.scaled(new_size, Qt.KeepAspectRatio)
        return pixmap.scaled(scaledSize, Qt.KeepAspectRatio)

    def updateImageInfo(self):
        filename = os.path.basename(self.imageFiles[self.currentImageIndex])
        infoText = f"{self.currentImageIndex + 1}/{len(self.imageFiles)}: {filename}"
        self.imageInfoLabel.setText(infoText)

    def showPrevImage(self):
        if self.currentImageIndex > 0:
            self.showImageByIndex(self.currentImageIndex - 1)

    def showNextImage(self):
        if self.currentImageIndex < len(self.imageFiles) - 1:
            self.showImageByIndex(self.currentImageIndex + 1)

    def openMenu(self, position):
        menu = QMenu()
        copyAction = menu.addAction("复制图片地址")
        action = menu.exec_(self.imageLabel.mapToGlobal(position))
        if action == copyAction:
            QApplication.clipboard().setText(self.imageFiles[self.currentImageIndex])

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ImagePreviewer()
    ex.show()
    sys.exit(app.exec_())

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值