Windows 如何在使用py2exe时包含ui和图像文件?

Windows 如何在使用py2exe时包含ui和图像文件?,windows,py2exe,pyside,Windows,Py2exe,Pyside,我正在使用Python2.7和PySide1.1.2进行一个项目。我的代码在我的GNU/Linux上运行没有任何问题,但我也想为Windows(7和8)分发。我不能期望用户安装Python和PySide,所以我决定使用py2exe(我还尝试了cx_freeze和pyinstaller) 首先,这是我的文件树: 我创建了setup.py,如下所示: # -*- coding: utf-8 -*- from distutils.core import setup import py2exe se

我正在使用Python2.7和PySide1.1.2进行一个项目。我的代码在我的GNU/Linux上运行没有任何问题,但我也想为Windows(7和8)分发。我不能期望用户安装Python和PySide,所以我决定使用py2exe(我还尝试了cx_freeze和pyinstaller)

首先,这是我的文件树:

我创建了setup.py,如下所示:

# -*- coding: utf-8 -*-

from distutils.core import setup
import py2exe

setup(
    console=['bin/metusuite.py'],
    name='metusuite',
    version='0.1',
    author='H. Gökhan Sarı',
    author_email='me@th0th.me',
    packages=['metusuite_libs'],
    package_dir={'metusuite_libs': 'metusuite_libs'},
    package_data={'metusuite_libs': ['ui/*', 'images/*']},
    scripts=['bin/metusuite.py'],
    url='https://github.com/th0th/metusuite/',
    license='LICENSE.txt',
    description='METU Suite.',
    long_description=open('README.md').read(),
)
当我跑的时候

setup.py py2exe
它成功地在“dist”文件夹中构建了metusuite.exe,但是,由于应用程序依赖于外部用户界面文件(使用Qt Designer创建),并且找不到这些文件,因此出现了一个错误:

Designer: An error has occurred while reading the UI file at line 1, column 0: Premature end of document.
Traceback (most recent call last):
  File "metusuite.py", line 38, in <module>
  File "metusuite_libs\msCafeteriaMenu.pyc", line 37, in __init__
  File "metusuite_libs\msCafeteriaMenu.pyc", line 17, in __init__
RuntimeError: Unable to open/read ui device
Designer:读取第1行第0列的UI文件时出错:文档过早结束。
回溯(最近一次呼叫最后一次):
文件“metusuite.py”,第38行,在
文件“metusuite_libs\msCafeteriaMenu.pyc”,第37行,在u init中__
文件“metusuite_libs\msCafeteriaMenu.pyc”,第17行,在__
运行时错误:无法打开/读取ui设备
我不知道该如何将*.ui文件(还有一些.png图标)添加到该结构中。我正在考虑将.ui文件转换为Python代码,然后当我需要添加一些图标时,我会遇到同样的问题


因此,如何在py2exe结构中添加ui和png文件?或者,对于我想要完成的事情,有没有其他的方法呢?

