每次写好的PY程序要打包发给客户时,需要使用pyinstaller命令行打包,稍显麻烦,尝试用pyqt写了一个GUI桌面程序打包,简洁直观。
UI代码(Ui_Mypy2exe.py):
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Mypy2exe(object): def setupUi(self, Mypy2exe): Mypy2exe.setObjectName("Mypy2exe") Mypy2exe.resize(418, 418) Mypy2exe.setMaximumSize(QtCore.QSize(418, 418)) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("e:\\Mypython\\Mypy2exe\\python.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off) Mypy2exe.setWindowIcon(icon) self.centralwidget = QtWidgets.QWidget(Mypy2exe) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setObjectName("verticalLayout") self.label = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) self.label.setSizePolicy(sizePolicy) self.label.setMaximumSize(QtCore.QSize(400, 80)) self.label.setText("") self.label.setPixmap(QtGui.QPixmap("e:\\Mypython\\Mypy2exe\\timgMM55UVQF.jpg")) self.label.setScaledContents(True) self.label.setObjectName("label") self.verticalLayout.addWidget(self.label) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setMinimumSize(QtCore.QSize(65, 0)) self.label_2.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_2.setFont(font) self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_2.setObjectName("label_2") self.horizontalLayout.addWidget(self.label_2) self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit.setReadOnly(True) self.lineEdit.setObjectName("lineEdit") self.horizontalLayout.addWidget(self.lineEdit) self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label_3 = QtWidgets.QLabel(self.centralwidget) self.label_3.setMinimumSize(QtCore.QSize(65, 0)) self.label_3.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_3.setFont(font) self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_3.setObjectName("label_3") self.horizontalLayout_2.addWidget(self.label_3) self.radioButton = QtWidgets.QRadioButton(self.centralwidget) self.radioButton.setChecked(True) self.radioButton.setObjectName("radioButton") self.horizontalLayout_2.addWidget(self.radioButton) self.radioButton_2 = QtWidgets.QRadioButton(self.centralwidget) self.radioButton_2.setObjectName("radioButton_2") self.horizontalLayout_2.addWidget(self.radioButton_2) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout_6 = QtWidgets.QHBoxLayout() self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.label_4 = QtWidgets.QLabel(self.centralwidget) self.label_4.setMinimumSize(QtCore.QSize(65, 0)) self.label_4.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_4.setFont(font) self.label_4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_4.setObjectName("label_4") self.horizontalLayout_6.addWidget(self.label_4) self.radioButton_3 = QtWidgets.QRadioButton(self.centralwidget) self.radioButton_3.setChecked(True) self.radioButton_3.setObjectName("radioButton_3") self.horizontalLayout_6.addWidget(self.radioButton_3) self.radioButton_4 = QtWidgets.QRadioButton(self.centralwidget) self.radioButton_4.setObjectName("radioButton_4") self.horizontalLayout_6.addWidget(self.radioButton_4) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_6.addItem(spacerItem1) self.verticalLayout.addLayout(self.horizontalLayout_6) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.label_7 = QtWidgets.QLabel(self.centralwidget) self.label_7.setMinimumSize(QtCore.QSize(65, 0)) self.label_7.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_7.setFont(font) self.label_7.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_7.setObjectName("label_7") self.horizontalLayout_3.addWidget(self.label_7) self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_2.setReadOnly(True) self.lineEdit_2.setObjectName("lineEdit_2") self.horizontalLayout_3.addWidget(self.lineEdit_2) self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_2.setObjectName("pushButton_2") self.horizontalLayout_3.addWidget(self.pushButton_2) self.verticalLayout.addLayout(self.horizontalLayout_3) self.horizontalLayout_5 = QtWidgets.QHBoxLayout() self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.label_9 = QtWidgets.QLabel(self.centralwidget) self.label_9.setMinimumSize(QtCore.QSize(65, 0)) self.label_9.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_9.setFont(font) self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_9.setObjectName("label_9") self.horizontalLayout_5.addWidget(self.label_9) self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_4.setReadOnly(True) self.lineEdit_4.setObjectName("lineEdit_4") self.horizontalLayout_5.addWidget(self.lineEdit_4) self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_4.setObjectName("pushButton_4") self.horizontalLayout_5.addWidget(self.pushButton_4) self.verticalLayout.addLayout(self.horizontalLayout_5) self.horizontalLayout_7 = QtWidgets.QHBoxLayout() self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.label_10 = QtWidgets.QLabel(self.centralwidget) self.label_10.setMinimumSize(QtCore.QSize(65, 0)) self.label_10.setMaximumSize(QtCore.QSize(65, 16777215)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_10.setFont(font) self.label_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.label_10.setObjectName("label_10") self.horizontalLayout_7.addWidget(self.label_10) self.lineEdit_5 = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_5.setReadOnly(True) self.lineEdit_5.setObjectName("lineEdit_5") self.horizontalLayout_7.addWidget(self.lineEdit_5) self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget) self.pushButton_6.setObjectName("pushButton_6") self.horizontalLayout_7.addWidget(self.pushButton_6) self.verticalLayout.addLayout(self.horizontalLayout_7) self.label_6 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(11) self.label_6.setFont(font) self.label_6.setAlignment(QtCore.Qt.AlignCenter) self.label_6.setObjectName("label_6") self.verticalLayout.addWidget(self.label_6) self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget) self.textBrowser.setObjectName("textBrowser") self.verticalLayout.addWidget(self.textBrowser) self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget) font = QtGui.QFont() font.setPointSize(11) self.pushButton_5.setFont(font) self.pushButton_5.setObjectName("pushButton_5") self.verticalLayout.addWidget(self.pushButton_5) Mypy2exe.setCentralWidget(self.centralwidget)
self.retranslateUi(Mypy2exe) self.pushButton.clicked.connect(Mypy2exe.open_py) self.pushButton_2.clicked.connect(Mypy2exe.open_ico) self.pushButton_4.clicked.connect(Mypy2exe.open_dir) self.pushButton_5.clicked.connect(Mypy2exe.start_py) self.radioButton.toggled['bool'].connect(Mypy2exe.ischeck) self.radioButton_2.toggled['bool'].connect(Mypy2exe.ischeck) self.radioButton_3.toggled['bool'].connect(Mypy2exe.ischeck) self.radioButton_4.toggled['bool'].connect(Mypy2exe.ischeck) self.lineEdit.textChanged['QString'].connect(Mypy2exe.ischeck) self.lineEdit_2.textChanged['QString'].connect(Mypy2exe.ischeck) self.lineEdit_4.textChanged['QString'].connect(Mypy2exe.ischeck) self.pushButton_6.clicked.connect(Mypy2exe.open_evn) QtCore.QMetaObject.connectSlotsByName(Mypy2exe)
def retranslateUi(self, Mypy2exe): _translate = QtCore.QCoreApplication.translate Mypy2exe.setWindowTitle(_translate("Mypy2exe", "PY打包器")) self.label_2.setText(_translate("Mypy2exe", "PY文件:")) self.pushButton.setText(_translate("Mypy2exe", "选择")) self.label_3.setText(_translate("Mypy2exe", "打包成:")) self.radioButton.setText(_translate("Mypy2exe", "单个exe文件")) self.radioButton_2.setText(_translate("Mypy2exe", "文件夹")) self.label_4.setText(_translate("Mypy2exe", "控制台:")) self.radioButton_3.setText(_translate("Mypy2exe", "关闭")) self.radioButton_4.setText(_translate("Mypy2exe", "开启")) self.label_7.setText(_translate("Mypy2exe", "图 标:")) self.pushButton_2.setText(_translate("Mypy2exe", "选择")) self.label_9.setText(_translate("Mypy2exe", "保 存:")) self.pushButton_4.setText(_translate("Mypy2exe", "选择")) self.label_10.setText(_translate("Mypy2exe", "环 境:")) self.pushButton_6.setText(_translate("Mypy2exe", "选择")) self.label_6.setText(_translate("Mypy2exe", "命令预览")) self.textBrowser.setHtml(_translate("Mypy2exe", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n""<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n""p, li { white-space: pre-wrap; }\n""</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n""<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-F 打包成单个可执行文件</p>\n""<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-D 打包成文件夹<br />-w 关闭控制台窗口</p>\n""<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">-c 使用控制台窗口<br />-p 环境变量<br />-i 可执行文件的图标</p>\n""<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">--distpath 保存路径</p></body></html>")) self.pushButton_5.setText(_translate("Mypy2exe", "开始打包"))
主程序(Mypy2exe.py)
import os,sysimport qdarkstylefrom Ui_Mypy2exe import Ui_Mypy2exe
from PyQt5 import QtCore,QtWidgets,QtGuifrom PyQt5.QtWidgets import QMessageBox,QDesktopWidget,QFileDialog,QApplication,QMainWindow
class mwindow(QMainWindow, Ui_Mypy2exe): def __init__(self): super(mwindow, self).__init__() self.setupUi(self) self.command = ["pyinstaller ",'','','','','',''] self.center() self.buttonGroup1=QtWidgets.QButtonGroup(self) self.buttonGroup2=QtWidgets.QButtonGroup(self) self.buttonGroup1.addButton(self.radioButton) self.buttonGroup1.addButton(self.radioButton_2) self.buttonGroup2.addButton(self.radioButton_3) self.buttonGroup2.addButton(self.radioButton_4) self.radioButton.setChecked(True) self.radioButton_3.setChecked(True)
def center(self): #页面居中显示 screen=QDesktopWidget().screenGeometry() #获取屏幕的大小 size=self.geometry() #获取窗口的大小 self.move((screen.width() - size.width()) /2,(screen.height() - size.height()) /2) #屏幕中央
def open_py(self): f, filetype = QFileDialog.getOpenFileName(self, "选择要打包的py文件", "", "py格式(*.py)") if f: self.lineEdit.setText(f) self.command[4] = f self.ischeck()
def open_ico(self): f, filetype = QFileDialog.getOpenFileName(self, "选择图标文件", "", "ico格式(*.ico)") if f: self.lineEdit_2.setText(f) self.command[3] = " -i {} ".format(f) self.ischeck()
def open_dir(self): directory1 = QFileDialog.getExistingDirectory(self, "选择文件夹", "/") if directory1: self.lineEdit_4.setText(directory1) self.command[5] = " --distpath {}".format(directory1) self.ischeck() def open_evn(self): directory2 = QFileDialog.getExistingDirectory(self, "选择文件夹", "/") if directory2: self.lineEdit_5.setText(directory2) self.command[6] = " -p {}".format(directory2) self.ischeck()
def ischeck(self): self.command[1] = " -F " if self.radioButton.isChecked() else " -D " self.command[2] = " -w " if self.radioButton_3.isChecked() else " -c " self.textBrowser.clear() text = "".join(self.command) self.textBrowser.append(text)
def start_py(self): if self.command[4] !="": text = "".join(self.command) os.system(text) else: QMessageBox.warning(self,"文件错误","还没有选择一个PY文件!") self.open_py()
if __name__ == "__main__": QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) #让程序支持高分辨率显示 app = QApplication(sys.argv) app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) w = mwindow() w.show() sys.exit(app.exec_())
运行界面
结果: