PySide2 中 Pyinstaller 和 loadUiType 的问题
Problem with Pyinstaller and loadUiType in PySide2
我想将我的 PySide2 应用程序转换为 exe 文件。使用 PySide2.QtUiTools 中的 loadUiType 函数加载 ui 文件很重要。最小可重现示例包含:
Python 文件:
import os
from PySide2 import QtWidgets
from PySide2.QtUiTools import loadUiType
from PySide2 import QtXml
current_dir = os.environ.get(
"_MEIPASS2",
os.path.abspath(".")
)
Form, Base = loadUiType(os.path.join(current_dir, "ui\main.ui"))
class MainWidget(Base, Form):
def __init__(self, parent=None):
super(self.__class__, self).__init__(parent)
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
main_widget_object = MainWidget()
main_widget_object.show()
sys.exit(app.exec_())
Ui 文件:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QPushButton" name="button">
<property name="geometry">
<rect>
<x>100</x>
<y>110</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Thank you for help :D</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
使用以下命令我使用 pyinstaller 将 main.py 文件转换为可执行文件:
pyinstaller --noconfirm --onefile --console --add-data "D:/!python_projects/pyinstaller_example/ui/main.ui;." "D:/!python_projects/pyinstaller_example/main.py"
然后我用 main.ui 复制 ui 文件夹到用 exe 文件创建的输出文件夹。
当我 运行 通过 cmd 创建 exe 文件时,我收到以下消息:
Cannot run 'pyside2-uic': "Process failed to start: The system cannot find the file specified." - Exit status QProcess::NormalExit ( 0 )
Check if 'pyside2-uic' is in PATH
Traceback (most recent call last):
File "main.py", line 10, in <module>
TypeError: cannot unpack non-iterable NoneType object
[6392] Failed to execute script main
我是否在 pyinstaller 命令或 py 文件中遗漏了一些重要的东西?
EDITv1:
我将 uic 工具复制到带有 exe 的文件夹,将其重命名为“pyside2-uic”并出现以下错误:
Error while compiling the generated Python file
File "<stdin>", line 1
/********************************************************************************
^
SyntaxError: invalid syntax
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "main.py", line 10, in <module>
SystemError: <built-in function loadUiType> returned a result with an error set
[11612] Failed to execute script main
如果选中 source code:
// Use the 'pyside2-uic' wrapper instead of 'uic'
// This approach is better than rely on 'uic' since installing
// the wheels cover this case.
QString uicBin("pyside2-uic");
QStringList uicArgs = {QString::fromUtf8(uiFileName)};
据观察,它使用 pyside2-uic 工具从 .ui 中获取 python 代码,但在 PySide2 的最新版本中该脚本已被删除(可能一个错误),因为使用了 uic 工具。
一个可能的解决方案是将 pyside2-uic 脚本复制到可执行文件旁边:
pyside2-uic
# -*- coding: utf-8 -*-
import re
import sys
from PySide2.scripts.pyside_tool import uic
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(uic())
我想将我的 PySide2 应用程序转换为 exe 文件。使用 PySide2.QtUiTools 中的 loadUiType 函数加载 ui 文件很重要。最小可重现示例包含:
Python 文件:
import os
from PySide2 import QtWidgets
from PySide2.QtUiTools import loadUiType
from PySide2 import QtXml
current_dir = os.environ.get(
"_MEIPASS2",
os.path.abspath(".")
)
Form, Base = loadUiType(os.path.join(current_dir, "ui\main.ui"))
class MainWidget(Base, Form):
def __init__(self, parent=None):
super(self.__class__, self).__init__(parent)
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
main_widget_object = MainWidget()
main_widget_object.show()
sys.exit(app.exec_())
Ui 文件:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QPushButton" name="button">
<property name="geometry">
<rect>
<x>100</x>
<y>110</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Thank you for help :D</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
使用以下命令我使用 pyinstaller 将 main.py 文件转换为可执行文件:
pyinstaller --noconfirm --onefile --console --add-data "D:/!python_projects/pyinstaller_example/ui/main.ui;." "D:/!python_projects/pyinstaller_example/main.py"
然后我用 main.ui 复制 ui 文件夹到用 exe 文件创建的输出文件夹。 当我 运行 通过 cmd 创建 exe 文件时,我收到以下消息:
Cannot run 'pyside2-uic': "Process failed to start: The system cannot find the file specified." - Exit status QProcess::NormalExit ( 0 )
Check if 'pyside2-uic' is in PATH
Traceback (most recent call last):
File "main.py", line 10, in <module>
TypeError: cannot unpack non-iterable NoneType object
[6392] Failed to execute script main
我是否在 pyinstaller 命令或 py 文件中遗漏了一些重要的东西?
EDITv1: 我将 uic 工具复制到带有 exe 的文件夹,将其重命名为“pyside2-uic”并出现以下错误:
Error while compiling the generated Python file
File "<stdin>", line 1
/********************************************************************************
^
SyntaxError: invalid syntax
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "main.py", line 10, in <module>
SystemError: <built-in function loadUiType> returned a result with an error set
[11612] Failed to execute script main
如果选中 source code:
// Use the 'pyside2-uic' wrapper instead of 'uic'
// This approach is better than rely on 'uic' since installing
// the wheels cover this case.
QString uicBin("pyside2-uic");
QStringList uicArgs = {QString::fromUtf8(uiFileName)};
据观察,它使用 pyside2-uic 工具从 .ui 中获取 python 代码,但在 PySide2 的最新版本中该脚本已被删除(可能一个错误),因为使用了 uic 工具。
一个可能的解决方案是将 pyside2-uic 脚本复制到可执行文件旁边:
pyside2-uic
# -*- coding: utf-8 -*-
import re
import sys
from PySide2.scripts.pyside_tool import uic
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(uic())