目标:解压 z i p zip zip 文件夹下的所有 w i n z i p winzip winzip 文件,当需要解压密码时,利用 t k i n t e r tkinter tkinter 弹框接收密码,最终把所有解压出来的文件放到 u n z i p unzip unzip 文件夹下
- p y z i p p e r pyzipper pyzipper : 0.3.5
- t k i n t e r tkinter tkinter : p y t h o n python python 内置包
文件分布情况:
把上面的六个普通文件每两个压缩为一个 w i n z i p winzip winzip 文件,其中 z i p _ 3. z i p zip\_3.zip zip_3.zip 是有密码的,密码如下图
C o d e : Code: Code:
import os
import pyzipper as pz
from pathlib import Path
import tkinter as tk
from tkinter import StringVar
zip_folder = r'C:\Users\Desktop\test\zip'
output_path = r'C:\Users\Desktop\test\unzip'
password = ''
filename_list = os.listdir(zip_folder)
for i in filename_list:
# 首先创建用于存放后面解压出来的文件的文件夹
unzip_files_folder_name = i.split('.')[0].strip()
unzip_path = Path(output_path).resolve().joinpath(unzip_files_folder_name)
if not os.path.exists(unzip_path):
os.mkdir(unzip_path)
# 循环直到输入正确密码
flag = 1
while flag:
try:
with pz.AESZipFile(os.path.join(zip_folder, i).strip()) as unzip:
unzip.extractall(path=unzip_path, pwd=bytes(password, 'utf-8'))
flag = 0
# 若报错,说明需要密码,这时候才会弹框
except RuntimeError:
root = tk.Tk()
root.title('') # 设置弹框的标题
root.geometry('200x80') # 设置弹框的大小
root.wm_attributes('-topmost', 1)
pwd_string = StringVar()
label1 = tk.Label(root, text="Please input the correct password.").pack()
text = tk.Entry(root, borderwidth=1, width=40, show='*', textvariable=pwd_string)
text.pack() # 由于文本框绑定了快捷键,因此先设置后打包
button = tk.Button(root, text="Confirm", command=lambda: [root.destroy()], width=10, height=1).pack() # 设置按钮属性
# 设置快捷键
root.bind('<Escape>', lambda event=None: root.destroy())
text.bind('<Return>', lambda event=None: root.destroy())
root.mainloop()
# 获取 passward 以在外部复用
password = pwd_string.get()
continue
运行结果:
几点要注意的地方:
- 即使解压文件不需要密码,给 p y z i p p e r pyzipper pyzipper 传入
pwd
参数也能正常运行 - 在这种情况,也就是以用户输入的密码作为 p y z i p p e r pyzipper pyzipper 函数的参数进行解压,在使用 t k i n t e r tkinter tkinter 时一定要把用户输入的密码传给能在外部使用的变量,这里的外部指的是 t k i n t e r tkinter tkinter 循环的外部,也就是执行 p y z i p p e r pyzipper pyzipper 的地方。在 t k i n t e r tkinter tkinter(内部)中,有一个用于接收文本框( E n t r y Entry Entry)中输入的类
StringVar
,通过它,我们就能实现把用户从框内输入的值从内部拿到外部。所以整个流程是: 用户在文本框输入 p a s s w a r d passward \space passward → \rightarrow → t k . E n t r y \space tk.Entry tk.Entry接收后在textvariabl
处传给 p w d _ s t r i n g ( S t r i n g V a r ) pwd\_string(StringVar) pwd_string(StringVar) → \rightarrow \space → 在循环外部使用StringVar
的类方法get
把密码值赋值给 p a s s w a r d passward passward - 设置文本框、按钮等 w i d g e t widget widget 时,若无需绑定快捷键(即代码中的
bind
),可以不为它们赋值,如代码中的 “ l a b e l 1 = label1= label1=” 就可以删去