一、引言
因办公要求,经常需要对众多、各类文件(夹)进行重命名(如大量原始照片本来是以姓名.jpg形式命名的,但是要求提交的格式是“身份证号码.jpg”)。人数少还好说,人数大就是一个稍微复杂的问题了。当然这个问题也可以通过“暴力”的方式解决(具体怎么“暴力”,我就不多赘述了),但是工作效率会大大折扣。所以,为极大提高办公效率,就谋生了这个想法。
二、gui界面设计
使用pyqt5进行界面的搭建,最终界面如下:
1.第一步:确定待命名文件所在的文件夹
直接点击,即可弹出文件夹选择对话框。该文件夹存储的是:所有待命名文件(夹)。即所有待命名文件(架)都应放置在这个文件夹中。
假设有100个文件夹,名称从1-100,而这100个文件夹被存放在“新建文件夹”中。
第一步选取成功后,会弹出成功的对话框。
2.第二步:下载并填写对应表文件(.xlsx)
直接点击即可下载。
该对应表文件(.xlsx)中共有两列(如下图),列名分别为“旧文件(夹)名称(含类型后缀.xxx)”和“新文件(夹)名称(含类型后缀.xxx)”,两者分别代表着待命名文件(夹)的现有名称(即旧名称)、命名完成后的文件(夹)名称(即新名称)。只需将待命名文件(夹)的名称填写到第一列,再将其一一对应的新名称填写到第二列,保存即可。
说明:如果遇到大量文件(夹)时,暴力方法不能瞬时获取其文件名称,即第一列的旧名称不好填写时,那么请看这里:一键曝光:python+pyqt实现文件目录。而有了第一列的数据后,第二列在excel中使用最常用的vlookup函数即可按需求一一匹配搞定。
注意:无论是新名称还是旧名称,都需要将其后缀也一一对应填写在表格中(如下图)。因为上述的测试举例对象被随意选取为文件夹,本身无(.xxx)后缀,所以在表格中直接写的就是文件名称(1-100分别对应200-299,上图只截取了一部分);如果想对图片(.jpg、.png等类型)、文本文档.txt、doc文档.doc、docx文档.docx、ppt演示文稿.ppt、pptx演示文稿.pptx、xls工作表.xls、xlsx工作表.xlsx等多种类型进行重命名(已测试通过,可以实现),则需要把后缀也写入到单元格中。
当然,如果已经之前用过该系统了,跳过此步骤,直接到第三步也可以。
3.第三步:上传对应表文件(.xlsx)
点击后,弹出文件选择对话框。
对文件没有名称的限制,只要格式为工作表.xlsx就可以;当然也可以覆盖重复上传多次。弹出的文件对话框如下:
同样,会有上传成功的提示。
4.第四步:开始批量重命名
直接点击,即可实现大量对文件(夹)的批量迅速重命名。
当然也会有命名成功的提示。
最终的命名效果如下,可以看到,不费一分力,直接瞬间完成批量重命名。
5.使用提示
当未进行第一步和第三步,直接单击“开始批量重命名”会有如下提示,请按提示操作即可(当然,若缺少第一步和第三步的任意一步,均会有对应提示;如果已经有第二步的对应表文件了,可以直接跳过第二步,且不会报错)。
如果已经完成批量重命名了,但是还持续点击“开始批量重命名”,则会有如下提示。
6.界面设计jiemian.py
最后附上通过pyuic5产生的gui界面代码jiemian.py:
# -*- coding: utf-8 -*- # form implementation generated from reading ui file 'jiemian.ui' # # created by: pyqt5 ui code generator 5.15.11 # # 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 class ui_form(object): def setupui(self, form): form.setobjectname("form") form.setenabled(true) form.resize(400, 600) form.setminimumsize(qtcore.qsize(400, 600)) form.setmaximumsize(qtcore.qsize(400, 600)) icon = qtgui.qicon() icon.addpixmap(qtgui.qpixmap(":/image1.png"), qtgui.qicon.normal, qtgui.qicon.off) form.setwindowicon(icon) self.label = qtwidgets.qlabel(form) self.label.setgeometry(qtcore.qrect(60, 250, 201, 21)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(12) font.setbold(false) font.setweight(50) self.label.setfont(font) self.label.setobjectname("label") self.groupbox = qtwidgets.qgroupbox(form) self.groupbox.setgeometry(qtcore.qrect(50, 240, 291, 81)) self.groupbox.setautofillbackground(false) self.groupbox.settitle("") self.groupbox.setflat(false) self.groupbox.setobjectname("groupbox") self.pushbutton_3 = qtwidgets.qpushbutton(self.groupbox) self.pushbutton_3.setgeometry(qtcore.qrect(70, 40, 191, 23)) self.pushbutton_3.setobjectname("pushbutton_3") self.pushbutton_2 = qtwidgets.qpushbutton(form) self.pushbutton_2.setgeometry(qtcore.qrect(50, 540, 291, 31)) self.pushbutton_2.setobjectname("pushbutton_2") self.label_5 = qtwidgets.qlabel(form) self.label_5.setgeometry(qtcore.qrect(230, 70, 141, 31)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(16) self.label_5.setfont(font) self.label_5.setobjectname("label_5") self.label_8 = qtwidgets.qlabel(form) self.label_8.setgeometry(qtcore.qrect(70, 20, 251, 31)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(18) font.setbold(false) font.setweight(50) self.label_8.setfont(font) self.label_8.setobjectname("label_8") self.label_10 = qtwidgets.qlabel(form) self.label_10.setgeometry(qtcore.qrect(310, 60, 71, 51)) self.label_10.settext("") self.label_10.setpixmap(qtgui.qpixmap(":/image1.png")) self.label_10.setobjectname("label_10") self.label_2 = qtwidgets.qlabel(form) self.label_2.setgeometry(qtcore.qrect(60, 350, 201, 21)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(12) font.setbold(false) font.setweight(50) self.label_2.setfont(font) self.label_2.setobjectname("label_2") self.groupbox_2 = qtwidgets.qgroupbox(form) self.groupbox_2.setgeometry(qtcore.qrect(50, 340, 291, 81)) self.groupbox_2.setautofillbackground(false) self.groupbox_2.settitle("") self.groupbox_2.setflat(false) self.groupbox_2.setobjectname("groupbox_2") self.pushbutton_4 = qtwidgets.qpushbutton(self.groupbox_2) self.pushbutton_4.setgeometry(qtcore.qrect(70, 40, 191, 23)) self.pushbutton_4.setobjectname("pushbutton_4") self.label_3 = qtwidgets.qlabel(form) self.label_3.setgeometry(qtcore.qrect(60, 450, 201, 21)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(12) font.setbold(false) font.setweight(50) self.label_3.setfont(font) self.label_3.setobjectname("label_3") self.groupbox_3 = qtwidgets.qgroupbox(form) self.groupbox_3.setgeometry(qtcore.qrect(50, 440, 291, 81)) self.groupbox_3.setautofillbackground(false) self.groupbox_3.settitle("") self.groupbox_3.setflat(false) self.groupbox_3.setobjectname("groupbox_3") self.pushbutton_5 = qtwidgets.qpushbutton(self.groupbox_3) self.pushbutton_5.setgeometry(qtcore.qrect(70, 40, 191, 23)) self.pushbutton_5.setobjectname("pushbutton_5") self.groupbox_5 = qtwidgets.qgroupbox(form) self.groupbox_5.setgeometry(qtcore.qrect(20, 120, 351, 481)) self.groupbox_5.settitle("") self.groupbox_5.setobjectname("groupbox_5") self.label_7 = qtwidgets.qlabel(form) self.label_7.setgeometry(qtcore.qrect(60, 150, 281, 21)) font = qtgui.qfont() font.setfamily("adobe arabic") font.setpointsize(12) font.setbold(false) font.setweight(50) self.label_7.setfont(font) self.label_7.setobjectname("label_7") self.groupbox_6 = qtwidgets.qgroupbox(form) self.groupbox_6.setgeometry(qtcore.qrect(50, 140, 291, 81)) self.groupbox_6.setautofillbackground(false) self.groupbox_6.settitle("") self.groupbox_6.setflat(false) self.groupbox_6.setobjectname("groupbox_6") self.pushbutton_6 = qtwidgets.qpushbutton(self.groupbox_6) self.pushbutton_6.setgeometry(qtcore.qrect(70, 40, 191, 23)) self.pushbutton_6.setobjectname("pushbutton_6") self.groupbox_5.raise_() self.groupbox_2.raise_() self.groupbox_6.raise_() self.groupbox_3.raise_() self.groupbox.raise_() self.label.raise_() self.pushbutton_2.raise_() self.label_5.raise_() self.label_8.raise_() self.label_10.raise_() self.label_2.raise_() self.label_3.raise_() self.label_7.raise_() self.retranslateui(form) self.pushbutton_2.clicked.connect(form.close) # type: ignore qtcore.qmetaobject.connectslotsbyname(form) def retranslateui(self, form): _translate = qtcore.qcoreapplication.translate form.setwindowtitle(_translate("form", "batch_rename")) self.label.settext(_translate("form", "二、请下载对应表文件:")) self.pushbutton_3.settext(_translate("form", "点击下载对应表模板文件")) self.pushbutton_2.settext(_translate("form", "退出系统")) self.label_5.settext(_translate("form", "designed by")) self.label_8.settext(_translate("form", "文件批量重命名系统")) self.label_2.settext(_translate("form", "三、请上传对应表文件:")) self.pushbutton_4.settext(_translate("form", "点击上传对应表模板文件")) self.label_3.settext(_translate("form", "四、开始批量重命名:")) self.pushbutton_5.settext(_translate("form", "开始批量重命名")) self.label_7.settext(_translate("form", "一、请选择待命名文件所在的文件夹:")) self.pushbutton_6.settext(_translate("form", "点击选择待命名文件所在的文件夹")) import ziyuan_rc
三、主要程序详解
1.导入所需模块
import sys,os import openpyxl from jiemian import * from pyqt5.qtwidgets import qapplication, qwidget # 保持窗口大小和qtdesigner中的一致 from pyqt5 import qtcore qtcore.qcoreapplication.setattribute(qtcore.qt.aa_enablehighdpiscaling) from openpyxl import workbook
不懂为啥需要导入qtcore的,请看一键曝光:python+pyqt实现的文件目录。
2.初始化设置
class login_interface(qwidget, ui_form): def __init__(self): super(qwidget, self).__init__() self.setupui(self) # 绑定信号 self.pushbutton_3.clicked.connect(self.xiazai) self.pushbutton_4.clicked.connect(self.shangchuan) self.pushbutton_5.clicked.connect(self.kaishi) self.pushbutton_6.clicked.connect(self.daimingming) # 设置按键标志位 self.duqu_flag = false self.shangchuan_flag = false # 初始化定义新、旧名称列表 self.duqu = [] self.jiumingcheng = [] self.xinmingcheng = [] # 待命名的文件所在文件夹的路径 self.lujing = ""
对一些pushbutton绑定相应信号;duqu_flag和shangchuan_flag是标志位,用于判断用户是否完成步骤一和步骤三,以便进行后续操作;列表duqu用于存放所有待命名文件的名称(如果有后缀的话则包含后缀);列表jiumingcheng代表对应表文件中的第一列数据(除列名以外;如果有后缀的话则包含后缀);列表xinmingcheng代表对应表文件中的第二列数据(除列名以外;如果有后缀的话则包含后缀);lujing表示待命名文件(夹)所在文件夹的路径。
3.确定待命名文件所在的文件夹
def daimingming(self): # 读取待命名的所有文件名称 filepath = qtwidgets.qfiledialog.getexistingdirectory(self, "请选取存放待命名文件的文件夹") # 获取文件夹的路径 try: if filepath: self.lujing = filepath self.duqu = os.listdir(filepath) self.duqu = str_genggai(self.duqu) self.duqu_flag = true qtwidgets.qmessagebox.information(self, "成功", "选取存放待命名文件的文件夹成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请选择合适的文件夹!") except: qtwidgets.qmessagebox.critical(self, "提示", "请选择合适的文件夹!")
通过qfiledialog获取其所在的路径filepath,并赋值给lujing;使用os.listdir()读取所有文件(夹)的名称,为避免后期出现内容相符,但因格式不一致而匹配不到的问题(如1与'1'不相等,虽 然都表示数字1,但前者是int类型,后者是str类型),提前在此通过自定义函数str_genggai将其强制转换为str类型。
4.设置对应表文件(.xlsx)格式
def xiazai(self): # 下载对应表模板文件 wb = workbook() ws = wb.active ws.column_dimensions['a'].width = 36 ws.column_dimensions['b'].width = 36 ws.cell(row=1, column=1, value="旧文件(夹)名称(含类型后缀.xxx)") ws.cell(row=1, column=2, value="新文件(夹)名称(含类型后缀.xxx)") wb.save('duiyingbiao.xlsx') qtwidgets.qmessagebox.information(self,"成功","对应表模板文件下载成功,请查看!")
主要对列宽及列名进行设定。
5.上传并存储新、旧名称
def shangchuan(self): filepath, _ = qtwidgets.qfiledialog.getopenfilename(self, "请选择对应表文件", "", "xlsx工作表 (*.xlsx)") # 获取文件路径 try: if filepath: wb = openpyxl.load_workbook(filepath) # 根据获取到的文件路径来读取文件 sheet = wb['sheet'] # 读取文件中的新、旧名称 for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=1, max_col=1): for cell in row: self.jiumingcheng.append(cell.value) for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=2, max_col=2): for cell in row: self.xinmingcheng.append(cell.value) self.shangchuan_flag = true self.jiumingcheng = str_genggai(self.jiumingcheng) self.xinmingcheng = str_genggai(self.xinmingcheng) qtwidgets.qmessagebox.information(self, "成功", "对应表模板文件上传成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请选择xlsx工作表类型!") except: qtwidgets.qmessagebox.critical(self, "提示", "请选择正确的xlsx工作表类型!")
将对应表(.xlsx)的第一列内容从上至下按序存储在jiumingcheng中,将对应表(.xlsx)的第二列内容从上至下按序存储在xinmingcheng中。同样,为避免格式不一致,提前通过自定义函数str_genggai将其强制转换为str类型。最后,考虑特殊情况(如虽然打开了对话框,但并未上传对应表(.xlsx)文件等),处理异常。
6.开始批量重命名
def kaishi(self): # 根据标志位来判断按键/选择情况 try: if self.duqu_flag == true: if self.shangchuan_flag == true: rename(self.duqu,self.xinmingcheng,self.jiumingcheng, self.lujing) qtwidgets.qmessagebox.information(self, "成功", "所有文件命名成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤三:上传对应表文件!") else: if self.shangchuan_flag == true: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤一:选择待命名文件所在的文件夹!") else: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤一和步骤三!") except: qtwidgets.qmessagebox.critical(self, "提示", "已完成批量命名,请勿重复操作!")
以duqu_flag和shangchuan_flag两个标志位为条件进行判断,如若都满足,调用自定义函数rename进行批量重命名操作。
7.自定义函数
def str_genggai(filelist): # 将列表中的数据类型强制转换为str for i in filelist: index = filelist.index(i) filelist[index] = str(i) return filelist
def rename(liebiao, xin, jiu, filepath): for oldname in liebiao: if oldname in jiu: info_index = jiu.index(oldname) newname = xin[info_index] os.rename(filepath+'/'+oldname, filepath+'/'+newname)
注意:待命名的文件数不一定等于转换表里的旧名称数,所以要进行判断:只有在jiu里的才进行重命名。
四、总程序代码
import sys,os import openpyxl from jiemian import * from pyqt5.qtwidgets import qapplication, qwidget # 保持窗口大小和qtdesigner中的一致 from pyqt5 import qtcore qtcore.qcoreapplication.setattribute(qtcore.qt.aa_enablehighdpiscaling) from openpyxl import workbook class login_interface(qwidget, ui_form): def __init__(self): super(qwidget, self).__init__() self.setupui(self) # 绑定信号 self.pushbutton_3.clicked.connect(self.xiazai) self.pushbutton_4.clicked.connect(self.shangchuan) self.pushbutton_5.clicked.connect(self.kaishi) self.pushbutton_6.clicked.connect(self.daimingming) # 设置按键标志位 self.duqu_flag = false self.shangchuan_flag = false # 初始化定义新、旧名称列表 self.duqu = [] self.jiumingcheng = [] self.xinmingcheng = [] # 待命名的文件所在文件夹的路径 self.lujing = "" def daimingming(self): # 读取待命名的所有文件名称 filepath = qtwidgets.qfiledialog.getexistingdirectory(self, "请选取存放待命名文件的文件夹") # 获取文件夹的路径 try: if filepath: self.lujing = filepath self.duqu = os.listdir(filepath) self.duqu = str_genggai(self.duqu) self.duqu_flag = true qtwidgets.qmessagebox.information(self, "成功", "选取存放待命名文件的文件夹成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请选择合适的文件夹!") except: qtwidgets.qmessagebox.critical(self, "提示", "请选择合适的文件夹!") def xiazai(self): # 下载对应表模板文件 wb = workbook() ws = wb.active ws.column_dimensions['a'].width = 36 ws.column_dimensions['b'].width = 36 ws.cell(row=1, column=1, value="旧文件(夹)名称(含类型后缀.xxx)") ws.cell(row=1, column=2, value="新文件(夹)名称(含类型后缀.xxx)") wb.save('duiyingbiao.xlsx') qtwidgets.qmessagebox.information(self,"成功","对应表模板文件下载成功,请查看!") def shangchuan(self): filepath, _ = qtwidgets.qfiledialog.getopenfilename(self, "请选择对应表文件", "", "xlsx工作表 (*.xlsx)") # 获取文件路径 try: if filepath: wb = openpyxl.load_workbook(filepath) # 根据获取到的文件路径来读取文件 sheet = wb['sheet'] # 读取文件中的新、旧名称 for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=1, max_col=1): for cell in row: self.jiumingcheng.append(cell.value) for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=2, max_col=2): for cell in row: self.xinmingcheng.append(cell.value) self.shangchuan_flag = true self.jiumingcheng = str_genggai(self.jiumingcheng) self.xinmingcheng = str_genggai(self.xinmingcheng) qtwidgets.qmessagebox.information(self, "成功", "对应表模板文件上传成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请选择xlsx工作表类型!") except: qtwidgets.qmessagebox.critical(self, "提示", "请选择正确的xlsx工作表类型!") def kaishi(self): # 根据标志位来判断按键/选择情况 try: if self.duqu_flag == true: if self.shangchuan_flag == true: rename(self.duqu,self.xinmingcheng,self.jiumingcheng, self.lujing) qtwidgets.qmessagebox.information(self, "成功", "所有文件命名成功!") else: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤三:上传对应表文件!") else: if self.shangchuan_flag == true: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤一:选择待命名文件所在的文件夹!") else: qtwidgets.qmessagebox.critical(self, "提示", "请完成步骤一和步骤三!") except: qtwidgets.qmessagebox.critical(self, "提示", "已完成批量命名,请勿重复操作!") def str_genggai(filelist): # 将列表中的数据类型强制转换为str for i in filelist: index = filelist.index(i) filelist[index] = str(i) return filelist def rename(liebiao, xin, jiu, filepath): for oldname in liebiao: # 待命名的文件数不一定等于转换表里的旧名字数,所以要进行判断 # 只有在表里的才进行重命名,否则会报错 if oldname in jiu: info_index = jiu.index(oldname) newname = xin[info_index] os.rename(filepath+'/'+oldname, filepath+'/'+newname) if __name__ == '__main__': app = qapplication(sys.argv) w = login_interface() w.show() sys.exit(app.exec_())
以上就是python打造智能批量重命名工具的详细指南的详细内容,更多关于python重命名的资料请关注代码网其它相关文章!
发表评论