电脑自带的图片浏览器,很好用,但不是万能的。现实中有各种特殊需求,因此有时为了方便,量身打造一款适合自己的图片浏览器可能是有必要的。各种特殊需求总是不一样的,我这儿的特殊需求就是:我有成百上千的图片需要查看,查看中当遇到特殊图片我需要把这张图片单独挑选出存放在一个文件夹下,然后进行下一张,重复这个过程挑选完这堆图片中所有特殊的图片存放在一个文件夹下。咋一看,你可能觉得这简单呀,何须自己弄个工具呀,你会怎么做?是 用电脑自带的图片浏览器一张张看,当遇到特殊问题图片,再把这张图片拎出来放在一个文件夹下,如果图片少这么做也是不错的选择,但是当图片比较多,而且你以后还会多次遇到这种情况,量身定制一款自己的图片浏览器是一个很不错的选择。下面就用PyQt5简单实现这一过程吧
       我使用的是PyCharm作为IDE,因此首先的安装这个软件,然后配置PyQt5,designer,.ui文件转.py文件工具等,这些网上有比较多额资料,在此不做说明。下面使用视图说一下完成这个任务的流程。

1、打开PyCharm ,启动designer,完成如下界面的各个组件搭建

本任务只需要5个组件,其中4个为Push Button 按钮,用于鼠标点击触发事件,1个Label控件用于显示图像;各个组件的一些属性设置可以在右侧查看修改,在此不细说。各个组件的名字最好重命名为和操作事件相关的字符,我的命名如上图右上边所示。这些在后续代码也要使用。

2、界面布局

组件创建设置属性好了以后,根据最终界面的形式,我把界面整体布局为水平布局,左侧为功能区按钮,右侧为图像显示区域;而左侧功能各个组件需要垂直布局一下;为了整个组件和界面随主窗体有缩放性,最后还需要整体布局一下。下面按布局的顺序一一说明一下。

2.1 按钮区域布局(竖直布局)

具体操作:先选中需要布局的这四个组件-----》右键单击,选中Lay out -----》选择竖直布局

2.2 按钮区和图像显示区域布局

具体操作:先选中2.1已经布局好的单击按钮组合和图像显示区Label组件-----》右键单击,选中Lay out -----》选择水平布局

经过上述操作后,形成的视图如下:

现在的界面看着很不好看,但没关系的,继续后面操作。

2.3  整体布局

具体操作:在非含有上述几个组件的区域-----》右键单击,选中Lay out -----》选择水平布局或竖直布局,的到的界面乳腺如下:

从图上可以看到按钮组合区域和图像显示区域平分水平区域,这样看着不美观,进行下面的调整就可。

2.4 水平布局比例调整

找到界面上的Objext Inspector 下的HorizontalLayout,选中它,在其下方的Property Editor找到layoutStretch,看到了原始的为0,0,我现在把他改为1,8,调整的示例和改后的界面如上图所示。

到现在为止界面的整体就算完成了,执行Ctr+R,得到如下图所示:

3 ui文件转化为py文件

实现ui文件转化为py文件需要安装工具,在此假设安装了。具体在此不叙述。回到PyCharm主界面,选中刚才的ui文件---》右键,找到External Tools---》PyUIC(这个是我的ui文件转py文件工具名),单击它就会在PyCharm工程目录下出现了和ui文件同名的py文件。这个过程也来一张截图吧直观。

