窗口对象的事件接着步骤二继续
【Python+PyQt】pdf页面尺寸统计工具步骤二:获取拖入目录的所有pdf文件完整路径,存入file_path这个list中⑵
def dragEnterEvent(self, event):
if len(file_path) == 0: # 如果文件列表为空,说明一个PDF文件都没有。
self.label_info.setText("一个PDF文件都没有。")
return
current_path = os.path.dirname(file_path[0])
self.setWindowTitle(current_path) # 窗口标题显示有点不合适,以后再改。
list_temp = []
list_unknownsize = [] # 记录全部文件的未知尺寸,以[['filename', {(297,420):6, (420,594):3}], [], []]的形式
for f in file_path:
# 注意记录未知尺寸的文件名。以['filename', {(297,420):6, (420, 594):3}]的形式。
dict_temp, dict_unknownsize = GetSizeNameAndCount(GetPdfsize(f)) # 临时字典变量和临时字符串变量分别接收此函数的两个返回值。第一个返回值是该文件的尺寸字典,第二个返回值是未知尺寸内容。
if len(dict_unknownsize) > 0: # 未知尺寸字典长度不为空,说明当前文件有未知尺寸明细。
list_unknownsize.append([f, dict_unknownsize])
list_temp.append([GetDirnameOfFile(f), dict_temp]) # 将当前这个文件的所在目录和它的尺寸字典,以两项列表的形式,添加到list_temp列表中。
list_samedir = SameDirSizeTotal(list_temp) # 合计相同上级目录的尺寸信息
list_total = total(list_samedir) # 作表格最后一行合计。
list_lastinfo = form_size_table(list_samedir) # 补全所有key列中的空值。便于在表格中展示。
list_lastinfo += list_total # 最后合计行的信息
里面用到了两个自定义函数 GetPdfsize()和GetSizeNameAndCount()
def GetPdfsize(filepath):
"""
根据传入的pdf文件路径,返回该文件的尺寸(长和宽),较小的值在左。注意要判断只接收pdf文件
:param filepath:
:return: 列表形式返回文件内页面尺寸,每一页尺寸一个元组,是列表中的一项。
"""
list_size = []
pdf = PyPDF2.PdfReader(filepath)
for pagenum in range(0, len(pdf.pages)):
p = pdf.pages[pagenum - 1]
w = float(p.mediabox.width) * 0.352
h = float(p.mediabox.height) * 0.352
# 一律设置尺寸两数值的左边为较小值。
if w > h:
w, h = h, w
list_size.append((round(w), round(h)))
return list_size
# 单页返回[(593, 419)],
#多页返回[(298, 421), (595, 841), (202, 298), (298, 421), (298, 421), (298, 421), (298, 421), (298, 421), (298, 421),(298, 421)]
def GetSizeNameAndCount(size_list: list):
'''
根据传入的尺寸列表,返回列表所示的尺寸名称和数量
# print(GetSizeNameAndCount(
# [(298, 421), (595, 841), (202, 298), (410, 2080), (410, 2091), (298, 421), (594, 1260), (298, 421), (298, 421),
# (298, 421), (298, 421),
# (420, 743), (410, 2080)]))
对于不在尺寸明细表中的尺寸,进行未知尺寸统计。分两种情况,一:若宽度在5种类型之外,直接判断为未知尺寸。二:若宽度在5种类型之中,而长度不在。认定为未知尺寸。
:param size_list: 包含长宽尺寸的列表
:return: 返回字典,key表示尺寸名,value表示数量。返回包含尺寸类型和数量的字典,例如:{'A3': 6, 'A1': 1, 'A4': 1, 'A2+5/2': 3, 'A1+1/2': 1, 'A2+1/4': 1}
'''
dict_unknownsize = {} # 未知尺寸明细字典,记录当前这个文件中,未知尺寸的明细。相同未知尺寸还需要合计。
SizeNameList = {}
for i in size_list:
is_find = False # 搜索尺寸明细表之前,初始化找到标记为False
if inrange(i[0], 210 - size_error, 210 + size_error): # A4大类
for item in dict_SizeDetail[210]:
if inrange(i[1], item[0] - size_error,
item[0] + size_error): # 如果某较大尺寸值与尺寸明细表中的大值,符合size_error模糊匹配时,取得item[1]的值,里面是对应的尺寸名
# print(item[1])
if item[1] not in SizeNameList:
SizeNameList[item[1]] = 1
else:
SizeNameList[item[1]] += 1
is_find = True # 在尺寸明细中找到对应值,作找到标记。
break # 一旦找到尺寸,立即退出当前循环
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
elif inrange(i[0], 297 - size_error, 297 + size_error): # A3大类
for item in dict_SizeDetail[297]:
if inrange(i[1], item[0] - size_error,
item[0] + size_error): # 如果某较大尺寸值与尺寸明细表中的大值,符合size_error模糊匹配时,取得item[1]的值,里面是对应的尺寸名
# print(item[1])
if item[1] not in SizeNameList:
SizeNameList[item[1]] = 1
else:
SizeNameList[item[1]] += 1
is_find = True # 在尺寸明细中找到对应值,作找到标记。
break # 一旦找到尺寸,立即退出当前循环
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
elif inrange(i[0], 410, 430): # A2大类。当页面尺寸(获取尺寸时已经将较小值放左边了)为约420时,判断为A2图,进一步判断是A2还是A2加长。
for item in dict_SizeDetail[420]:
if inrange(i[1], item[0] - size_error,
item[0] + size_error): # 如果某较大尺寸值与尺寸明细表中的大值,符合size_error模糊匹配时,取得item[1]的值,里面是对应的尺寸名
# print(item[1])
if item[1] not in SizeNameList:
SizeNameList[item[1]] = 1
else:
SizeNameList[item[1]] += 1
is_find = True # 在尺寸明细中找到对应值,作找到标记。
break # 一旦找到尺寸,立即退出当前循环
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
elif inrange(i[0], 584, 594 + size_error): # A1大类
for item in dict_SizeDetail[594]:
if inrange(i[1], item[0] - size_error,
item[0] + size_error): # 如果某较大尺寸值与尺寸明细表中的大值,符合size_error模糊匹配时,取得item[1]的值,里面是对应的尺寸名
# print(item[1])
if item[1] not in SizeNameList:
SizeNameList[item[1]] = 1
else:
SizeNameList[item[1]] += 1
is_find = True # 在尺寸明细中找到对应值,作找到标记。
break # 一旦找到尺寸,立即退出当前循环
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
elif inrange(i[0], 831, 859): # A0大类
for item in dict_SizeDetail[841]:
if inrange(i[1], item[0] - size_error,
item[0] + size_error): # 如果某较大尺寸值与尺寸明细表中的大值,符合size_error模糊匹配时,取得item[1]的值,里面是对应的尺寸名
# print(item[1])
if item[1] not in SizeNameList:
SizeNameList[item[1]] = 1
else:
SizeNameList[item[1]] += 1
is_find = True # 在尺寸明细中找到对应值,作找到标记。
break # 一旦找到尺寸,立即退出当前循环
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
else: # 不属于5大类的未知尺寸。上面属于5大类,但也没有对应尺寸。也需列入未知尺寸。
print(f'不属于5大类的未知尺寸{i}')
if not is_find: # 如果没找到尺寸明细,记录未知尺寸。
if i not in dict_unknownsize:
dict_unknownsize[i] = 1
else:
dict_unknownsize[i] += 1
if " 未知尺寸" not in SizeNameList:
SizeNameList[" 未知尺寸"] = 1
else:
SizeNameList[" 未知尺寸"] += 1
return SizeNameList, dict_unknownsize
def inrange(value, start, end):
'''
判断给定的一个值是否在区间内。
:param value:
:param start:
:param end:
:return:
'''
if start <= end:
return start <= value <= end
else:
return start >= value >= end
通过file_path列表循环,将目录下每个文件的尺寸信息以字典形式保存。
dict_temp, dict_unknownsize = GetSizeNameAndCount(GetPdfsize(f)) # 临时字典变量和临时字符串变量分别接收此函数的两个返回值。第一个返回值是该文件的尺寸字典,第二个返回值是未知尺寸内容。
# dict_temp可能为单个文件:{'A4': 59}、{'A0': 1}、{'A3': 1}、{'A0+1/2': 1}、{' 未知尺寸': 1}、{' 未知尺寸': 25},组合文件:{'A1': 36, 'A4': 2}