2012-11-16 99 views
3

我正在使用Python 2.7和PySide 1.1.2開展一個項目。我的代碼在我的GNU/Linux上沒有任何問題,但我想分發給Windows(7和8)。我不能指望用戶安裝Python和PySide,所以我決定使用py2exe(我也試過cx_freeze和pyinstaller)。如何在使用py2exe時包含ui和圖像文件?

首先,這裏是我的文件樹:My Project on GitHub

我創建了一個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='[email protected]', 
    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 

它成功建立但是,由於應用程序依賴於外部用戶界面文件 - 使用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 

而我無法弄清楚如何將* .ui文件(也有一些.png圖標)添加到該結構中。我正在考慮將.ui文件轉換爲Python代碼,然後當我需要添加一些圖標時遇到同樣的問題。

因此,如何添加我的ui和png文件在py2exe結構中?還是有什麼替代方法,我想要完成什麼?

回答

9

好吧,我想你可以做兩件事情的現實之一:

  1. 編譯你的.ui文件的.py使用pyside-uic文件,並修改代碼以做PY文件的加載條件的用戶界面並放置在一個Qt資源的PNG文件的文件
  2. 創建一個Qt資源與它裏面你的UI文件的文件,編譯與pyside-RCC,然後使用QtUiTools或一些類似的過程
加載UI文件

pyside-uic

我非常喜歡使用pyside-uic方法加載UI文件,因爲它是加載UI文件的最直接的方式進入,與我的Qt的相關知識,在C pyside-uic包含在PySide應用程序,對我來說在我的Python安裝的腳本目錄中找到,例如C:\Python27\Scripts\pyside-uic.exe。從C語言編譯如何處理用戶界面的文件,我通常編譯我的UI文件以一記有一個名稱,如ui_ [牛耳文件的名稱]的.py:

C:\Python27\Scripts\pyside-uic mainwindow.ui > ui_mainwindow.py 

裏面是造成.py文件中,pyside- uic創建一個名爲與Ui_前綴的ui文件的基類名稱相同的類。因此,例如,如果創建了包含名爲MainWindow的類的定義的mainwindow.ui,則創建的類將是Ui_MainWindow。如果ui文件定義了一個名爲SourceWindow的類,該類是.py文件Ui_SourceWindow中的類。在Qt Designer中,您可以通過在對象樹的根元素(窗口右上角)中設置objectName來設置類名。

通過您的文件cafeteria_menu,ui和dialog_login.ui,您將獲得派生類Ui_cafeteria_menu和Ui_dialog_login。

一旦你有了。生成的PY文件,它可以通過將它導入到你的插件的定義文件使用,使用類的setupUi方法在UI文件中使用

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定義,所有的連接和窗口小部件的UI元素需要通過self.ui

 self.ui.lineEdit.textChanged[str].connect(self.processText) 

訪問既然你必須把你的.png文件中Qt的資源文件,我將在下一節談論它。

pyside-rcc

pyside-uicpyside-rcc包含在PySide應用程序,雖然我的是在Python的site-packages目錄,而不是在腳本(如果它是在你同一個地方,你可以隨時將它複製)。

C:\Python27\lib\site-packages\PySide\pyside-rcc.exe 

在編譯Qt資源文件之前,您必須先使用Qt工具之一來創建它。我使用Qt Creator,因爲它可以在一個應用程序中執行幾乎所有與Qt相關的功能。 Qt Resource System的文檔顯示資源文件實際上只是一個定義資源系統的文件路徑和內部路徑的XML文件。您可以根據需要設置和組織文件,但在編譯時,資源文件中定義的所有文件必須位於同一目錄或文件的子目錄中。定義資源文件後,您需要使用pyside-rcc.exe將其編譯爲.py文件。我通常將資源文件命名爲與項目相同,並將所有內容保存在一個資源文件中,以使資源處理更加簡潔。

C:\Python27\lib\site-packages\PySide\pyside-rcc.exe -py2 MyProject.qrc > MyProject_Resources.py 

的-py2開關限定了從文件輸出應被格式化爲Python 2.x的如果您正在使用Python 3.x或計劃將來使用它,則可以使用-py3開關,並且結果將與Python 3.x兼容。

全部放在一起

既然你已經直接加載UI文件QUiLoader,你只需要重構自己QUiLoader語句來加載開放從資源系統的UI資源的一個QFile時。要使用資源系統中的文件,您只需將資源.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的GUICafeteriaMenu代碼中使用時,我只需更改用於GuiCafeteriaMenu的__init__方法以加載和使用資源中的ui文件:

uiFile = QFile(":/ui/cafeteria_menu.ui") 
uiFile.open(QFile.ReadOnly) 
UiLoader.load(uiFile, self) 
uiFile.close() 

我可能會將pyside-rcc的輸出放入metsuite_libs包中,放入類似msResources.py的文件中,並導入__init__.py文件中的msResources文件作爲包的一部分。這樣,一旦將.py文件創建並導入到您的程序中,額外的文件將被封裝在您的軟件包中,您將不需要更改setup.py文件。在進行py2exe轉換之前,運行重構程序應該正常工作。此外,無論您如何處理ui文件,您始終需要使用資源文件才能將圖標打包到程序中。出於便攜性的原因,使用資源文件作爲圖標可能是一個很好的習慣。

相關問題