【问题标题】:Pyinstaller standalone executable cannot find ui file defined in spec filePyinstaller 独立可执行文件找不到规范文件中定义的 ui 文件
【发布时间】:2020-05-19 09:03:43
【问题描述】:

我正在使用 pyinstaller 编译一个独立的可执行文件。 python 脚本使用来自 QtDesigner 的外部 ui 文件。如果没有 ui 文件,我无法让它运行可执行文件。我阅读了有关定义规范文件的信息,但是如果没有 ui 文件,我尝试的一切都不起作用。我不知道我做错了什么。我可以编译它,但是当我删除 ui 文件并运行可执行文件时,我得到了错误:

FileNotFoundError: [Errno 2] No such file or directory: 'D:/visu.ui'

如何将此文件集成到可执行文件中?

这是我的代码。使用pyi-makespec生成spec文件并手动添加数据:

visu.py

import sys
import os
from PyQt5 import QtWidgets, uic

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

Ui_MainWindow, QtBaseClass = uic.loadUiType(resource_path('visu.ui'))

class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

visu.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>172</width>
    <height>122</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>40</x>
     <y>50</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>Ok</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

visu.spec

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['D:/visu.py'],
             pathex=['C:\\Users\\xxx'],
             binaries=[],
             datas=[("visu.ui", '.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='visu',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='visu')

【问题讨论】:

    标签: python pyqt5 pyinstaller


    【解决方案1】:

    我确定如果您将visu.ui 文件转换为visu.py

    pyuic5 visu.ui -o visu.py 
    

    那么你不会有任何问题。

    pyinstaller -F -w pyinstaller_standalone_executable.py
    

    pyinstaller_standalone_executable.py

    import sys
    import os
    from PyQt5 import QtWidgets     #, uic
    
    from visu import Ui_Dialog
    
    '''
    def resource_path(relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
    
        try:
            # PyInstaller creates a temp folder and stores path in _MEIPASS
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")
    
        return os.path.join(base_path, relative_path)
    
    Ui_MainWindow, QtBaseClass = uic.loadUiType(resource_path('visu.ui'))
    '''
    
    #class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    class MyWindow(QtWidgets.QDialog, Ui_Dialog):
        def __init__(self):
            super().__init__()
    
            self.setupUi(self)
    
            self.pushButton.clicked.connect(
                lambda: QtWidgets.QMessageBox.information(None, "Message", self.pushButton.text())
            )
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        window = MyWindow()
        window.show()
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 2015-10-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      相关资源
      最近更新 更多