【问题标题】:Problem with Pyinstaller and loadUiType in PySide2PySide2 中 Pyinstaller 和 loadUiType 的问题
【发布时间】:2021-06-17 03:50:56
【问题描述】:

我想将我的 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: 我使用 exe 将 uic 工具复制到文件夹,将其重命名为“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

【问题讨论】:

  • 问题是 loadUiType 使用 pyside2-uic 工具进行转换,在您的情况下找不到它,请尝试以下操作:1)查看 PySide2 文件夹(您可以找到通过在 cmd 中执行以下命令来创建文件夹:python -c "import os; import PySide2; print(os.path.dirname(PySide2.__file__))") 工具 pyside2-uic 并将其复制到可执行文件旁边。 2)或者将你的操作系统环境变量的PATH添加到PySide2文件夹的路径
  • output folder 是什么意思? .exe 文件是自解压的 .zip 文件,它会创建您在 current_dir 中的名称的新文件夹,您应该将 .ui 放入此文件夹中 - 但此文件夹是在 .exe 启动时创建的,它可能具有随机名称。或者你应该将.ui 添加到配置文件 - spec - 它应该将.ui 添加到.exe
  • 如果我在loadUiType(os.path.join(current_dir, "ui/main.ui")) 中使用/ 而不是\ ,它适用于我。我认为使用os.path.join(current_dir, "ui", "main.ui") 会更安全
  • @eyllanesc 我尝试了您评论中的步骤。我想找到 PySide2 文件夹,但我可以找到“pyside2-uic”工具,我只找到 uic 应用程序。后来我将它复制到带有可执行文件的文件夹中,并将“uic”重命名为“pyside2-uic”。出现以下错误(上述错误值)
  • @furas 在 Linux 中使用 pip 安装工具时(例如安装 pyside2 时,也安装了 pyside2-uic),它放在 Linux 知道有二进制文件的文件夹中,所以它不会失败,但在 Windows 中不会发生。

标签: python windows pyinstaller pyside2


【解决方案1】:

如果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())

【讨论】:

    猜你喜欢
    • 2019-11-01
    • 2021-11-16
    • 2021-06-25
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多