基于Python自制一個(gè)文件解壓縮小工具
經(jīng)常在辦公的過程中會(huì)遇到各種各樣的壓縮文件處理,但是呢每個(gè)壓縮軟件支持的格式又是不同的。
沒有可以一種可以同時(shí)多種格式的并且免費(fèi)的文件解壓縮工具,于是我使用python的PyQt5開發(fā)出這個(gè)文件解壓縮的小工具。
接下來,我們將開發(fā)過程中需要的python非標(biāo)準(zhǔn)庫(kù)以及代碼塊做一個(gè)簡(jiǎn)單的介紹,有興趣的小伙伴可以停下腳步一起來看看。
一般在windows的操作系統(tǒng)下文件解壓縮的格式就是7z/zip/rar這三種,首先我們需要安裝一下PyQt5以及需要文件解壓縮處理的模塊。
這里我們直接使用的是pip的安裝方式進(jìn)行安裝,我的pip默認(rèn)配置的是全局的清華大學(xué)鏡像站。
pip?install?PyQt5 pip?install?py7zr pip?install?rarfile
然后,在開始之前我們將需要的python標(biāo)準(zhǔn)或非標(biāo)準(zhǔn)模塊全部導(dǎo)入代碼塊中準(zhǔn)備進(jìn)入下面的開發(fā)環(huán)節(jié)。
#?Importing?all?the?classes?from?the?PyQt5.QtGui?module. from?PyQt5.QtGui?import?* #?Importing?all?the?classes?from?the?PyQt5.QtWidgets?module. from?PyQt5.QtWidgets?import?* #?Importing?all?the?classes?from?the?PyQt5.QtCore?module. from?PyQt5.QtCore?import?* #?`import?os`?is?importing?the?os?module. import?os #?`import?sys`?is?importing?the?sys?module. import?sys #?`import?zipfile?as?zip`?is?importing?the?zipfile?module?as?zip. import?zipfile?as?zip #?`import?py7zr`?is?importing?the?py7zr?module. import?py7zr #?`import?rarfile?as?rar`?is?importing?the?rarfile?module?as?rar. import?rarfile?as?rar #?Importing?the?traceback?module. import?traceback import?images
至此,我們開發(fā)需要使用到的python模塊就全部導(dǎo)入進(jìn)來了,這里說明一下我們使用到的英文注釋是通過pycharm的AI插件直接生成的。
首先,創(chuàng)建一個(gè)名稱為CompressUI的python類,將所有的UI頁面組件及布局全部放在這個(gè)類中進(jìn)行開發(fā)。
以及包括UI頁面組件關(guān)聯(lián)的槽函數(shù)也放在這個(gè)類中,也就是在CompressUI類中我們只處理頁面操作相關(guān)的部分不做具體邏輯的實(shí)現(xiàn)。
class?CompressUI(QWidget): ????def?__init__(self): ????????super(CompressUI,?self).__init__() ????????self.init_ui() ????def?init_ui(self): ????????self.setWindowTitle('文件解壓縮處理工具?公眾號(hào):Python 集中營(yíng)') ????????self.setWindowIcon(QIcon(':/analysis.ico')) ????????self.resize(600,?400) ????????self.compress_file_type?=?QLabel() ????????self.compress_file_type.setText('解壓縮文件類型:') ????????self.compress_file_type_combox?=?QComboBox() ????????self.compress_file_type_combox.addItems(['7z格式',?'zip格式',?'rar格式']) ????????self.file_catch_type?=?QLabel() ????????self.file_catch_type.setText('文件處理方式:') ????????self.file_catch_type_combox?=?QComboBox() ????????self.file_catch_type_combox.addItems(['壓縮',?'解壓縮']) ????????self.source_dir_or_file?=?QLineEdit() ????????self.source_dir_or_file.setPlaceholderText('來源目錄或文件路徑...') ????????self.source_dir_or_file_btn?=?QPushButton() ????????self.source_dir_or_file_btn.setText('加載來源目錄或文件') ????????self.source_dir_or_file_btn.clicked.connect(self.source_dir_or_file_btn_clk) ????????self.target_dir_or_file?=?QLineEdit() ????????self.target_dir_or_file.setPlaceholderText('目標(biāo)目錄路徑...') ????????self.target_dir_or_file_btn?=?QPushButton() ????????self.target_dir_or_file_btn.setText('選擇目標(biāo)路徑') ????????self.target_dir_or_file_btn.clicked.connect(self.target_dir_or_file_btn_clk) ????????self.start_btn?=?QPushButton() ????????self.start_btn.setText('開始執(zhí)行文件壓縮或解壓縮處理') ????????self.start_btn.clicked.connect(self.start_btn_clk) ????????self.brower?=?QTextBrowser() ????????self.brower.setReadOnly(True) ????????self.brower.setFont(QFont('宋體',?8)) ????????self.brower.setPlaceholderText('日志處理過程區(qū)域...') ????????self.brower.ensureCursorVisible() ????????grid?=?QGridLayout() ????????grid.addWidget(self.compress_file_type,?0,?0,?1,?2) ????????grid.addWidget(self.compress_file_type_combox,?0,?2,?1,?1) ????????grid.addWidget(self.file_catch_type,?1,?0,?1,?2) ????????grid.addWidget(self.file_catch_type_combox,?1,?2,?1,?1) ????????grid.addWidget(self.source_dir_or_file,?2,?0,?1,?2) ????????grid.addWidget(self.source_dir_or_file_btn,?2,?2,?1,?1) ????????grid.addWidget(self.target_dir_or_file,?3,?0,?1,?2) ????????grid.addWidget(self.target_dir_or_file_btn,?3,?2,?1,?1) ????????grid.addWidget(self.start_btn,?4,?0,?1,?3) ????????grid.addWidget(self.brower,?5,?0,?1,?3) ????????self.thread_?=?WorkThread(self) ????????self.thread_.message.connect(self.show_message) ????????self.thread_.finished.connect(self.thread_is_finished) ????????self.setLayout(grid) ????def?show_message(self,?text): ????????cursor?=?self.brower.textCursor() ????????cursor.movePosition(QTextCursor.End) ????????self.brower.append(text) ????????self.brower.setTextCursor(cursor) ????????self.brower.ensureCursorVisible() ????def?target_dir_or_file_btn_clk(self): ????????target_dir_or_file_path?=?QFileDialog.getExistingDirectory(self,?'選擇文件夾',?os.getcwd()) ????????self.target_dir_or_file.setText(target_dir_or_file_path) ????def?source_dir_or_file_btn_clk(self): ????????file_catch_type?=?self.file_catch_type_combox.currentText() ????????if?file_catch_type?==?'壓縮': ????????????source_dir_or_file_path?=?QFileDialog.getExistingDirectory(self,?'選擇文件夾',?os.getcwd()) ????????????self.source_dir_or_file.setText(source_dir_or_file_path) ????????else: ????????????source_dir_or_file_path?=?QFileDialog.getOpenFileName(self,?"選取文件",?os.getcwd(), ??????????????????????????????????????????????????????????????????"RAR?File?(*.rar);;ZIP?File?(*.zip);;7z?File?(*.7z)") ????????????self.source_dir_or_file.setText(source_dir_or_file_path[0]) ????def?start_btn_clk(self): ????????self.start_btn.setEnabled(False) ????????self.thread_.start() ????def?thread_is_finished(self,?text): ????????if?text?is?True: ????????????self.start_btn.setEnabled(True)
以上就是整個(gè)UI頁面組件/布局以及組件對(duì)應(yīng)的槽函數(shù)的的開發(fā)過程了,有需要的小伙伴可以仔細(xì)研究一下。
接下來進(jìn)入具體業(yè)務(wù)的開發(fā)環(huán)節(jié),我們創(chuàng)建一個(gè)名稱為WorkThread的python類,該類繼承自QThread的子線程。
并且在子線程中可以接收主線程的變量參數(shù),以及向主線程中傳遞信息的操作。將子線程執(zhí)行的過程信息實(shí)時(shí)傳遞到主線程的文本瀏覽器中。
class?WorkThread(QThread): ????message?=?pyqtSignal(str) ????finished?=?pyqtSignal(bool) ????def?__init__(self,?parent=None): ????????super(WorkThread,?self).__init__(parent) ????????self.parent?=?parent ????????self.working?=?True ????def?__del__(self): ????????self.working?=?False ????def?run(self): ????????try: ????????????compress_file_type?=?self.parent.compress_file_type_combox.currentText() ????????????file_catch_type?=?self.parent.file_catch_type_combox.currentText() ????????????source_dir_or_file?=?self.parent.source_dir_or_file.text().strip() ????????????target_dir_or_file?=?self.parent.target_dir_or_file.text().strip() ????????????if?source_dir_or_file?==?''?or?target_dir_or_file?==?'': ????????????????self.message.emit('來源或目標(biāo)文件路徑為空,請(qǐng)檢查參數(shù)設(shè)置!') ????????????????return ????????????if?file_catch_type?==?'壓縮'?and?os.path.isfile(source_dir_or_file): ????????????????self.message.emit('當(dāng)處理類型為:壓縮,來源類型應(yīng)該選擇文件夾,請(qǐng)按順序設(shè)置參數(shù)!') ????????????????return ????????????if?file_catch_type?==?'解壓縮'?and?os.path.isdir(source_dir_or_file): ????????????????self.message.emit('當(dāng)處理類型為:解壓縮,來源類型應(yīng)該選擇文件,請(qǐng)按順序設(shè)置參數(shù)!') ????????????????return ????????????self.message.emit('準(zhǔn)備處理的格式類星星為:{}'.format(compress_file_type)) ????????????self.message.emit('準(zhǔn)備處理的處理類型為:{}'.format(file_catch_type)) ????????????self.message.emit('來源文件或目錄的路徑為:{}'.format(source_dir_or_file)) ????????????self.message.emit('目標(biāo)目錄的路徑為:{}'.format(target_dir_or_file)) ????????????if?compress_file_type?==?'zip格式': ????????????????if?file_catch_type?==?'壓縮': ????????????????????self.do_zip(source_dir_or_file,?target_dir_or_file) ????????????????else: ????????????????????self.un_zip(source_dir_or_file,?target_dir_or_file) ????????????elif?compress_file_type?==?'rar格式': ????????????????if?file_catch_type?==?'壓縮': ????????????????????self.message.emit('rar格式的文件壓縮正在玩命開發(fā)中,請(qǐng)關(guān)注后續(xù)版本更新!') ????????????????else: ????????????????????self.un_rar(source_dir_or_file,?target_dir_or_file) ????????????elif?compress_file_type?==?'7z格式': ????????????????if?file_catch_type?==?'壓縮': ????????????????????self.do_7z(source_dir_or_file,?target_dir_or_file) ????????????????else: ????????????????????self.un_7z(source_dir_or_file,?target_dir_or_file) ????????????self.message.emit('當(dāng)前處理過程:{}完成!'.format(file_catch_type)) ????????????self.finished.emit(True) ????????except: ????????????traceback.print_exc() ????????????self.finished.emit(True) ????def?do_zip(self,?source_,?target_file): ????????""" ????????If?the?user?selects?the?"壓縮"?option,?then?the?user?can?select?a?directory,?and?the?path?of?the?directory?will?be ????????displayed?in?the?text?box ????????""" ????????zip_file?=?zip.ZipFile(target_file,?'w') ????????pre_len?=?len(os.path.dirname(source_)) ????????for?parent,?dirnames,?filenames?in?os.walk(source_): ????????????for?filename?in?filenames: ????????????????print(f'{filename}') ????????????????path_file?=?os.path.join(parent,?filename) ????????????????arcname?=?path_file[pre_len:].strip(os.path.sep) ????????????????zip_file.write(path_file,?arcname) ????????zip_file.close() ????def?un_zip(self,?source_file,?target_): ????????""" ????????>?Unzip?a?file?to?a?target?directory ????????:param?source_file:?The?file?you?want?to?unzip ????????:param?target_:?the?directory?where?you?want?to?unzip?the?file ????????""" ????????zip_file?=?zip.ZipFile(source_file) ????????if?os.path.isdir(target_): ????????????pass ????????else: ????????????os.mkdir(target_) ????????for?names?in?zip_file.namelist(): ????????????zip_file.extract(names,?target_) ????????zip_file.close() ????def?do_7z(self,?source_,?target_file): ????????""" ????????>?This?function?takes?a?source?file?and?a?target?file?and?compresses?the?source?file?into?the?target?file?using?7z ????????:param?source_:?The?source?file?or?directory?to?be?compressed ????????:param?target_file:?The?name?of?the?file?to?be?created ????????""" ????????with?py7zr.SevenZipFile(target_file,?'r')?as?file: ????????????file.extractall(path=source_) ????def?un_7z(self,?source_file,?target_): ????????""" ????????It?takes?a?source?directory?and?a?target?file,?and?creates?a?zip?file?containing?the?contents?of?the?source ????????directory ????????:param?source_:?The?path?to?the?folder?you?want?to?zip ????????:param?target_file:?The?path?to?the?zip?file?you?want?to?create ????????""" ????????with?py7zr.SevenZipFile(source_file,?'w')?as?file: ????????????file.writeall(target_) ????def?un_rar(self,?source_file,?target_): ????????""" ????????It?takes?a?source?file?and?a?target?directory?and?unzips?the?source?file?into?the?target?directory ????????:param?source_file:?The?path?to?the?RAR?file?you?want?to?extract ????????:param?target_:?The?directory?where?you?want?the?files?to?be?extracted?to ????????""" ????????obj_?=?rar.RarFile(source_file.decode('utf-8')) ????????obj_.extractall(target_.decode('utf-8'))
最后,使用python模塊的主函數(shù)main,將整個(gè)應(yīng)用加入到主體循環(huán)過程中就可以啟動(dòng)整個(gè)桌面應(yīng)用了。
if?__name__?==?'__main__': ????app?=?QApplication(sys.argv) ????main?=?CompressUI() ????main.show() ????sys.exit(app.exec_())
完成上述的開發(fā)工作之后,我們可以選擇使用常用的pyinstaller打包模塊對(duì)整個(gè)應(yīng)用進(jìn)行打包操作,打包細(xì)節(jié)可以參考我的歷史文章中的說明!
到此這篇關(guān)于基于Python自制一個(gè)文件解壓縮小工具的文章就介紹到這了,更多相關(guān)Python文件解壓縮工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python協(xié)程方式的實(shí)現(xiàn)及意義筆記分享
協(xié)程也被稱為微線程,是一種用戶態(tài)的上下文切換技術(shù),簡(jiǎn)而言之,就是通過一個(gè)線程實(shí)現(xiàn)代碼互相切換執(zhí)行,本文主要給大家介紹實(shí)現(xiàn)協(xié)程的幾種方法2021-09-09Python個(gè)人博客程序開發(fā)實(shí)例后臺(tái)編寫
這篇文章主要介紹了怎樣用Python來實(shí)現(xiàn)一個(gè)完整的個(gè)人博客系統(tǒng),我們通過實(shí)操上手的方式可以高效的鞏固所學(xué)的基礎(chǔ)知識(shí),感興趣的朋友一起來看看吧2022-12-12python中將字典形式的數(shù)據(jù)循環(huán)插入Excel
這篇文章主要介紹了python中將字典形式的數(shù)據(jù)循環(huán)插入Excel的方法,需要的朋友可以參考下2018-01-01matplotlib設(shè)置顏色、標(biāo)記、線條,讓你的圖像更加豐富(推薦)
這篇文章主要介紹了matplotlib設(shè)置顏色、標(biāo)記、線條,讓你的圖像更加豐富,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Python 實(shí)現(xiàn)日志同時(shí)輸出到屏幕和文件
這篇文章主要介紹了Python 實(shí)現(xiàn)日志同時(shí)輸出到屏幕和文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02淺談pyhton學(xué)習(xí)中出現(xiàn)的各種問題(新手必看)
下面小編就為大家?guī)硪黄獪\談pyhton學(xué)習(xí)中出現(xiàn)的各種問題(新手必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05解決pycharm上的jupyter notebook端口被占用問題
今天小編就為大家分享一篇解決pycharm上的jupyter notebook端口被占用問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12使用PyInstaller將Pygame庫(kù)編寫的小游戲程序打包為exe文件及出現(xiàn)問題解決方法
這篇文章主要介紹了使用PyInstaller將Pygame庫(kù)編寫的小游戲程序打包為exe文件的方法,給大家介紹了通過Pyinstaller打包Pygame庫(kù)寫的小游戲程序出現(xiàn)的問題及解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09