在此把这个原始的py文件代码也贴在这里吧

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'ScanImTool.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(1193, 747)font = QtGui.QFont()font.setPointSize(12)font.setBold(False)font.setWeight(50)MainWindow.setFont(font)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)self.horizontalLayout_2.setObjectName("horizontalLayout_2")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.verticalLayout = QtWidgets.QVBoxLayout()self.verticalLayout.setObjectName("verticalLayout")self.OpenDirBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.OpenDirBnt.setFont(font)self.OpenDirBnt.setIconSize(QtCore.QSize(20, 20))self.OpenDirBnt.setObjectName("OpenDirBnt")self.verticalLayout.addWidget(self.OpenDirBnt)self.PreImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.PreImBnt.setFont(font)self.PreImBnt.setObjectName("PreImBnt")self.verticalLayout.addWidget(self.PreImBnt)self.NextImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.NextImBnt.setFont(font)self.NextImBnt.setObjectName("NextImBnt")self.verticalLayout.addWidget(self.NextImBnt)self.CopyCurImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(15)font.setBold(False)font.setItalic(False)font.setUnderline(False)font.setWeight(50)font.setStrikeOut(False)font.setKerning(True)self.CopyCurImBnt.setFont(font)self.CopyCurImBnt.setStyleSheet("background-color: rgb(255, 0, 0);")self.CopyCurImBnt.setFlat(False)self.CopyCurImBnt.setObjectName("CopyCurImBnt")self.verticalLayout.addWidget(self.CopyCurImBnt)self.horizontalLayout.addLayout(self.verticalLayout)self.ImShowLabel = QtWidgets.QLabel(self.centralwidget)self.ImShowLabel.setStyleSheet("background-color: rgb(255, 255, 255);")self.ImShowLabel.setText("")self.ImShowLabel.setObjectName("ImShowLabel")self.horizontalLayout.addWidget(self.ImShowLabel)self.horizontalLayout.setStretch(0, 1)self.horizontalLayout.setStretch(1, 8)self.horizontalLayout_2.addLayout(self.horizontalLayout)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 1193, 26))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "图片查看器"))MainWindow.setToolTip(_translate("MainWindow", "<html><head/><body><p>t</p></body></html>"))self.OpenDirBnt.setText(_translate("MainWindow", "打开目录"))self.PreImBnt.setText(_translate("MainWindow", "上一张图"))self.NextImBnt.setText(_translate("MainWindow", "下一张图"))self.CopyCurImBnt.setText(_translate("MainWindow", "拷贝当前图"))self.ImShowLabel.setToolTip(_translate("MainWindow", "Image Show Region"))

这个py文件就是刚才ui界面的代码表达形式,这个原始py文件是不能直接运行的,需要添加一些回调函数和主函数才能运行起来的。

4、功能区回调函数的实现

