Python代码实现压缩软件

写在前面的话

       诗经有云:五月斯螽动股,六月莎鸡振羽,七月在野,八月在宇,九月在户,十月蟋蟀入我床下。十一月有点凉,十二月被窝到不了的地方都是远方。这句话的意思就是:五月蚱蜢弹腿跳,六月纺织娘振翅,七月蟋蟀在田野,八月来到屋檐下,九月蟋蟀进门口,十月钻进我床下。十一月天气有点凉,十二月被窝到不了的地方都是远方。

       既然天气这么冷,不想去远方,不如搞点事情吧~ 前几天因为工作关系,需要远程其他地方的电脑,为了方便,下载了某远程工具,结果自动安装上了一堆的流氓软件,其中就有一个压缩软件,天天推送一些不知所云的广告,让我花费了很大的力气才彻底清除。我在想能不能用Python自己实现一个压缩软件,这样自己用的也方便,也不怕有什么广告了,我们的故事便从这里开始……


一、相关库简介

       (1)zipfile库

       首先我想到了Python中有一个实现解压缩的很方便的库——zipfile库。zipfile用来做zip格式编码的压缩和解压缩,由于是很常见的zip格式,所以这个模块使用频率也是比较高。它有两个非常重要的class,分别是ZipFile和ZipInfo, 在绝大多数的情况下,只需要使用这两个class就可以。ZipFile是主要的类,用来创建和读取zip文件;ZipInfo是存储的zip文件的每个文件的信息的。

       (2)os库

       Python的os模块提供了简单方便的方法来使用操作系统的一些功能。就是说通过os库可以使用python执行一些常见的操作系统的功能,比如切换目录,增删文件,设置环境变量,运行shell 命令等等。以下是os库常用的部分:

os.sep:可以取代操作系统特定的路径分隔符。
os.name:字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。
os.getcwd():函数得到当前工作目录,即当前Python脚本工作的目录路径。
os.getenv():获取一个环境变量,如果没有返回none。
os.link():方法用于创建硬链接。
os.mkdir():方法用于以数字权限模式创建目录。
os.listdir(path):返回指定目录下的所有文件和目录名。
os.remove(path):函数用来删除一个文件。如果指定的路径是一个目录,将抛出OSError,在Unix,Windows中有效。
os.rmdir(path):方法用于删除指定路径的目录。仅当这文件夹是空的才可以,否则,抛出OSError。
os.system(command):函数用来运行shell命令。
os.linesep:字符串给出当前平台使用的行终止符。
os.curdir:返回当前目录('.')。
os.chdir(dirname):改变工作目录到dirname。

os.path常用方法:
os.path.isfile(path)和os.path.isdir(path)函数:分别检验给出的路径是一个文件还是目录,绝对路径。
os.path.existe():函数用来检验给出的路径是否真地存在。
os.path.getsize(name):获得文件大小。
os.path.abspath(name):获得绝对路径。
os.path.normpath(path):规范path字符串形式。
os.path.split(path):将path分割成目录和文件名二元组返回。
os.path.splitext():分离文件名与扩展名。
os.path.join(path,name):连接目录与文件名或目录;使用“\”连接。
os.path.basename(path):返回文件名。
os.path.dirname(path):返回文件路径​。

       (3)Tkinter组件

       Tkinter提供的各种控件如下图所示:

       Tkinter组件的标准属性(所有控件均有的属性)如下所示:

       Tkinter控件有特定的几何状态管理方法,管理整个控件区域组织,以下是Tkinter公开的几何管理类:包、网格、位置。

二、相关方法编写

       1、首先需要有选择文件的功能,例如:选择需要压缩的文件和选择需要解压缩的文件,方法如下:

def choose_compress_file():
    '''
    选择需要压缩的文件
    :return:
    '''
    compress_file_path_name.set(askdirectory())

def choose_uncompress_file():
    '''
    选择需要解压的文件
    :return:
    '''
    uncompress_file_path = askopenfilename()
    uncompress_file_path.replace("/", "\\\\")  # 字符转义
    uncompress_file_path_name.set(uncompress_file_path)

       2、选择文件的功能有了,就需要思考一个问题:解压的文件需要有一个解压的目录,所以此处还需要一个解压到某个目录的方法,如下:

def choose_uncompress_dir():
    '''
    选择解压到的目录
    :return:
    '''
    uncompress_file_terminal_path_name.set(askdirectory())

       3、然后,压缩、解压成功或者失败后是不是得需要设置一些信息进行以下提示,这里又需要压缩或解压成功、失败的提示信息方法,如下所示:

def compress_file_success_message():
    '''
    压缩文件成功后,弹出信息框
    :return:
    '''
    tkinter.messagebox.askokcancel(title='success', message='压缩成功!')

def uncompress_file_success_message():
    '''
    解压文件成功后,弹出信息框
    :return:
    '''
    tkinter.messagebox.askokcancel(title='success', message='解压成功!')

def uncompress_file_failure_message():
    '''
    解压失败弹出框
    :return:
    '''
    tkinter.messagebox.askokcancel(title='failed', message='这不是zip压缩文件!')

       4、这些基本方法设置完之后,就到了核心模块了——压缩和解压缩的方法。

def compress_file():
    '''
    压缩文件
    :return:
    '''
    # 给压缩文件加上.zip
    compress_file_name = compress_file_path_name.get() + '.zip'

    # 写入
    zip = zipfile.ZipFile(compress_file_name, 'w', zipfile.ZIP_DEFLATED)

    # 遍历目录路径、目录名、文件名
    for dirpath, dirnames, filenames in os.walk(compress_file_path_name.get()):
        fpath = dirpath.replace(compress_file_path_name.get(), '')
        fpath = fpath and fpath + os.sep or ''

        # 迭代文件名
        for filename in filenames:
            zip.write(os.path.join(dirpath, filename), fpath + filename)  # 写入
        zip.close()

        # 压缩成功,弹出信息框
        compress_file_success_message()

