Python——pyqt5的计算器(源码+打包)
目錄
一、效果圖
二、源碼
三、如何打包
四、如何減小打包程序大小(方法1)
五、如何減小打包程序大小(方法2)
學(xué)習(xí)視頻
一、效果圖
只是單純的練手,然后再學(xué)習(xí)一下如何打包
?
二、源碼
calculator_UI.zip - 藍(lán)奏云
三、如何打包
安裝PyInstaller
pip install pyinstaller快速打包命令:
pyinstaller -wF -i logo.ico main.pymain.py:是我要打包的python項(xiàng)目文件
?-i:為main.exe文件指定的圖標(biāo)(如果沒有,則不需要該參數(shù))
logo.ico :生成.exe文件的圖標(biāo)(推薦一個(gè)在線轉(zhuǎn)換ico圖標(biāo)的網(wǎng)址)
-F:生成結(jié)果是一個(gè)exe文件,所有的第三方依賴、資源和代碼均被打包進(jìn)該exe內(nèi)
-w :不顯示命令行窗口(如不用此參數(shù),打包后的程序在運(yùn)行時(shí)會(huì)彈出一個(gè)命令行窗口)
打包成功
?
基本用法 :??pyinstaller [選項(xiàng)] 文件名.py
常用選項(xiàng)
-F, --onefile:將應(yīng)用程序打包為單個(gè)可執(zhí)行文件
-D, --onedir:將應(yīng)用程序打包為目錄
-c, --console:使用控制臺(tái)模式(在終端窗口中運(yùn)行應(yīng)用程序)
-w, --noconsole:使用Windows模式(沒有控制臺(tái)窗口)
--name:指定應(yīng)用程序的名稱
--distpath:指定輸出目錄
--clean:在打包之前清除臨時(shí)文件夾日志
-d, --debug:生成運(yùn)行時(shí)調(diào)試器
--log-level:設(shè)置日志級(jí)別,供調(diào)試嵌入其他文件
--add-data:將data文件夾嵌入到生成的可執(zhí)行文件中
--add-binary:將binary文件與其他文件一起嵌入到可執(zhí)行文件中
--hidden-import:打包特定的Python庫(kù),例如--hidden-import=PIL
--version:顯示版本信息
--help:顯示幫助信息
以上是_pyinstaller的常用選項(xiàng)和命令,可以根據(jù)需要進(jìn)行選擇和使用。
有時(shí)候,打包exe程序后的文件大小會(huì)非常大!如何減小呢?
四、如何減小打包程序大小(方法1)
1、安裝pipenv
pip install pipenv2、新建一個(gè)文件夾
安裝完成后,隨便找一個(gè)盤符,在這個(gè)盤符的根目錄(最好是根目錄)新建一個(gè)文件夾,作為虛擬環(huán)境,然后雙擊進(jìn)入該文件夾
3、安裝python版本(在虛擬環(huán)境下安裝所需的python版本)
pipenv install -python 3.6- 系統(tǒng)有可能提示無(wú)法轉(zhuǎn)換為 “utf-8”,具體原因是因?yàn)橹形霓D(zhuǎn)碼的問(wèn)題,但是不必深究。
- 這時(shí)候最好的方法是重啟電腦
- 重啟電腦后,不要打開任何其他程序,重復(fù)上述第2步
4、激活虛擬環(huán)境(在命令行下)
pipenv shell- 如何系統(tǒng)提示無(wú)法轉(zhuǎn)換為“utf-8”,則再次重啟電腦
- 然后重新進(jìn)入power shell,再嘗試運(yùn)行 pipenv shell
5、安裝需要的庫(kù)(僅需安裝需要打包的.py文件中所用到的庫(kù))
根據(jù)要打包的程序中需要導(dǎo)入的庫(kù),在pipenv環(huán)境下重新安裝,例如:
pipenv install pyinstaller pipenv install removebg6、進(jìn)行打包
把py腳本文件復(fù)制到這個(gè)新建的目錄下,重新運(yùn)行 pyinstaller
pyinstaller -wF -i logo.ico main.py?五、如何減小打包程序大小(方法2)
使用 PyInstaller 將 PyQt5 程序打包成 exe 文件,并用 UPX 壓縮生成的文件,即可生成盡可能小的 exe 文件。
1、安裝 PyInstaller 和 UPX
打開命令行窗口(Windows 下可以按下 Win+R 后,輸入 cmd 啟動(dòng)),輸入以下命令安裝 PyInstaller 和 UPX:
pip install pyinstaller pip install upx2、創(chuàng)建 PyInstaller 打包配置文件
在 PyInstaller 命令行中輸入以下命令,創(chuàng)建一個(gè)打包配置文件 myapp.spec:
pyinstaller -y -w myapp.py-y 表示自動(dòng)覆蓋現(xiàn)有的 build 和 dist 文件夾
-w 表示去除控制臺(tái)窗口
此時(shí)當(dāng)前目錄會(huì)出現(xiàn)一個(gè) build 文件夾和一個(gè) dist 文件夾,dist 文件夾中會(huì)生成一個(gè)不壓縮的 exe 文件。
3、修改 PyInstaller 打包配置文件
在當(dāng)前目錄下,使用編輯器打開 myapp.spec 文件,添加以下代碼:
import upx upx_path = "your_upx_path" # UPX 所在路徑a = Analysis(['myapp.py'],pathex=['your_path_for_py_file'], # myapp.py 所在路徑binaries=[],datas=[],hiddenimports=['sip', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets'],hookspath=['hooks'],runtime_tmpdir=None,excludes=[],win_no_prefer_redirects=False,win_private_assemblies=False,cipher=None,alg='AES256',key=None,upx=True, # 是否開啟壓縮upx_path=upx_path, # UPX 所在路徑console=False) pyz = PYZ(a.pure, a.zipped_data,cipher=None,alg='AES256',key=None,unbuffered=False) exe = EXE(pyz,a.scripts,a.binaries,a.zipfiles,a.datas,[],name='myapp',debug=False,bootloader_ignore_signals=False,strip=False,upx=True, # 經(jīng)過(guò)測(cè)試,tostring() 或 tobytes() 方法生成的資源文件即是這里的 a.zipped_dataupx_path=upx_path, # UPX 所在路徑upx_exclude=[],runtime_tmpdir=None,console=False,icon=None)注意:
upx_path 需要填寫 UPX.exe 所在的文件夾路徑
hiddenimports 需要添加 PyQt5 相關(guān)的模塊
4、打包 exe 文件
在命令行中輸入以下命令,將 myapp.spec 文件轉(zhuǎn)換為 exe 文件:
pyinstaller -y -c myapp.spec生成的文件在 dist 文件夾內(nèi),文件名是在 myapp.spec 文件中 name 參數(shù)指定的。
-c 表示使用控制臺(tái)程序,如果不需要控制臺(tái)程序,可以將 -c 改為 -w。
5、使用 UPX 壓縮 exe 文件
在命令行中輸入以下命令,使用 UPX 壓縮 exe 文件:
upx --best myapp.exemyapp.exe 是需要壓縮的文件名
--best 表示使用最高級(jí)別的壓縮
附代碼
import sysfrom PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QMainWindow, QApplicationfrom calculator import Ui_calculator_MainWindowclass MyMainForm(QMainWindow, Ui_calculator_MainWindow):def __init__(self, parent=None):super().__init__(parent)self.setupUi(self)self.start_x = Noneself.start_y = Noneself.anim=Noneself.setAttribute(QtCore.Qt.WA_TranslucentBackground)self.setWindowFlags(Qt.FramelessWindowHint) # 設(shè)置窗口標(biāo)志:隱藏窗口邊框# Bind button scale up and scale downself.btn_max.clicked.connect(self.btn_max_click)self.btn_min.clicked.connect(self.minimize)self.btn_stop.clicked.connect(self.closeEvent)# 輸入self.input = ''# 綁定方法self.bin_number()# 輸入顯示def add_input(self,input):self.input +=inputself.number_input.setPlainText(str(self.input))# 計(jì)算結(jié)果def calculate_res(self):try:self.number_output.display(eval(self.input))except Exception:self.number_input.setPlainText('輸入格式錯(cuò)誤!')self.input = ''finally:# self.input = ''pass# clear LCD numberdef clear_input(self):self.input = ''self.number_input.setPlainText('')# back one numberdef back_number(self):self.input = self.input[:-1]self.number_input.setPlainText(self.input)# add button eventsdef bin_number(self):# number eventsself.b_one.clicked.connect(lambda: self.add_input('1'))self.b_tow.clicked.connect(lambda: self.add_input('2'))self.b_three.clicked.connect(lambda: self.add_input('3'))self.b_four.clicked.connect(lambda: self.add_input('4'))self.b_five.clicked.connect(lambda: self.add_input('5'))self.b_six.clicked.connect(lambda: self.add_input('6'))self.b_seven.clicked.connect(lambda: self.add_input('7'))self.b_eight.clicked.connect(lambda: self.add_input('8'))self.b_nine.clicked.connect(lambda: self.add_input('9'))self.b_point.clicked.connect(lambda: self.add_input('.'))self.b_add.clicked.connect(lambda: self.add_input('+'))self.b_divide.clicked.connect(lambda: self.add_input('/'))self.b_multiple.clicked.connect(lambda: self.add_input('*'))self.a_substract.clicked.connect(lambda: self.add_input('-'))# calculate resultself.b_equal.clicked.connect(lambda: self.calculate_res())# back one numberself.b_back.clicked.connect(lambda: self.back_number())# clear inputself.b_clear.clicked.connect(lambda: self.clear_input())# Window scale up and scale downdef btn_max_click(self):if self.isMaximized():self.showNormal()# self.btn_stop.setText('放大窗口')else:self.showMaximized()# self.btn_stop.setText('縮小窗口')# 重寫 closeEvent 函數(shù),關(guān)閉窗口并停止程序運(yùn)行def closeEvent(self, event):sys.exit()# 最小化窗口def minimize(self):self.showMinimized()# 鼠標(biāo)左鍵釋放時(shí)被觸發(fā)def mouseReleaseEvent(self, event):self.start_x = Noneself.start_y = None# 在鼠標(biāo)左鍵按下時(shí)被觸發(fā)def mousePressEvent(self, event):if event.button() == QtCore.Qt.LeftButton:super(MyMainForm, self).mousePressEvent(event)self.start_x = event.x()self.start_y = event.y()# 在鼠標(biāo)移動(dòng)時(shí)被觸發(fā)def mouseMoveEvent(self, event):try:super(MyMainForm, self).mouseMoveEvent(event)dis_x = event.x() - self.start_xdis_y = event.y() - self.start_yself.move(self.x() + dis_x, self.y() + dis_y)except:pass# 窗口設(shè)置陰影效果def effect_shadow_style(self, widget):effect_shadow = QtWidgets.QGraphicsDropShadowEffect(self)effect_shadow.setOffset(12, 12) # 偏移effect_shadow.setBlurRadius(128) # 陰影半徑effect_shadow.setColor(QColor(155, 230, 237, 150)) # 陰影顏色widget.setGraphicsEffect(effect_shadow)# 背景漸變# def paintEvent(self, event):# painter = QPainter(self)# gradient = QLinearGradient(0, 0, self.width(), self.height())# gradient.setColorAt(0, QColor(89, 217, 212, 128))# gradient.setColorAt(1, QColor(104, 202, 237, 128))# gradient.setStart(0, 0)# gradient.setFinalStop(self.width(), self.height())# painter.setBrush(gradient)# painter.drawRect(self.rect())if __name__ == "__main__":app = QApplication(sys.argv)myWin = MyMainForm()myWin.show()# myWin.btn_img.clicked.connect(click())sys.exit(app.exec_())學(xué)習(xí)視頻
【已完結(jié)】PySide6百煉成真,帶你系統(tǒng)性入門Qt_嗶哩嗶哩_bilibili【已完結(jié)】PySide6百煉成真,帶你系統(tǒng)性入門Qt共計(jì)75條視頻,包括:000 新的課程介紹、002環(huán)境搭建、003基礎(chǔ)框架等,UP主更多精彩視頻,請(qǐng)關(guān)注UP賬號(hào)。https://www.bilibili.com/video/BV1c84y1N7iL計(jì)算器這個(gè)案例就是跟著這個(gè)視頻里做的!打call!很贊的教程!
總結(jié)
以上是生活随笔為你收集整理的Python——pyqt5的计算器(源码+打包)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 键盘种类
- 下一篇: Python手绘图案出现MemoryEr