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

文章目录

  • 一.前言
  • 二.展示
    • 1.主界面
    • 2.添加图片
    • 3.多级目录
    • 4.查看文件信息
    • 5.调整UI布局
  • 三.源代码
    • 1.image_god_main_v.py
    • 2.image_god_GUI.py
  • 四.总结


一.前言

本次使用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 qtawesomefrom image_god_GUI import Ui_MainWindow as mainWindow
from webbrowser import open as open_url
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget, QTreeWidgetItem, QFileDialog, QAbstractItemView, \QMenu, QFileIconProvider, QMessageBox, QActionclass ImageGod(QMainWindow, mainWindow):pixRatio = 1def __init__(self):super(ImageGod, self).__init__()self.setupUi(self)self.ui_init()self.slot_init()def ui_init(self):def icon_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()def slot_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)def menu_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, ])def on_openDir_triggered(self):"""打开有图片的目录:return:"""def CreateTree(dirs, root, path):"""创建目录树:param dirs::param root::param path::return:"""for i in dirs:path_new = path + '\\' + iif 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)if not self.check_file(fileInfo.suffix()): continuechild = 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(["目录文件", "大小", "类型", "创建时间", "上次修改时间"])if not path: returndirs = 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, "警告", "选择的目录不存在图片文件!")def clear_dirTree(self):"""清空目录树:return:"""self.treeWidget.clear()self.action_broom.setEnabled(False)self.label.setPixmap(QPixmap(""))self.change_action_ui(False)def onTreeItemClicked(self, item, column):"""treeWidget节点被单击:return:"""file = item.data(column, Qt.UserRole)self.show_image(file)def show_image(self, file):if file:self.pixRatio = 1  # 每次都重置为1self.statusbar.showMessage(file)  # 将文件名展示到状态栏self.currPixmap.load(file)self.on_zoomFitH_triggered()self.change_action_ui(True)def show_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, "警告", "文件未找到")def onTreeWidgetCustomContextMenuRequested(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 != None and item1 != None and file != "":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()def on_zoomFitH_triggered(self):"""自动适应高度:return:"""height = self.scrollArea.height()readHeight = self.currPixmap.height()self.pixRatio = float(height) / readHeightpix = self.currPixmap.scaledToHeight(height - 30)self.label.setPixmap(pix)def on_zoomFitW_triggered(self):"""自动适应宽度:return:"""width = self.scrollArea.width()readHWidth = self.currPixmap.width()self.pixRatio = float(width) / readHWidthpix = self.currPixmap.scaledToWidth(width - 30)self.label.setPixmap(pix)def on_actionZoomIn_triggered(self):"""放大图片:return:"""self.pixRatio = self.pixRatio * 1.2width = self.pixRatio * self.currPixmap.width()height = self.pixRatio * self.currPixmap.height()pix = self.currPixmap.scaled(width, height)self.label.setPixmap(pix)def on_actionFid_triggered(self):"""自适应大小:return:"""self.pixRatio = 1self.label.setPixmap(self.currPixmap)def on_actionZoomOut_triggered(self):"""放大图片:return:"""pixRatio_tmp = self.pixRatioself.pixRatio = self.pixRatio * 0.8width = self.pixRatio * self.currPixmap.width()height = self.pixRatio * self.currPixmap.height()if width < self.scrollArea.width() and height < self.scrollArea.height():  # 避免缩小太小导致失真self.pixRatio = pixRatio_tmpreturnpix = self.currPixmap.scaled(width, height)self.label.setPixmap(pix)def closeEvent(self, event):reply = QMessageBox.question(self, '关闭', "确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)if reply == QMessageBox.Yes:event.accept()else:event.ignore()def check_dir(self, dir, root=False):"""查看文件夹是否有图片文件:param dir::return:"""for file in os.listdir(dir):file_abs = dir + '\\' + fileif os.path.isdir(file_abs):return Trueif "." in file:if self.check_file(file.split(".")[-1]):return Truereturn Falsedef check_file(self, suffix):"""看文件是否为图片文件:param suffix::return:"""if suffix in ['jpg', 'png', 'jpeg', 'psd', 'bmp', 'webp']:return Trueelse:return Falsedef change_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, QtWidgetsclass Ui_MainWindow(object):def setupUi(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)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.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。希望得到大家的赞,谢谢大家!
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部