PySide2动态/静态加载UI及程序发布
Python 现在是一个“家喻户晓”的术语。它可能用于许多行业,包括最强大的人工智能(AI)和大数据。今天我们将介绍Python图形界面(GUI)的实现。请记住,当 Python 刚问世时,开发强大而美观的 GUI 非常不方便。在早期,Python 自己的 GUI 模块库被称为 Tkinter。当然,这个模块的功能和功能比以前丰富了很多。另外还有wxpthon、pyGtk、Jython、Pywin
Python 现在是一个“家喻户晓”的术语。它可能用于许多行业,包括最强大的人工智能(AI)和大数据。今天我们将介绍Python图形界面(GUI)的实现。请记住,当 Python 刚问世时,开发强大而美观的 GUI 非常不方便。在早期,Python 自己的 GUI 模块库被称为 Tkinter。当然,这个模块的功能和功能比以前丰富了很多。另外还有wxpthon、pyGtk、Jython、Pywin32、PyQt PySide\PySide2等。在这么多图形开发工具中,我比较喜欢PySide2。下面重点介绍如何将开发的程序打包成可执行文件并发布,可以在别人的电脑上使用(仅限Windows电脑)。
PySide2简介
PySide2实际上是Qt的python版本,官方称为“Qt for Python”。这样一来,你应该明白,其实是Qt的各种图形库和功能模块库调用Python开发,在Python中导入一个模块。相信大家都知道“import”,所以PySide2的使用就这么简单。我们需要学习的是《Qt for Python》相关的API函数接口的使用。按照模块分为很多API,如图形控制API、网络通讯API、串口API、Web相关API等,需要什么API就看这些API即可。这很容易!
另外,我们解释一下PySide2是Qt的儿子。比如kotlin语言就是google为Android APP开发准备的语言(起初Android APP开发只能用java语言开发)。现在我们发现很多安卓应用都是用kotlin开发的,功能支持也越来越好。毕竟是自己的,所以PySide2也是如此。收养人是谁?我上面提到的 PyQt 是一家专门为 Qt 开发 Python 相关 API 的公司。当然,它比 PySide2 诞生得更早。
在版本问题上,PySide2是基于Qt5开发的,而她面前还有一个PySide,是早期版本。它也是基于Qt4的最早版本。现在几乎没有人使用它,因为功能并不完善。最新的是 PySide6。是不是感觉从2跳到6有点快?它可能会跟随老子的步伐。 QT现在已经发展到6.0版本,所以直接是PySide6。不过由于6.0版本的很多API都没有完全支持,所以本文介绍PySide2。几乎和Qt5同步,她几乎可以实现Qt5的一些功能。
(PyQt -> PyQt5 -> PyQt6 这是采用版本的开发图)
打包神器 Pyinstaller
打包python的工具有很多,除了这个,py2exe和Cx_free也是一个不错的工具。
1.安装 Pyinstaller 打包工具
微软视窗[版本 10.0.19041.867]
(c) 2020 微软公司。版权所有。
C:\Users\Gary>pip install -i https://pypi.douban.com/simple pyinstaller
看索引:https://pypi.douban.com/simple
收集pyinstaller
下载 https://pypi.doubanio.com/packages/b4/83/9f6ff034650abe9778c9a4f86bcead63f89a62acf02b1b47fc2bfc6bf8dd/pyinstaller-4.2.tar.gz (3.6 MB)
|█████████████████████████████████| 3.6 MB 46 KB/秒
安装构建依赖项...完成
获得制造轮子的要求...完成
准备车轮元数据...完成
收集 altgraph
下载 https://pypi.doubanio.com/packages/ee/3d/bfca21174b162f6ce674953f1b7a640c1498357fa6184776029557c25399/altgraph-0.17-py2.py3-none-any.whl (21 kB)
收集pyinstaller-hooks-contrib>u003d2020.6
下载 https://pypi.doubanio.com/packages/27/c7/58a634d861e4744ac62dca4a4992ace8def8b05dab91e6b25e5043e79acf/pyinstaller_hooks_contrib-2021.1-py2.py3-none-any.whl (181 kB)
|█████████████████████████████████| 181 KB ...
已满足要求:d:\users\python\python39\lib\site-packages 中的 setuptools(来自 pyinstaller)(49.2.1)
采集pefile>u003d2017.8.1; sys_platform u003du003d "win32"
下载 https://pypi.doubanio.com/packages/36/58/acf7f35859d541985f0a6ea3c34baaefbfaee23642cf11e85fe36453ae77/pefile-2019.4.18.tar.gz (62 kB)
|█████████████████████████████████| 62 KB 408 KB/秒
采集pywin32-ctypes>u003d0.2.0; sys_platform u003du003d "win32"
下载 https://pypi.doubanio.com/packages/9e/4b/3ab2720f1fa4b4bc924ef1932b842edf10007e4547ea8157b0b9fc78599a/pywin32_ctypes-0.2.0-py2.py3-none-any.whl (28 kB)
收集未来
下载 https://pypi.doubanio.com/packages/45/0b/38b06fd9b92dc2b68d58b75f900e97884c45bedd2ff83203d933cf5851c9/future-0.18.2.tar.gz (829 kB)
|█████████████████████████████████| 829 KB 819 KB/秒
对 pefile 使用旧版“setup.py install”,因为未安装“wheel”包。
将来使用旧版“setup.py install”,因为未安装“wheel”包。
为收集的包构建轮子:pyinstaller
pyinstaller (PEP 517) 的构建轮 ... 完成
为 pyinstaller 创建轮子:filenameu003dpyinstaller-4.2-py3-none-any.whl sizeu003d2413076 sha256u003dfa9cdc6ec88e2d0c3df74e7aec0f71330feb1b2b6fb751f188bb498631837d06
存储在目录:c:\users\gary\appdata\local\pip\cache\wheels\af\ea\26\5812f58861dc385ff5573249b18dfe1624c5f84ea67fa76397
成功搭建pyinstaller
安装收集的包:altgraph、pyinstaller-hooks-contrib、future、pefile、pywin32-ctypes、pyinstaller
为将来运行 setup.py install ...完成
为 pefile 运行 setup.py install ... 完成
成功安装altgraph-0.17 future-0.18.2 pefile-2019.4.18 pyinstaller-4.2 pyinstaller-hooks-contrib-2021.1 pywin32-ctypes-0.2.0
警告:您使用的是 pip 版本 20.2.3;但是,版本 21.0.1 可用。
您应该考虑通过 'd:\users\python\python39\python.exe -m pip install --upgrade pip' 命令进行升级。
C:\用户\加里>
可以查看Python第三方包的目录,多找到两个:(Pywin32会同时安装)
2. pyinstaller常用指令参数
以下是一些常用参数:
D:\py\MFGTool>pyinstaller --help
用法:pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME] [--add-data <SRC;DEST 或 SRC:DEST>]
[--add-binary <SRC;DEST 或 SRC:DEST>] [-p DIR] [--hidden-import MODULENAME]
[--additional-hooks-dir HOOKSPATH] [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]
[--key KEY] [-d {all,imports,bootloader,noarchive}] [-s] [--noupx] [--upx-排除文件] [- c] [-w]
[-i <FILE.ico or FILE.exe,ID or FILE.icns or "NONE">] [--version-file FILE] [-m <FILE or XML>]
[-r 资源] [--uac-admin] [--uac-uiaccess] [--win-private-assemblies] [--win-no-prefer-redirects]
[--osx-bundle-identifier BUNDLE_IDENTIFIER] [--runtime-tmpdir PATH] [--bootloader-ignore-signals]
[--distpath DIR] [--workpath WORKPATH] [-y] [--upx-dir UPX_DIR] [-a] [--clean] [ --日志级别级别]
脚本名[脚本名...]
位置参数:
scriptname 要处理的脚本文件的名称或恰好是一个 .spec 文件。如果指定了 .spec 文件,
大多数选项都是不必要的并且被忽略。
可选参数:
-h, --help 显示此帮助信息并退出
-v, --version 显示程序版本信息并退出。
--distpath DIR 捆绑应用程序的放置位置(默认:.\dist)指定保存打包文件的位置。默认是 dist 这个目录
--workpath WORKPATH 放置所有临时工作文件的位置,.log、.pyz 等(默认:.\build)
-y, --noconfirm 替换输出目录(默认:SPECPATH\dist\SPECNAME)而不要求确认
--upx-dir UPX_DIR UPX 实用程序的路径(默认:搜索执行路径)
-a, --ascii 不包括 unicode 编码支持(默认:如果可用,包括)
--clean 清理PyInstaller缓存,并在构建前移除临时文件。打包成功后,打包过程中产生的文件会被清理干净
-D, --onedir 创建一个包含可执行文件的单文件夹捆绑包(默认) 这是默认设置。所有与可执行文件相关的文件都将复制到目录 dist 中
-F, --onefile 创建单文件捆绑的可执行文件。这样只会生成一个exe文件,文件会很大
--hidden-import 模块名,--hiddenimport 模块名
命名在脚本代码中不可见的导入。此选项可多次使用
次。隐藏一些模块。这些模块通常不在实际程序中,而是编译器或打包器所需的模块。如果不隐藏,则打包失败,说缺少一个模块
-p DIR, --paths DIR 搜索导入的路径(如使用 PYTHONPATH)。允许多条路径,由
';',或多次使用此选项
指定要包含的库的路径。如果没有要指定的库,则不需要该参数
-c,--控制台,--nowindowed
打开标准 i/o 的控制台窗口(默认)。在 Windows 上,此选项无效
如果第一个脚本是“.pyw”文件。
-w,--windowed,--noconsole
Windows 和 Mac OS X:不为标准 i/o 提供控制台窗口。在 Mac OS X 上,这也是
触发构建 OS X .app 包。在 Windows 上,如果第一个脚本将设置此选项
是一个“.pyw”文件。此选项在 *NIX 系统中被忽略。
上面的 -c 或 -w 是指打包后是否显示控制台,类似 dos 这样的界面
打包应用
GUI界面是动态加载的:
导入我们
导入系统
从 PySide2.QtWidgets 导入 QApplication、QMainWindow、QMessageBox
从 PySide2.QtCore 导入 QFile、QRegExp、QByteArray、QIODevice
从 PySide2.QtUiTools 导入 QUiLoader
从 PySide2.QtGui 导入 QRegExpValidator
从 PySide2 导入 QtSerialPort
#从 ui_mfgtool 导入 Ui_MfgTool
类 MfgTool(QMainWindow):
定义__init__(自我):
super(MfgTool, self).__init__()
self.load_ui()
#self.ui u003d Ui_MfgTool() #静态加载UI
#self.ui.setupUi(自我)
self.initUI()
self.ConnectFun()
self.m_ba u003d QByteArray(b"")
def 加载_ui(自我):
loader u003d QUiLoader() #动态加载UI
路径 u003d os.path.join(os.path.dirname(__file__), "mfgtool.ui")
ui_file u003d QFile(路径)
ui_file.open(QFile.ReadOnly)
self.ui u003d loader.load(ui_file, self)
ui_file.close()
self.ui.show()
包装说明如下:
D:\py\MFGTool>pyinstaller mfgtool.py
171 信息:PyInstaller:4.2
171 信息:Python:3.9.2
171 信息:平台:Windows-10-10.0.19041-SP0
171 信息:写 D:\py\MFGTool\mfgtool.spec
171 信息:UPX 不可用。
188 信息:使用路径扩展 PYTHONPATH
['D:\\py\\MFGTool', 'D:\\py\\MFGTool']
202 INFO:检查分析
327 信息:由于 hiddenimports 更改而构建
327 信息:正在初始化模块依赖图...
327 信息:缓存模块图挂钩...
344 警告:为模块“win32ctypes.core”定义了几个挂钩。请注意它们不要冲突。
359 信息:分析 base_library.zip ...
4468 信息:处理来自 'd:\\users\\python\\python39\\lib\\site-packages\\PyInstaller\ 的预查找模块路径挂钩 distutils \hooks\\pre_find_module_path\\hook-distutils.py'。
4468 信息:distutils:重定向到非 venv 目录 'd:\\users\\python\\python39\\lib'
.........
23921 信息:引导加载程序 d:\users\python\python39\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe
23921 信息:检查 EXE
23953 信息:由于图标更改而构建
23953 信息:从 EXE-00.toc 构建 EXE
23953 信息:从 ['d:\\users\\python\\python39\\lib\\site-packages\\PyInstaller\\bootloader\ 复制图标\\images\\icon-console.ico']
24140 信息:使用 104 字节写入 RT_GROUP_ICON 0 资源
24140 信息:使用 3752 字节写入 RT_ICON 1 资源
24140 信息:使用 2216 字节写入 RT_ICON 2 资源
24140 信息:使用 1384 字节写入 RT_ICON 3 资源
24140 信息:使用 37019 字节写入 RT_ICON 4 资源
24140 信息:使用 9640 字节写入 RT_ICON 5 资源
24140 信息:使用 4264 字节写入 RT_ICON 6 资源
24140 信息:使用 1128 字节写入 RT_ICON 7 资源
24156 信息:将存档附加到 EXE D:\py\MFGTool\build\mfgtool\mfgtool.exe
24327 信息:从 EXE-00.toc 构建 EXE 已成功完成。
24327 信息:检查收集
警告:输出目录“D:\py\MFGTool\dist\mfgtool”及其所有内容将被删除!继续? (是/否)是
风险自负,您可以使用选项 `--noconfirm`来摆脱这个问题。
36014 信息:删除目录 D:\py\MFGTool\dist\mfgtool
36093 信息:建筑 COLLECT COLLECT-00.toc
37921 信息:构建 COLLECT COLLECT-00.toc 已成功完成。
D:\py\MFGTool>
直接进入dist\mfgtool\目录运行打包好的mfgtool exe,会弹出一个框报错:
以上都是带控制台的默认参数(运行时类似DOS的界面)。
直接从命令行运行:
D:\py\MFGTool\dist\mfgtool>mfgtool.exe
Traceback(最近一次通话最后一次):
文件“mfgtool.py”,第 8 行,在 <module> 中
文件“C:\Users\Gary\AppData\Local\Temp\embedded.r2luoun3.zip\shibokensupport\__feature__.py”,第 142 行,在 _import
ImportError:无法导入模块“PySide2.QtXml”
[544] 执行脚本 mfgtool 失败
D:\py\MFGTool\dist\mfgtool>
操作提示缺少'pyside2 Qtxml',这个库在我们实际的代码开发中并没有用到,但是在打包的时候需要用到,所以我们需要用上面提到的参数“--hidden import”来隐藏它。另外,包装的时候为什么要带控制台呢?这样方便查找问题。如果没有控制台直接运行,就看不到真正的错误在哪里。
现在用这个参数再试一次:
D:\py\MFGTool>pyinstaller mfgtool.py --hidden-import PySide2.QtXml
D:\py\MFGTool\dist\mfgtool>mfgtool.exe
QIODevice::read (QFile, "mfgtool.ui"): 设备未打开
设计器:读取第 1 行第 0 列的 UI 文件时发生错误:文档过早结束。
Traceback(最近一次通话最后一次):
<module> 中的文件“mfgtool.py”,第 245 行
文件“mfgtool.py”,第 17 行,位于 __init__
文件“mfgtool.py”,第 29 行,在 load_ui 中
RuntimeError: 无法打开/读取 ui 设备
[440] 执行脚本 mfgtool 失败
D:\py\MFGTool\dist\mfgtool>
运行后又报新的错误,“RuntimeError: Unable to open/read ui device”,因为我们的程序加载界面是动态的,需要将界面对应的ui文件复制到exe程序所在的位置。我们的程序是一个串口通信演示程序,对应的ui接口文件叫mfgtool ui,所以把这个文件复制到mfgtool exe(打包后的可执行文件),默认在dist\mfgtool\下。
复制好后直接双击exe文件就可以看到UI界面了。这时候你会在后面看到一个黑色的dos界面。去掉的方法是加个参数“-w”重新打包,然后再次运行,就不会看到后面的控制台窗口了,如下:
D:\py\MFGTool>pyinstaller mfgtool.py --hidden-import PySide2.QtXml -w
动态加载UI操作后的程序界面如下:
实际上,程序界面的一部分并没有完全显示出来。以下是程序初始化的部分代码。从代码中我们可以看出我们已经设置了程序的主题标题,但是这里的主题名称是“Mfgtool”(默认主题名称)。
定义 initUI(自我):
桌面 u003d QApplication.desktop()
self.screenWidth u003d desktop.width() * 0.4
self.screenHeight u003d desktop.height() * 0.6
print("屏幕宽度:",self.screenWidth,"高度:",self.screenHeight)
self.setGeometry(0, 0, self.screenWidth, self.screenHeight)
self.setWindowTitle("MfgTool V1.0.0") #正确答案应该是self ui。 setWindowTitle("MfgTool V1.0.0")
上面的问题其实是动态加载UI的不足。这可能是 PySide2 设计中的一个问题,以后可能会改进。下面是这个问题的场景:
1、UI加载过程放在自定义类中
2.在main函数中创建上述类的实例
3、代码程序如下:
类 MfgTool(QMainWindow):
定义__init__(自我):
super(MfgTool, self).__init__()
self.load_ui()
def 加载_ui(自我):
装载机 u003d QUiLoader()
路径 u003d os.path.join(os.path.dirname(__file__), "mfgtool.ui")
ui_file u003d QFile(路径)
ui_file.open(QFile.ReadOnly)
self.ui u003d loader.load(ui_file, self)
ui_file.close()
self.ui.show()
如果 __name__ u003du003d "__main__":
应用程序 u003d QApplication(sys.argv)
mainUI u003d MfgTool()
sys.exit(app.exec_())
上面动态加载UI场景的问题:
1.self是我们自定义的类,不是ui,所以上面的主题设置无效
- 1问题不大。最致命的问题是我们的主窗口QMainWindow和我们的ui是相互独立的,也就是在主窗口QMainWindow中不会加载ui。所以上面代码运行后的界面如上图所示,但是细心的人可能会发现我的win10(我的开发主机是win10)任务栏中没有程序图标。为什么不?因为图标是主程序,上面代码的主程序QMainWindow根本没有显示出来。让我们在下面显示它,您需要在 Main 中添加一行:
mainUI.show()
或者,直接在 load_UI 函数末尾加一行,效果是一样的:
self.show()
怎么会有两个显示界面?确实,有两个。空的一个是QMainWindow的主程序,win10任务栏也有一个主程序图标(默认是python图标)。这个显示结果也解释了上面2中的问题。主程序和我们的UI是两个独立的界面。
1、另外,上面的问题2也会带来一系列的问题,比如不会触发QMainWindow的事件等等。当然,要接收窗口事件,需要重写相应的事件接口,而且重写效果不是最好的,这里就不详细解释了。其他人也遇到了同样的问题。这是一个外国人写的帖子。问题与我上面遇到的大致相同。
https://translate.google.com/translate?hl=en&sl=auto&tl=zh&u=https://stackoverflow.com/questions/53828666/pyside2-qmainwindow-loaded-from-ui-file-not-triggering-window-events
概括:
1.看到这里,不知道是不是对PySide2开发python GUI有点失望。不用担心。这只是 PySide2 的一个设计。如果你研究PyQt5,你会发现它没有这个问题。它将ui视为主界面QMainWindow的一部分,即类中的父子关系。
另外,按照Qt官方的做法,加载ui的动作是直接放在main中的,所以不会出现以上问题。以下是直接复制的示例:
# 文件:main.py
导入系统
从 PySide2.QtUiTools 导入 QUiLoader
从 PySide2.QtWidgets 导入 QApplication
从 PySide2.QtCore 导入 QFile、QIODevice
如果 __name__ u003du003d "__main__":
应用程序 u003d QApplication(sys.argv)
ui_file_name u003d "主窗口.ui"
ui\file u003d QFile(ui\file\name)
如果不是 ui_file.open(QIODevice.ReadOnly):
print("无法打开 {}: {}".format(ui_file_name, ui_file.errorString()))
系统退出(-1)
装载机 u003d QUiLoader()
窗口 u003d loader.load(ui\file)
ui_file.close()
如果不是窗口:
打印(loader.errorString())
系统退出(-1)
窗口.show()
sys.exit(app.exec_())
1、最好的UI调用方式是静态加载,这样就可以覆盖事件,这和直接使用Qt IDE开发工具很相似。
GUI界面是静态加载的:
首先,PySide2提供了将ui转换为py文件的工具:
pyzde2-uric machitool.ui > ui_machitool.py
如果你熟悉 Qt 开发,转换后的 py 文件与 Qt Creator 转换后的 UI 界面文件非常相似。是的,事实上,它们的原理是相似的。他们都将UI内容构建成一个类,然后直接调用这个类。以下是部分转换后的代码:
## 创建者:Qt 用户界面编译器版本 5.15.2
警告!重新编译 UI 文件时,对该文件所做的所有更改都将丢失!
################################################# ###############################
从 PySide2.QtCore 导入 *
从 PySide2.QtGui 导入 *
从 PySide2.QtWidgets 导入 *
类 Ui_MfgTool(对象):
def setupUi (self, MfgTool):
如果不是 MfgTool.objectName():
MfgTool.setObjectName(u"MfgTool")
MfgTool.resize(800, 600)
MfgTool.setStyleSheet(u"QLabel{\n"
“字体:20px;\n”
"}\n"
"QPushButton{\n"
“字体:25px;\n”
"}\n"
"QComboBox,QLineEdit{\n"
“字体:18px;\n”
"}")
self.centralwidget u003d QWidget(MfgTool)
self.centralwidget.setObjectName(u"centralwidget")
self.label_port u003d QLabel(self.centralwidget)
self.label_port.setObjectName(u"label_port")
self.label_port.setGeometry(QRect(139, 30, 141, 31))
self.label_port.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
......
MfgTool.setStatusBar(self.statusbar)
self.retranslateUi(MfgTool)
QMetaObject.connectSlotsByName(MfgTool)
设置界面
def retranslateUi (self, MfgTool):
MfgTool.setWindowTitle(QCoreApplication.translate("MfgTool", u"MfgTool", None))
self.label_port.setText(QCoreApplication.translate("MfgTool", u"串口:", None))
self.pushButton_refresh.setText(QCoreApplication.translate("MfgTool", u"Refresh", None))
self.pushButton_open.setText(QCoreApplication.translate("MfgTool", u"Open", None))
self.pushButton_read.setText(QCoreApplication.translate("MfgTool", u"Read", None))
self.pushButton_write.setText(QCoreApplication.translate("MfgTool", u"Write", None))
self.label_type.setText(QCoreApplication.translate("MfgTool", u"设备类型:", 无))
self.label_sn.setText(QCoreApplication.translate("MfgTool", u"Device S/N:", None))
self.label_mfgsn.setText(QCoreApplication.translate("MfgTool", u"MFG S/N:", None))
self.label_pdate.setText(QCoreApplication.translate("MfgTool", u"PDate:", None))
self.label_hwver.setText(QCoreApplication.translate("MfgTool", u"HW Version:", None))
重新翻译Ui
我们来看看主程序:
从 ui_mfgtool 导入 Ui_MfgTool
类 MfgTool(QMainWindow):
定义__init__(自我):
super(MfgTool, self).__init__()
self.load_ui()
self.ui u003d Ui_MfgTool()
self.ui.setupUi(自我)
self.initUI()
self.ConnectFun()
........
如果 __name__ u003du003d "__main__":
应用程序 u003d QApplication(sys.argv)
mainUI u003d MfgTool()
mainUI.show()
sys.exit(app.exec_())
这样,我们先在命令行模式下运行,界面如下:
从上图可以看出,程序的主题标题也正常显示,win10任务栏也有主程序图标,没有两个界面(QMainWindow和ui)。这就是静态加载的优点。和Qt Creator下开发的效果一样。这十分完美!
最后我们来演示一下,主程序窗口和Ui已经完美对接了,完全就是父子类的关系。
定义 initUI(自我):
桌面 u003d QApplication.desktop()
self.screenWidth u003d desktop.width() * 0.4
self.screenHeight u003d desktop.height() * 0.6
print("屏幕宽度:",self.screenWidth,"高度:",self.screenHeight)
self.setGeometry(0, 0, self.screenWidth, self.screenHeight)
self.ui.setWindowTitle("MfgTool V1.0.0")#静态加载应该写成self setWindowTitle("MfgTool V1.0.0")
如果将上面代码中的title设置为动态加载模式,会遇到如下错误:
D:\py\MFGTool>python mfgtool.py
Traceback(最近一次通话最后一次):
文件“D:\py\MFGTool\mfgtool.py”,第 245 行,在 <module>
mainUI u003d MfgTool()
文件“D:\py\MFGTool\mfgtool.py”,第 20 行,位于 __init__
self.initUI()
文件“D:\py\MFGTool\mfgtool.py”,第 39 行,在 initUI
self.ui.setWindowTitle("MfgTool V1.0.0")
AttributeError: 'Ui_MfgTool' 对象没有属性 'setWindowTitle'
现在我已经完成了静态加载 UI 的介绍。打包成exe,方法同动态打包的说明。它不重复。这意味着您不必将 UI 文件复制到打包文件夹中。
另外,如果只想打包成exe可执行文件,没有其他关联的库和其他文件,可以使用“-F”参数,只会打包成exe文件,但是exe文件有点大。
更多推荐
所有评论(0)