看了代码就知道原始文件是不能直接运行的,没有main函数呀,但即使加了也没啥意义,因为你点击那些按钮也不给你执行什么功能,因此我们需要在上述代码中添加一些函数来完成这些功能。由于前面已经说得比较详细,而且代码也觉得还算简洁,故直接贴上不用过多解释了,有些python的知识一看就懂了。

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'ScanImTool.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
##2019/05/12 by DQfrom PyQt5 import QtCore, QtGui, QtWidgets
##########################################
import sys,os
import datetime
import shutilCurFolder=os.getcwd()
DefaultImFolder=CurFolder
NowTime=datetime.datetime.now()
Month=str(NowTime.month).zfill(2)
Day=str(NowTime.day).zfill(2)
Hour=str(NowTime.hour).zfill(2)
Minute=str(NowTime.minute).zfill(2)
##########################################class Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(1193, 747)font = QtGui.QFont()font.setPointSize(12)font.setBold(False)font.setWeight(50)MainWindow.setFont(font)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)self.horizontalLayout_2.setObjectName("horizontalLayout_2")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.verticalLayout = QtWidgets.QVBoxLayout()self.verticalLayout.setObjectName("verticalLayout")self.OpenDirBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.OpenDirBnt.setFont(font)self.OpenDirBnt.setIconSize(QtCore.QSize(20, 20))self.OpenDirBnt.setObjectName("OpenDirBnt")self.verticalLayout.addWidget(self.OpenDirBnt)self.PreImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.PreImBnt.setFont(font)self.PreImBnt.setObjectName("PreImBnt")self.verticalLayout.addWidget(self.PreImBnt)self.NextImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(20)font.setBold(True)font.setWeight(75)self.NextImBnt.setFont(font)self.NextImBnt.setObjectName("NextImBnt")self.verticalLayout.addWidget(self.NextImBnt)self.CopyCurImBnt = QtWidgets.QPushButton(self.centralwidget)font = QtGui.QFont()font.setPointSize(15)font.setBold(False)font.setItalic(False)font.setUnderline(False)font.setWeight(50)font.setStrikeOut(False)font.setKerning(True)self.CopyCurImBnt.setFont(font)self.CopyCurImBnt.setStyleSheet("background-color: rgb(255, 0, 0);")self.CopyCurImBnt.setFlat(False)self.CopyCurImBnt.setObjectName("CopyCurImBnt")self.verticalLayout.addWidget(self.CopyCurImBnt)self.horizontalLayout.addLayout(self.verticalLayout)self.ImShowLabel = QtWidgets.QLabel(self.centralwidget)self.ImShowLabel.setStyleSheet("background-color: rgb(255, 255, 255);")self.ImShowLabel.setText("")self.ImShowLabel.setObjectName("ImShowLabel")self.horizontalLayout.addWidget(self.ImShowLabel)self.horizontalLayout.setStretch(0, 1)self.horizontalLayout.setStretch(1, 8)self.horizontalLayout_2.addLayout(self.horizontalLayout)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 1193, 26))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)################定义相关变量并初始化################self.ImFolder = '' #图片文件夹路径self.ImNameSet = [] #图片集合self.CurImId = 0 #当前显示图在集合中的编号self.CopyImFolder = '' #Copy图片存放的文件夹self.MainWindow = MainWindow################button按钮点击事件回调函数################self.OpenDirBnt.clicked.connect(self.OpenDirBntClicked)self.NextImBnt.clicked.connect(self.NextImBntClicked)self.PreImBnt.clicked.connect(self.PreImBntClicked)self.CopyCurImBnt.clicked.connect(self.CopyCurImBntClicked)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "图片查看器"))MainWindow.setToolTip(_translate("MainWindow", "<html><head/><body><p>t</p></body></html>"))self.OpenDirBnt.setText(_translate("MainWindow", "打开目录"))self.PreImBnt.setText(_translate("MainWindow", "上一张图"))self.NextImBnt.setText(_translate("MainWindow", "下一张图"))self.CopyCurImBnt.setText(_translate("MainWindow", "拷贝当前图"))self.ImShowLabel.setToolTip(_translate("MainWindow", "Image Show Region"))#########选择图片文件夹#########def OpenDirBntClicked(self):ImFolder = QtWidgets.QFileDialog.getExistingDirectory(None,"select folder", DefaultImFolder)#这个语句有些邪门if ImFolder!='':ImNameSet = os.listdir(ImFolder)ImNameSet.sort()ImPath = os.path.join(ImFolder, ImNameSet[0])pix = QtGui.QPixmap(ImPath)self.ImShowLabel.setPixmap(pix)self.ImFolder=ImFolderself.ImNameSet=ImNameSetself.CurImId=0_,SelectFolderName=os.path.split(ImFolder)CopyImFolderName = 'From{}CopyIm_{}-{}-{}-{}'.format(SelectFolderName, Month, Day, Hour, Minute)self.CopyImFolder = os.path.join(CurFolder, CopyImFolderName)_translate = QtCore.QCoreApplication.translateCurWinTitle = "看图工具1.0                                                " +\"                                                             " +\SelectFolderName+'\\'+ImNameSet[0]self.MainWindow.setWindowTitle(_translate("MainWindow", CurWinTitle))else:print('请重新选择文件夹')#########显示下一张图片 #########def NextImBntClicked(self):ImFolder=self.ImFolderImNameSet = self.ImNameSetCurImId = self.CurImIdImNum = len(ImNameSet)if CurImId<ImNum-1:#不可循环看图ImPath = os.path.join(ImFolder, ImNameSet[CurImId+1])pix = QtGui.QPixmap(ImPath)self.ImShowLabel.setPixmap(pix)self.CurImId = CurImId+1_, SelectFolderName = os.path.split(ImFolder)_translate = QtCore.QCoreApplication.translateCurWinTitle = "看图工具1.0                                                " + \"                                                             " + \SelectFolderName + '\\' + ImNameSet[CurImId+1]self.MainWindow.setWindowTitle(_translate("MainWindow", CurWinTitle))#########显示前一张图片 #########def PreImBntClicked(self):ImFolder = self.ImFolderImNameSet = self.ImNameSetCurImId = self.CurImIdImNum = len(ImNameSet)if CurImId>0:#第一张图片没有前一张ImPath = os.path.join(ImFolder, ImNameSet[CurImId -1])pix = QtGui.QPixmap(ImPath)self.ImShowLabel.setPixmap(pix)self.CurImId = CurImId -1_, SelectFolderName = os.path.split(ImFolder)_translate = QtCore.QCoreApplication.translateCurWinTitle = "看图工具1.0                                                " + \"                                                             " + \SelectFolderName + '\\' + ImNameSet[CurImId -1]self.MainWindow.setWindowTitle(_translate("MainWindow", CurWinTitle))if self.CurImId<0:self.CurImId=0#########copy 当前图片函数 #########def CopyCurImBntClicked(self):ImFolder = self.ImFolderImNameSet = self.ImNameSetCurImId = self.CurImIdImPath = os.path.join(ImFolder, ImNameSet[CurImId])CopyImFolder=self.CopyImFolderif not os.path.isdir(CopyImFolder):os.makedirs(CopyImFolder)shutil.copy(ImPath,CopyImFolder)#########主函数入口 #########
if __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)mainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(mainWindow)mainWindow.show()sys.exit(app.exec_())