def upcompress_file():
    '''
    解压缩文件
    :return:
    '''
    # 判断是否为压缩文件,以文件后缀是否为.zip为判断依据
    is_true = zipfile.is_zipfile(uncompress_file_path_name.get())

    if is_true:
        # 读取压缩文件
        unzip = zipfile.ZipFile(uncompress_file_path_name.get(), 'r')
        # 遍历文件
        for file in unzip.namelist():
            # 输出文件
            unzip.extract(file, uncompress_file_terminal_path_name.get())

        # 解压成功,弹出信息框
        uncompress_file_success_message()
    else:
        # 解压失败,弹出信息框
        uncompress_file_failure_message()

       5、当然还得需要咱们的图形用户界面,所以此处还是设置一个图形用户界面的方法,如下:

def graphical_user_interface():
    '''
    图形用户界面
    :return:
    '''
    # label:ow代表label是放在第几行,column是放在第几列
    Label(root, text='压缩文件路径:').grid(row=0, column=0)

    # entry:获取输入
    Entry(root, textvariable=compress_file_path_name).grid(row=0, column=1)

    # 操作按钮
    Button(root, text='选择压缩文件', command=choose_compress_file).grid(row=0, column=2)

    # label标签
    Label(root, text='解压文件路径:').grid(row=1, column=0)

    # 获取输入
    Entry(root, textvariable=uncompress_file_path_name).grid(row=1, column=1)

    # 操作按钮
    Button(root, text='选择解压文件', command=choose_uncompress_file).grid(row=1, column=2)

    # label标签
    Label(root, text='解压到:').grid(row=2, column=0)

    # 获取输入
    Entry(root, textvariable=uncompress_file_terminal_path_name).grid(row=2, column=1)

    # 操作按钮
    Button(root, text='选择解压路径', command=choose_uncompress_dir).grid(row=2, column=2)

    # 操作按钮
    Button(root, text='点击压缩', command=compress_file).grid(row=3, column=0)

    # 操作按钮
    Button(root, text='点击解压', command=upcompress_file).grid(row=3, column=2)

    # 操作按钮
    Button(root, text='退出', command=root.quit).grid(row=4, column=1)

    # 显示操作界面
    root.mainloop()

       至此,所需要的所有方法均已经设置完毕。是时候进行测试了~

三、测试

if __name__ == '__main__':
    # 初始化,并设置文件名称
    root = Tk(className='轻压-极简版')
    # 设置标题,与root = Tk(className='轻压-极简版')有异曲同工之妙
    # root.title('轻压')

    # 设置压缩屏幕大小
    # root.geometry('1000x150')

    # 设置压缩图标
    # root.iconbitmap(default='xzw.ico')

    # 显示需要压缩的文件路径名
    compress_file_path_name = StringVar()

    # 显示需要解压的文件路径名
    uncompress_file_path_name = StringVar()

    # 显示文件想要解压到的路径名
    uncompress_file_terminal_path_name = StringVar()

    # 函数调用,显示图形用户界面
    graphical_user_interface()

       测试结果如下:

       点击相应的按钮可以进行压缩和解压缩的操作~ 这样又暴露出了一个问题,如果别人想用这个软件,但是又不具备Python环境,这样该怎么办呢?于是便有了一下打包成.exe文件的操作。

四、打包成.exe文件

       可以使用pyinstaller命令打包对应的.py文件。pyinstaller命令常用的参数如下所示:

-F, --onefile Py代码只有一个文件
-D, --onedir Py代码放在一个目录中(默认是这个)
-K, --tk 包含TCL/TK
-d, --debug 生成debug模式的exe文件
-w, --windowed, --noconsole 窗体exe文件(Windows Only)
-c, --nowindowed, --console 控制台exe文件(Windows Only)
-X, --upx 使用upx压缩exe文件
-o DIR, --out=DIR 设置spec文件输出的目录,默认在PyInstaller同目录
--icon=<FILE.ICO> 加入图标(Windows Only)
-v FILE, --version=FILE 加入版本信息文件

       这里,我们使用如下命令进行打包:

pyinstaller -w -F -i compressed_software/favicon.ico compressed_software/lkys.py

       在控制台出现如下情况说明打包成功:

        打包后的.exe文件会出现在项目的dist目录下,将其拷贝出来后,如下所示:

       点击运行,如下所示,说明成功:

五、一些并不怎么愉快的事情

       打包成.exe文件后,在运行时发生了一些并不怎么愉快的事情,首先运行的时候会报一个运行脚本发生错误的问题,如下所示:

       因为打包时使用了-w的参数,所以运行.exe文件并没有启动Windows窗口,故而再次打包。发现报了如下两个错误:

       1、_tkinter.TclError: bitmap "xzw.ico" not defined

       2、PermissionError: [Errno 13] Permission denied: 'picture.ico'

       相关错误的解决办法,有兴趣的可以点击错误链接查看。

六、源码

       源码已经同步至GitHub,有兴趣的同志可以点此进行查看~ 因为时间关系,此次压缩软件图形用户界面做的比较简陋,只能算是极简版,往后会慢慢的更新优化用户界面,相关代码也会在GitHub上实时更新,本篇文章到此结束,谢谢大家。

       你们在此过程中遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。

发布了253 篇原创文章 · 获赞 1152 · 访问量 50万+

猜你喜欢

转载自blog.csdn.net/gdkyxy2013/article/details/103757893