0


python3GUI--图片浏览器By:PyQt5(附源码)

文章目录


一.前言

本次使用PyQt5开发一款图片浏览器,本篇主要练习QDockWidget、QTreeWidget,软件打包好放在了文末,可自取。

二.展示

1.主界面

在这里插入图片描述

2.添加图片

点击“添加目录”后,选择目录,软件会扫描文件夹及子文件夹下的所有图片文件,最后展示到左侧的目录树中。
在这里插入图片描述

3.多级目录

支持多级目录图片展示
在这里插入图片描述

4.查看文件信息

右击文件,点击查看文件信息
在这里插入图片描述

5.调整UI布局

通过鼠标拖动QDockWidget,选择悬停位置改变UI布局。
在这里插入图片描述

三.源代码

1.image_god_main_v.py

文件主逻辑调用

import os
import re
import sys
import traceback
from PyQt5.QtCore import Qt, QFileInfo, QSize
from PyQt5.QtGui import QPixmap, QIcon, QCursor
import qtawesome

from image_god_GUI import Ui_MainWindow as mainWindow
from webbrowser importopenas open_url
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget, QTreeWidgetItem, QFileDialog, QAbstractItemView, \
    QMenu, QFileIconProvider, QMessageBox, QAction

classImageGod(QMainWindow, mainWindow):
    pixRatio =1def__init__(self):super(ImageGod, self).__init__()
        self.setupUi(self)
        self.ui_init()
        self.slot_init()defui_init(self):deficon_init():
            self.action_addDir.setIcon(qtawesome.icon("mdi.folder-open", color="#3D59AB"))
            self.action_broom.setIcon(qtawesome.icon("ei.broom", color="#DDA0DD"))
            self.action_zoomIn.setIcon(qtawesome.icon("msc.zoom-in", color="brown"))
            self.action_zoomOut.setIcon(qtawesome.icon("msc.zoom-out", color="brown"))
            self.action_zoomFit.setIcon(qtawesome.icon("mdi.restore", color="green"))
            self.action_exit.setIcon(qtawesome.icon("mdi6.exit-to-app", color="gray"))

        self.treeWidget.setColumnCount(1)
        self.treeWidget.setColumnWidth(0,30)
        self.treeWidget.setHeaderLabels(["目录文件"])
        self.treeWidget.setIconSize(QSize(25,25))
        self.treeWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setCentralWidget(self.scrollArea)
        self.scrollArea.setWidgetResizable(True)
        self.action_broom.setEnabled(False)
        self.scrollArea.setAlignment(Qt.AlignCenter)
        self.label.setAlignment(Qt.AlignCenter)
        self.currPixmap = QPixmap()
        icon_init()
        self.change_action_ui(False)
        self.menu_init()defslot_init(self):
        self.action_addDir.triggered.connect(self.on_openDir_triggered)
        self.action_exit.triggered.connect(self.close)
        self.actionabout_author.triggered.connect(lambda: open_url("https://blog.csdn.net/a1397852386"))
        self.actionabout_qt.triggered.connect(lambda: QMessageBox.aboutQt(self,"关于QT"))
        self.action_zoomIn.triggered.connect(self.on_actionZoomIn_triggered)
        self.action_zoomOut.triggered.connect(self.on_actionZoomOut_triggered)
        self.action_zoomFit.triggered.connect(self.on_actionFid_triggered)
        self.action_broom.triggered.connect(self.clear_dirTree)
        self.actiontree.triggered.connect(lambda: self.dockWidget.setVisible(self.actiontree.isChecked()))# self.dockWidget.closeEvent=self.actiontree.setChecked(not self.dockWidget.isVisible())
        self.treeWidget.customContextMenuRequested.connect(self.onTreeWidgetCustomContextMenuRequested)
        self.treeWidget.itemClicked.connect(self.onTreeItemClicked)defmenu_init(self):"""
        treeWidget右击菜单初始化
        :return:
        """
        self.treeWidget_menu = QMenu(self.treeWidget)
        self.action_show_image = QAction(self)# 查看图片
        self.action_show_infos = QAction(self)# 查看文件信息
        self.action_open_image_folder = QAction(self)# 打开所在文件夹
        self.action_show_image.setText("查看图片")
        self.action_show_infos.setText("查看文件信息")
        self.action_open_image_folder.setText("打开所在文件夹")
        self.treeWidget_menu.addActions([self.action_show_image, self.action_show_infos, self.action_open_image_folder,])defon_openDir_triggered(self):"""
        打开有图片的目录
        :return:
        """defCreateTree(dirs, root, path):"""
            创建目录树
            :param dirs:
            :param root:
            :param path:
            :return:
            """for i in dirs:
                path_new = path +'\\'+ i
                if os.path.isdir(path_new):
                    fileInfo = QFileInfo(path_new)
                    child = QTreeWidgetItem(root)
                    dirs_new = os.listdir(path_new)
                    data =""if self.check_dir(path_new):# 确定文件夹有图片文件后,再创建子节点
                        CreateTree(dirs_new, child, path_new)else:
                    fileInfo = QFileInfo(path_new)ifnot self.check_file(fileInfo.suffix()):continue
                    child = QTreeWidgetItem(root)
                    data = fileInfo.absoluteFilePath()# 添加其他队列# child.setText(1, str(fileInfo.size()))# child.setToolTip(1, str(fileInfo.size()))# child.setText(2, fileInfo.suffix())# child.setToolTip(2, fileInfo.suffix())
                child.setData(0, Qt.UserRole, data)
                fileIcon = QFileIconProvider()
                icon = QIcon(fileIcon.icon(fileInfo))
                child.setText(0, i)
                child.setToolTip(0, i)
                child.setIcon(0, QIcon(icon))
                child.setExpanded(False)

        path = QFileDialog.getExistingDirectory(self,"选取文件夹","./")# self.treeWidget.setHeaderLabels(["目录文件", "大小", "类型", "创建时间", "上次修改时间"])ifnot path:return
        dirs = os.listdir(path)if self.check_dir(path, root=True):# 确定文件夹有图片文件后,再创建子节点
            fileInfo = QFileInfo(path)
            fileIcon = QFileIconProvider()
            icon = QIcon(fileIcon.icon(fileInfo))
            fileName_root = QTreeWidgetItem(self.treeWidget)
            fileName_root.setText(0, fileInfo.fileName())
            fileName_root.setToolTip(0, fileInfo.fileName())
            fileName_root.setIcon(0, QIcon(icon))
            fileName_root.setData(0, Qt.UserRole,"")
            CreateTree(dirs, fileName_root, path)
            self.action_broom.setEnabled(True)
            QApplication.processEvents()else:
            QMessageBox.warning(self,"警告","选择的目录不存在图片文件!")defclear_dirTree(self):"""
        清空目录树
        :return:
        """
        self.treeWidget.clear()
        self.action_broom.setEnabled(False)
        self.label.setPixmap(QPixmap(""))
        self.change_action_ui(False)defonTreeItemClicked(self, item, column):"""
        treeWidget节点被单击
        :return:
        """file= item.data(column, Qt.UserRole)
        self.show_image(file)defshow_image(self,file):iffile:
            self.pixRatio =1# 每次都重置为1
            self.statusbar.showMessage(file)# 将文件名展示到状态栏
            self.currPixmap.load(file)
            self.on_zoomFitH_triggered()
            self.change_action_ui(True)defshow_file_infos(self,file):"""
        文件信息
        :param file:
        :return:
        """
        infos =""try:
            file_obj = QFileInfo(file)
            file_name = file_obj.fileName()
            file_size = file_obj.size()
            file_suffix = file_obj.suffix()
            file_last = file_obj.lastModified().toString()
            file_create = file_obj.created().toString()
            file_ow_id = file_obj.ownerId()
            infos ="文件名:{}\n文件类型:{}\n文件大小:{}字节\n创建时间:{}\n上次修改时间:{}\nownerId:{}".format(file_name, file_suffix,
                                                                                        file_size,
                                                                                        file_create, file_last,
                                                                                        file_ow_id)except:
            traceback.print_exc()if infos:
            QMessageBox.information(self,"文件信息", infos)else:
            QMessageBox.warning(self,"警告","文件未找到")defonTreeWidgetCustomContextMenuRequested(self, pos):"""
        treeWidget被右击事件
        :return:
        """try:
            item = self.treeWidget.currentItem()
            index=self.treeWidget.indexFromItem(item,0).row()print("index===",index)
            column = self.treeWidget.currentColumn()
            item1 = self.treeWidget.itemAt(pos)file= item.data(column, Qt.UserRole)if item !=Noneand item1 !=Noneandfile!="":try:
                    self.action_show_image.triggered.disconnect()
                    self.action_show_infos.triggered.disconnect()
                    self.action_open_image_folder.triggered.disconnect()except:
                    traceback.print_exc()print(item.text(column))print(file)
                self.action_show_image.triggered.connect(lambda: self.show_image(file))
                self.action_show_infos.triggered.connect(lambda: self.show_file_infos(file))
                self.action_open_image_folder.triggered.connect(lambda: os.startfile(os.path.dirname(file)))
                self.treeWidget_menu.exec_(QCursor.pos())except:
            traceback.print_exc()defon_zoomFitH_triggered(self):"""
        自动适应高度
        :return:
        """
        height = self.scrollArea.height()
        readHeight = self.currPixmap.height()
        self.pixRatio =float(height)/ readHeight
        pix = self.currPixmap.scaledToHeight(height -30)
        self.label.setPixmap(pix)defon_zoomFitW_triggered(self):"""
        自动适应宽度
        :return:
        """
        width = self.scrollArea.width()
        readHWidth = self.currPixmap.width()
        self.pixRatio =float(width)/ readHWidth
        pix = self.currPixmap.scaledToWidth(width -30)
        self.label.setPixmap(pix)defon_actionZoomIn_triggered(self):"""
        放大图片
        :return:
        """
        self.pixRatio = self.pixRatio *1.2
        width = self.pixRatio * self.currPixmap.width()
        height = self.pixRatio * self.currPixmap.height()
        pix = self.currPixmap.scaled(width, height)
        self.label.setPixmap(pix)defon_actionFid_triggered(self):"""
        自适应大小
        :return:
        """
        self.pixRatio =1
        self.label.setPixmap(self.currPixmap)defon_actionZoomOut_triggered(self):"""
        放大图片
        :return:
        """
        pixRatio_tmp = self.pixRatio
        self.pixRatio = self.pixRatio *0.8
        width = self.pixRatio * self.currPixmap.width()
        height = self.pixRatio * self.currPixmap.height()if width < self.scrollArea.width()and height < self.scrollArea.height():# 避免缩小太小导致失真
            self.pixRatio = pixRatio_tmp
            return
        pix = self.currPixmap.scaled(width, height)
        self.label.setPixmap(pix)defcloseEvent(self, event):
        reply = QMessageBox.question(self,'关闭',"确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)if reply == QMessageBox.Yes:
            event.accept()else:
            event.ignore()defcheck_dir(self,dir, root=False):"""
        查看文件夹是否有图片文件
        :param dir:
        :return:
        """forfilein os.listdir(dir):
            file_abs =dir+'\\'+fileif os.path.isdir(file_abs):returnTrueif"."infile:if self.check_file(file.split(".")[-1]):returnTruereturnFalsedefcheck_file(self, suffix):"""
        看文件是否为图片文件
        :param suffix:
        :return:
        """if suffix in['jpg','png','jpeg','psd','bmp','webp']:returnTrueelse:returnFalsedefchange_action_ui(self, flag):"""
        改变按钮UI状态
        :param falg:
        :return:
        """
        self.action_zoomIn.setEnabled(flag)
        self.action_zoomOut.setEnabled(flag)
        self.action_zoomFit.setEnabled(flag)if __name__ =='__main__':
    app = QApplication(sys.argv)
    ui = ImageGod()
    ui.show()
    sys.exit(app.exec_())

2.image_god_GUI.py

UI文件,通过uic转化而来

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'image_god_GUI.ui'## Created by: PyQt5 UI code generator 5.15.4## WARNING: Any manual changes made to this file will be lost when pyuic5 is# run again.  Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgets

classUi_MainWindow(object):defsetupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1107,622)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setContentsMargins(0,0,0,0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0,0,845,553))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label = QtWidgets.QLabel(self.scrollAreaWidgetContents)
        self.label.setText("")
        self.label.setScaledContents(True)
        self.label.setObjectName("label")
        self.verticalLayout_2.addWidget(self.label)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.horizontalLayout.addWidget(self.scrollArea)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0,0,1107,23))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        self.menu_3 = QtWidgets.QMenu(self.menubar)
        self.menu_3.setObjectName("menu_3")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.dockWidget = QtWidgets.QDockWidget(MainWindow)
        self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable|QtWidgets.QDockWidget.DockWidgetMovable)
        self.dockWidget.setObjectName("dockWidget")
        self.dockWidgetContents = QtWidgets.QWidget()
        self.dockWidgetContents.setObjectName("dockWidgetContents")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.dockWidgetContents)
        self.verticalLayout.setContentsMargins(0,0,0,0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.treeWidget = QtWidgets.QTreeWidget(self.dockWidgetContents)
        self.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.treeWidget.setObjectName("treeWidget")
        self.treeWidget.headerItem().setText(0,"1")
        self.verticalLayout.addWidget(self.treeWidget)
        self.dockWidget.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.action_addDir = QtWidgets.QAction(MainWindow)
        self.action_addDir.setObjectName("action_addDir")
        self.action_broom = QtWidgets.QAction(MainWindow)
        self.action_broom.setObjectName("action_broom")
        self.action_zoomIn = QtWidgets.QAction(MainWindow)
        self.action_zoomIn.setObjectName("action_zoomIn")
        self.action_zoomOut = QtWidgets.QAction(MainWindow)
        self.action_zoomOut.setObjectName("action_zoomOut")
        self.action_zoomFit = QtWidgets.QAction(MainWindow)
        self.action_zoomFit.setObjectName("action_zoomFit")
        self.action_exit = QtWidgets.QAction(MainWindow)
        self.action_exit.setObjectName("action_exit")
        self.actiontree = QtWidgets.QAction(MainWindow)
        self.actiontree.setCheckable(True)
        self.actiontree.setChecked(True)
        self.actiontree.setObjectName("actiontree")
        self.actionabout_author = QtWidgets.QAction(MainWindow)
        self.actionabout_author.setObjectName("actionabout_author")
        self.actionabout_qt = QtWidgets.QAction(MainWindow)
        self.actionabout_qt.setObjectName("actionabout_qt")
        self.menu.addAction(self.action_addDir)
        self.menu.addAction(self.action_broom)
        self.menu.addAction(self.actiontree)
        self.menu.addSeparator()
        self.menu.addAction(self.action_exit)
        self.menu_2.addAction(self.action_zoomIn)
        self.menu_2.addAction(self.action_zoomOut)
        self.menu_2.addAction(self.action_zoomFit)
        self.menu_3.addAction(self.actionabout_author)
        self.menu_3.addAction(self.actionabout_qt)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())
        self.menubar.addAction(self.menu_3.menuAction())
        self.toolBar.addAction(self.action_addDir)
        self.toolBar.addAction(self.action_broom)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.action_zoomIn)
        self.toolBar.addAction(self.action_zoomOut)
        self.toolBar.addAction(self.action_zoomFit)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.action_exit)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)defretranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow","Image_god"))
        self.menu.setTitle(_translate("MainWindow","目录"))
        self.menu_2.setTitle(_translate("MainWindow","视图"))
        self.menu_3.setTitle(_translate("MainWindow","关于"))
        self.dockWidget.setWindowTitle(_translate("MainWindow","目录树"))
        self.toolBar.setWindowTitle(_translate("MainWindow","toolBar"))
        self.action_addDir.setText(_translate("MainWindow","添加目录"))
        self.action_addDir.setToolTip(_translate("MainWindow","添加目录"))
        self.action_broom.setText(_translate("MainWindow","清空目录树"))
        self.action_broom.setToolTip(_translate("MainWindow","清空目录树"))
        self.action_zoomIn.setText(_translate("MainWindow","放大"))
        self.action_zoomIn.setToolTip(_translate("MainWindow","放大"))
        self.action_zoomOut.setText(_translate("MainWindow","缩小"))
        self.action_zoomOut.setToolTip(_translate("MainWindow","缩小"))
        self.action_zoomFit.setText(_translate("MainWindow","原始大小"))
        self.action_zoomFit.setToolTip(_translate("MainWindow","原始大小"))
        self.action_exit.setText(_translate("MainWindow","退出"))
        self.action_exit.setToolTip(_translate("MainWindow","退出"))
        self.actiontree.setText(_translate("MainWindow","显示目录树"))
        self.actiontree.setToolTip(_translate("MainWindow","显示目录树"))
        self.actionabout_author.setText(_translate("MainWindow","关于作者"))
        self.actionabout_author.setToolTip(_translate("MainWindow","关于作者"))
        self.actionabout_qt.setText(_translate("MainWindow","关于QT"))
        self.actionabout_qt.setToolTip(_translate("MainWindow","关于QT"))

四.总结

本次练习了PyQt5相关组件使用,制作了一款图片浏览器,可以按照目录级别预览图片,支持放大、缩小、查看信息,实现功能比较基础,整体UI风格为PyQt5原生ui风格,未使用QSS做具体细节绘制。软件打包好放在了这里,解压后大小为37.5M。希望得到大家的赞,谢谢大家!
在这里插入图片描述

标签: qt python pyqt

本文转载自: https://blog.csdn.net/a1397852386/article/details/131268620
版权归原作者 懷淰メ 所有, 如有侵权,请联系我们删除。

“python3GUI--图片浏览器By:PyQt5(附源码)”的评论:

还没有评论