嗯,我想你可以做两件现实的事情之一:

  • 使用将.ui文件编译为.py文件,并修改代码以有条件地加载用户界面的py文件,并将png文件放置在Qt资源文件中
  • 创建一个包含ui文件的Qt资源文件,使用pyside rcc编译该文件,然后使用QtUiTools或类似过程加载ui文件
  • pyside uic
    <>我非常喜欢使用<代码> PySudioUC/<代码>方法来加载UI文件,因为它是将UI文件加载到程序中最直接的方式,它与我在C++中对Qt的知识有关。代码>pyside uic包含在pyside应用程序中,对我来说,它可以在Python安装的脚本目录中找到,例如
    C:\Python27\Scripts\pyside uic.exe
    。从C++编译如何处理UI文件的注释中,我通常编译我的UI文件,以获得一个名称,如ui[[ UI文件的名称] ]。
    C:\Python27\Scripts\pyside-uic mainwindow.ui > ui_mainwindow.py
    
    在生成的.py文件中,pyside uic创建了一个名为与ui文件的基类同名的类,该基类前面加了ui。因此,例如,如果您创建了一个mainwindow.ui,其中包含名为mainwindow的类的定义,则创建的类将是ui\u mainwindow。如果ui文件定义了一个名为SourceWindow的类,则.py文件ui\u SourceWindow中的类。在Qt Designer中,通过在对象树的根元素(窗口右上角)中设置
    objectName
    来设置类名

    使用文件caffeeta\u menu、ui和dialog\u login.ui,您将获得派生类ui\u caffeeta\u menu和ui\u dialog\u login

    生成.py文件后,可以通过将其导入小部件的定义文件并使用Ui文件中类的setupUi方法来使用它

    from PySide import QtCore, QtGui
    from ui_mainwindow import Ui_MainWindow
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
    
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
    一旦为类定义了ui,就需要通过self.ui访问小部件的所有连接和ui元素

            self.ui.lineEdit.textChanged[str].connect(self.processText)
    
    由于您必须将.png文件放在Qt资源文件中,因此我将在下一节中讨论它

    pyside rcc
    pyside uic
    类似,
    pyside rcc
    也包含在pyside应用程序中,尽管我的应用程序位于Python的site packages目录中,而不是脚本中(如果它位于同一位置,您可以随时复制它)

    在编译Qt资源文件之前,必须首先使用Qt工具之一创建它。我使用QtCreator,因为它可以在一个应用程序中执行几乎所有与Qt相关的功能。的文档表明,资源文件实际上只是一个XML文件,它定义了资源系统的文件路径和内部路径。您可以根据需要设置和组织文件,但在编译时,资源文件中定义的所有文件必须位于同一目录或文件的子目录中。定义了资源文件后,需要使用pyside-rcc.exe将其编译为.py文件。我通常将资源文件命名为与项目相同的名称,并将所有内容保存在一个资源文件中,以使处理资源更加简洁

    C:\Python27\lib\site-packages\PySide\pyside-rcc.exe -py2 MyProject.qrc > MyProject_Resources.py
    
    -py2开关定义该文件的输出应为Python2.x格式。如果您正在使用Python3.x或计划在将来使用它,那么可以使用-py3开关,结果将与Python3.x兼容

    把它们放在一起 由于您已经在直接加载ui文件
    QUiLoader
    ,因此只需重构QUiLoader语句即可加载从资源系统打开ui资源的QFile。要使用资源系统中的文件,只需将resource.py文件(从pyside rcc生成的文件)导入到程序的主脚本文件中,资源文件中的最后一行是对qInitResources()的调用,该调用将初始化整个程序中要使用的资源。要使用QFile加载文件,请使用以“:”开头的路径,然后引用资源文件中定义的路径。您可以创建一个文件msResources.qrc,该文件包含将ui和png文件定义为子类别的ui和图像

    那么,如果您的资源文件看起来像这样

    /ui
        cafeteria_menu.ui
        dialog_login.ui
    /images
        cafeteria-menu.png
        exit.png
        logo.png
        mail-fetch.ong
    
    如果要加载这些文件,只需创建一个QIcon或QFile,如下所示:

    cafeteriaMenuIcon = QtGui.QIcon(":/images/cafeteria-menu.png")
    cafeteriaMenuUi = QtCore.QFile(":/ui/cafeteria_menu.ui")
    
    在msCafeteriaMenu中的guicafeteraamenu代码中使用时,我只需更改guicafeteraamenu的
    \uuuu init\uuuu
    方法,以便从参考资料中加载和使用ui文件:

    uiFile = QFile(":/ui/cafeteria_menu.ui")
    uiFile.open(QFile.ReadOnly)
    UiLoader.load(uiFile, self)
    uiFile.close()
    
    我可能会将pyside rcc的输出放入metsuit
    uiFile = QFile(":/ui/cafeteria_menu.ui")
    uiFile.open(QFile.ReadOnly)
    UiLoader.load(uiFile, self)
    uiFile.close()