前言
昨天我们通过短视频的启发实现了一个开机自动清理用户临时文件的脚本工具。想了解的可以参考为什么网吧电脑能一直保持流畅运行?一个python脚本让你的电脑能够和网吧电脑看齐~。
想到之前我们还做过一个桌面文件整理器,可以实现文件的批量整理。六十来行python代码完成一个文件分类器。
前两天我们还学习了一个GUI的项目Gooey,可以帮助我们快速完成一个GUI界面设计。原来用它写GUI界面就十行代码的事,值得收藏~~
那菜鸟小白就在想,综合这三篇小文章,我们能否实现一个带GUI界面的文件处理器呢?答案当然是肯定的啦。接下来我们就详细说明一下我们实现这个内容的思考方式。
思路梳理
我们的目标是完成一个带有GUI界面的,能够实现指定文件夹清理文件功能和指定文件夹中根据文件后缀进行归类整理的功能。那我们需要实现一个GUI界面可以选择两种文件操作的功能,然后对不同的功能配置不同的参数输入,调用我们之前实现的函数然后实现我们的需求功能(不清楚功能实现的请自行翻阅前言中说的文章)。大致的流程是这样的。
python代码实现
接下来我们就来看看通过python怎么实现这个功能,首先我们需要完成一个GUI界面的设计,由于之前已经有过Gooey的说明,就不再进行详细的说明了,只是说一说之前没有提到的部分。
由于这次我们分为多个功能,所以我们需要一个选择框,不同功能实现出现不同的界面输入,这个就需要我们通过add_subparser这个功能来实现。下面是文件清理的界面。
代码语言:javascript复制 parser = gooey.GooeyParser(description='GUI') # 配置名称
subs = parser.add_subparsers(help='commands', dest='command')
file_remove_parser = subs.add_parser('文件清理')
file_remove_parser.add_argument('--清理的文件夹路径', default='无', help='清输入需要清理的文件夹', widget='TextField') # 文本输入框
file_remove_parser.add_argument('--文件保留天数', default=30, help='设置需要保留文件的天数,默认为30天', widget='TextField') # 文本输入框
file_arrange_parser = subs.add_parser('文件整理')
其中'--清理的文件夹路径'前面的“--”代表这个参数是可选参数。
两个功能的页面实现之后我们需要判断用户填入的功能是哪个,然后根据用户的选择情况实现不同的功能。
代码语言:javascript复制 if get_type == '文件清理':
clear_path = args.清理的文件夹路径 # 获取输入框内容
unused_time = float(args.文件保留天数)
file_remove(clear_path, unused_time)
elif get_type == "文件整理":
arrange_path = args.整理的文件夹路径
arrange_flag = args.是否保留原文件
arranged_path = args.整理后的文件夹路径
file.file_main(arrange_path, arranged_path, arrange_flag)
GUI界面的整体代码如下:
代码语言:javascript复制@Gooey(encodings='utf-8', program_name='菜鸟小白的文件处理器', optional_cols=3, program_description='文件处理器', language='chinese')
def main():
parser = gooey.GooeyParser(description='GUI') # 配置名称
subs = parser.add_subparsers(help='commands', dest='command')
file_remove_parser = subs.add_parser('文件清理')
file_remove_parser.add_argument('--清理的文件夹路径', default='无', help='清输入需要清理的文件夹', widget='TextField') # 文本输入框
file_remove_parser.add_argument('--文件保留天数', default=30, help='设置需要保留文件的天数,默认为30天', widget='TextField') # 文本输入框
file_arrange_parser = subs.add_parser('文件整理')
file_arrange_parser.add_argument('--整理的文件夹路径', default='桌面', help='清输入需要整理的文件夹,默认为桌面文件夹', widget='TextField')
file_arrange_parser.add_argument('--整理后的文件夹路径', default='桌面', help='清输入整理后文件存放的文件夹', widget='TextField')
file_arrange_parser.add_argument('--是否保留原文件', default='1', help='此项配置仅针对非桌面文件夹有效,保留请输入‘1’,不保留请输入‘2’', widget='TextField')
args = parser.parse_args()
print(args, flush=True)
get_type = args.command
if get_type == '文件清理':
clear_path = args.清理的文件夹路径 # 获取输入框内容
unused_time = float(args.文件保留天数)
file_remove(clear_path, unused_time)
elif get_type == "文件整理":
arrange_path = args.整理的文件夹路径
arrange_flag = args.是否保留原文件
arranged_path = args.整理后的文件夹路径
file.file_main(arrange_path, arranged_path, arrange_flag)
我们接下来看看这个界面的运行效果。
GUI实现了之后,我们需要实现上面调用的两个函数:文件清理函数(file_remove)和文件整理函数(file.file_main),这两个函数都是使用之前的实现代码移植过来的。
我们先来看看文件清理函数(file_remove)的实现,只是将昨天的文件清理函数的两个输入参数通过传参的形式进行接收过来处理就好了。
代码语言:javascript复制def file_remove(path, unused_time):
time_now = time.time()
old_threshold = time_now - float(unused_time) * 24 * 60 * 60
files = os.listdir(path)
for file_name in files:
file_pathname = os.path.join(path, file_name)
if not os.path.isdir(file_pathname):
access_time = os.stat(file_pathname).st_mtime
if access_time < old_threshold:
os.remove(file_pathname)
print(file_pathname ' removed')
我们再看看文件整理函数(file.file_main)的实现,这个也是一样,将之前的文件分类器的代码的输入参数通过传参的形式接收到进行处理(之前文章有说过这一块的详细说明,这里也不再赘述了)。
代码语言:javascript复制def FileHandle(goal_path, mkdir_path, flag):
file_num = 0
path_num = 0
for file in glob.glob(f'{goal_path}/**/*', recursive=True):
if os.path.isfile(file):
filename = os.path.basename(file)
if '.' in filename:
suffix = filename.split('.')[-1]
else:
suffix = 'others'
if not os.path.exists(f'{mkdir_path}/{suffix}'):
os.mkdir(f'{mkdir_path}/{suffix}')
path_num = 1
shutil.copy(file, f'{mkdir_path}/{suffix}')
file_num = 1
if flag == "2":
shutil.rmtree(goal_path)
return file_num, path_num
def DesktopHandle(goal_path, mkdir_path):
file_num = 0
path_num = 0
for file in glob.glob(f'{goal_path}/**/*', recursive=True):
if os.path.isfile(file):
filename = os.path.basename(file)
if '.' in filename:
suffix = filename.split('.')[-1]
else:
suffix = 'others'
if suffix == "exe" or suffix == "lnk":
pass
else:
if not os.path.exists(f'{mkdir_path}/{suffix}'):
os.mkdir(f'{mkdir_path}/{suffix}')
path_num = 1
shutil.copy(file, f'{mkdir_path}/{suffix}')
file_num = 1
return file_num, path_num
def WriteInfo(file_num, path_num, mkdir_path):
file_name = mkdir_path "info.txt"
with open(file_name, 'w', encoding='utf-8') as f:
f.write(f'整理完成,有{file_num}个文件分类到了{path_num}个文件夹中')
def file_main(arrange_path, arranged_path, arrange_flag):
if arrange_path == os.path.join(os.path.expanduser('~'), "Desktop"):
file_num, path_num = DesktopHandle(arrange_path, arranged_path)
else:
file_num, path_num = FileHandle(arrange_path, arranged_path, arrange_flag)
WriteInfo(file_num, path_num, arranged_path)
这样我们的文件处理器就完成了,成功实现了文件清理和文件分类的两个功能。我们通过一个演示视频来看看具体实现效果吧
http://mpvideo.qpic.cn/0bf2xqae4aaae4agd54vlzqfbpgdj26aatqa.f10002.mp4?dis_k=980ca40807fc5fc7496be298410da283&dis_t=1620895266&spec_id=MzI3MjM0MDM3Mg==1620895266&vid=wxv_1858873874218598402&format_id=10002