现在运行一下这个程序,找一些图片放置在一个文件夹下,试试看这个程序达到最初设想的功能了吗?如果你觉得这样使用这个工具每次在pycharm中启动不是很爽,那就执行第5步把它编译成exe文件,我想放哪里用就放哪里用。

5、py文件打包成exe文件

要实现这个功能,需要安装一个打包python程序未exe的库:pyinstaller,这个库的安装在此也不叙述。假设已经安装。如此的话,首先切换到cmd命令行,然后在其下执行:pyinstaller.exe -F -w E:\CodeProject\PythonProject\ViewImGUI\ScanImTool.py

其过程如图:

不要问我这条语句的具体解释我也是粘贴网上的。执行完上述命令,过会就会在adminstor某个文件夹下得到exe文件,具体在那个文件可以从最终的编译终端显示得到,如下图(这张图接上面的图,显示信息太多,上面的那张图截屏不下):

找到红色区域的位置,这个exe文件就在那里。好了现在你可以想放哪里用就放哪里用。

最后把这个小工具拿来试试,下面截取了两张图:

我把整个工程文件以及示例图片一并打包放置在这里:https://download.csdn.net/download/lingyunxianhe/11422828

积分本来想设置为1的,但自己不能设置了,就这样吧

啊这个过程还是有些小长。终于写完了。有些特别小的细节没有说明,但那都不重要了,有点python和qt基本知识的应该都一看就能懂得。

