Windows 如何在使用py2exe时包含ui和图像文件?
我正在使用Python2.7和PySide1.1.2进行一个项目。我的代码在我的GNU/Linux上运行没有任何问题,但我也想为Windows(7和8)分发。我不能期望用户安装Python和PySide,所以我决定使用py2exe(我还尝试了cx_freeze和pyinstaller) 首先,这是我的文件树: 我创建了setup.py,如下所示: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
# -*- 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文件?或者,对于我想要完成的事情,有没有其他的方法呢?嗯,我想你可以做两件现实的事情之一:
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()