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 篇原創文章 · 獲贊 1135 · 訪問量 49萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章