利用PyQt打造一款适合自己的图片浏览器相关推荐

  1. 自己动手,打造一款适合 Python 程序员的 Html5 音乐播放器

    近期断断续续读了一些 Web Audio API 和 WebRTC API 的文档,发现了很多好玩的东西,有一种"忽入桃花源"的感觉.这一款 Html5 音乐播放器,就是基于 We ...

  2. 李晓慧:如何利用MongoDB打造爆款小程序

    本文整理自作者在云加社区线下沙龙活动中的精彩分享,主题内容大概是两部分,第一部分:在现网运营中服务小游戏以及爆款小游戏积累的经验.在现网运维中我们做了一些改动,帮助爆款小游戏能够稳定运行. 第二部分我 ...

  3. 如何打造一款适合中老年人群体的产品?

    现在中国人口日益老龄化严重,中老年群体比例越来越大,市场需求很大,是一个很好的开发市场,但是针对于中老年人群体的产品不是特别多,也没有做的很出色的产品,大部分就是上来直接卖各种保健品等商品,看重目前的 ...

  4. 盛迈坤电商:自然流量怎么样打造爆款

    每个电商平台都有自己的引流方法.拼多多有很多活动可以作为引流方式,比如说限时秒杀.限购.拼多多团购等.但是还有一个可以通过利用商店的新爆款吸引自然流量.具体怎么做? 1. 对于产品选择,你需要先对你店 ...

  5. 安卓机适合用的手机浏览器,可下载视频可锁屏

    手机浏览器千千万,然而真正无广.好用的却没有多少个.曾经简约.广受好评的夸克浏览器,因为体积越来越大,功能越来越离谱而遭吐槽.今天,给大家带来一款简约.功能强大.无广告无新闻的手机浏览器,尤其适合安卓 ...

  6. 学计算机学生笔记本电脑实用,介绍四款适合学生党的笔记本电脑

    开一年一季的开学季又到了,恭喜的莘莘学子经过十年寒窗,终于考上了自己理想的大学,对于没有考上的学子你也不要气馁,毕竟过去不是炫耀未来的资本,未来还需努力.进入大学很多学生及其家长都在犹豫要不要在大一入 ...

  7. 如何通过病毒营销打造爆款产品

    病毒营销是通过提供有价值的产品或服务,让用户主动对其进行传播实现"营销杠杆"的作用,逐步获得尽人皆知,尽人参与的成效.如今,病毒式营销已经成为网络营销最为独特的手段,被越来越多的商 ...

  8. 实战:深度解析 淘宝打造爆款之淘客推广

    爆款,就是流量大.销量高.人气高.排名高,最重要是转化高了,一个店铺如果有一款爆款,就相当于一个引流利器,如果再把其他产品转化做好,那挣钱真是太容易了.特别是对于很多中小卖家们来说,打造爆款就是求生之 ...

  9. 如何打造一款好的社区产品

    http://blog.csdn.net/lzpsnake/article/details/8472510 如何打造一款好的社区产品,如何去吸引用户.激发用户的参与热情,如何维持社区的长久发展动力,这 ...

最新文章

  1. 《深入理解Spark:核心思想与源码分析》——3.10节创建和启动ExecutorAllocationManager...
  2. [Python图像处理] 二十八.OpenCV快速实现人脸检测及视频中的人脸
  3. Android添加Header请求参数实例,java响应header请求实现demo
  4. 关于字节对齐以及内存占用
  5. 如何解决大量的if语句或switch case语句?
  6. 卸载软件 Geek Uninstaller
  7. linux不解压情况下查看压缩包内文件的总行数、文件列表的数目
  8. php公物管理系统,开源客户管理系统 fly-crm
  9. 茎叶图、箱图是什么,如何用SPSS实现?(图文)
  10. BatteryProperty上报流程
  11. 历史上的今天——4月1日
  12. 360快传号,会成为下一个自媒体风口吗?
  13. 通俗理解极大似然估计
  14. 高速PCB损耗性能的影响分析
  15. DG232RL与FT232RL/GP232RL兼容开发资料
  16. 用不起!中国移动首个5G套餐确认,最低消费118元!
  17. ubuntu16 安装UR5e driver
  18. Pod 一直停留在 Terminating 状态,我等得花儿都谢了~
  19. 2000万日订单背后,如何保障系统的高可用?
  20. androidUSB通信——打印机

热门文章

  1. 【Java集合框架】16 ——NavigableSet 接口
  2. 使用 Nginx 实现 HTTPS 网站设置
  3. 回溯法解决tsp问题 matlab,回溯法求解tsp问题
  4. Program type already present问题解决
  5. 正则中文逗号转英文逗号
  6. v21.07 鸿蒙内核源码分析(线程概念) | 是谁在不断的折腾CPU | 百篇博客分析OpenHarmony源码
  7. 搞定 Redis 数据存储原理,别只会 set、get 了
  8. 制作ttylinux实例
  9. 程序员读老子,第一章
  10. 抢红包案例分析以及代码实现(三) 侵立删