PyQt和Py2exe结合出现系统路径错误

10

我的问题:

我有一个问题,如果我尝试在使用Pyqt/Pyside的Python文件上运行py2exe,当尝试运行在I:\Documents\Python\Buttonio_Testio\dist中生成的EXE时,会收到以下错误:

运行Package.exe时收到的错误:

I:\Documents\Python\Buttonio_Testio\dist>Package.exe
Traceback (most recent call last):
  File "Package.py", line 1, in <module>
  File "PySide\__init__.pyc", line 55, in <module>
  File "PySide\__init__.pyc", line 11, in _setupQtDirectories
  File "PySide\_utils.pyc", line 87, in get_pyside_dir
  File "PySide\_utils.pyc", line 83, in _get_win32_case_sensitive_name
  File "PySide\_utils.pyc", line 58, in _get_win32_short_name
WindowsError: [Error 3] The system cannot find the path specified.

我的setup.py文件看起来像这样:

    from distutils.core import setup
    import py2exe

    setup(console=['Package.py'])

My program, in Package.py looks like this:

from PySide.QtCore import *
from PySide.QtGui import *
import sys

import Gui


class Ui_Dialog(QDialog, Gui.Ui_Dialog):
    #Setupui and function afterwards generated converting XML file made by QT Desiner to python.
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(279, 295)
        self.textBrowser = QtGui.QTextBrowser(Dialog)
        self.textBrowser.setGeometry(QtCore.QRect(10, 10, 256, 192))
        self.textBrowser.setObjectName("textBrowser")
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(10, 210, 251, 71))
        self.pushButton.setObjectName("PushButton")

        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.textBrowser.clear)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("Dialog", "Clear Spam", None, QtGui.QApplication.UnicodeUTF8))

    def __init__(self, parent=None):
        super(Ui_Dialog, self).__init__(parent)
        self.setupUi(self)
        self.spam()

    def spam(self):
        self.textBrowser.append("SPAM")
        self.textBrowser.append("SPAM")
        self.textBrowser.append("SPAM")
        self.textBrowser.append("LOL")
        self.textBrowser.append("I")
        self.textBrowser.append("AM")
        self.textBrowser.append("SPAMMING")
        self.textBrowser.append("MYSELF")

app = QApplication(sys.argv)
form = Ui_Dialog()
form.show()
app.exec_()

我正在使用Windows 8操作系统,安装了32位Python和32位的模块。当我在命令提示符中运行setup.py时,Package.py文件与setup.py文件位于同一文件夹中。除此之外,我不知道还需要哪些其他信息来帮助解决我的问题。

就这些了,谢谢您提前给予任何答复。


我现在也遇到了同样的问题,但是没有人能给出任何提示... - foresightyj
你顺便找到解决方案了吗? - foresightyj
1
@foresightyj,我使用Python 3.3.2和PySide 1.2.0时遇到了不同的错误,但是来自相同的位置。我在Qt论坛上发布了一个问题(https://qt-project.org/forums/viewthread/29881/),希望我们中的某个人能得到答案。 - Praetorian
@Praetorian 我正在使用Python 2.7.5。我也尝试在pyqt的论坛上登录并发布问题,但我找不到可以开始新帖子的POST...我的修复看起来目前运行良好。希望他们能尽快解决这个问题。 - foresightyj
4个回答

7
我过去三个小时一直在拼命地寻找解决方案。最终,我进入了C:\Python27\Lib\site-packages\PySide目录中的_ _ init_ _.py文件。我将最后一行更改为以下内容:
try:
    _setupQtDirectories()
except WindowsError:
    pass

我承认这很丑。我希望PySide的开发者们能尽快修复这个问题。


2
我用稍微不同的方式修复了它,只有在应用程序没有冻结时才调用该函数。if not hasattr(sys, 'frozen'): _setupQtDirectories() - Praetorian
在我们随意跳过这个函数之前,它的目的是什么? - ArtOfWarfare
我想补充一下,我已经按照Praetorian的建议修改了这个函数,看起来解决了我的问题...但我仍然很想知道这个函数的作用。也许这应该在StackOverflow上提出一个单独的问题。 - ArtOfWarfare
@ArtOfWarfare 我从来没有时间去弄清楚它。但是在使用了两个月后,我从未遇到过任何问题。 - foresightyj

5

对于PySide 1.2.1版本: 在PySide/_utils.py中修复get_pyside_dir()函数。

if sys.platform == 'win32':
    ...
    def get_pyside_dir():
        is_frozen = hasattr(sys, 'frozen')
        try:
            from . import QtCore
        except ImportError: 
            s1 = sys.argv[0] if is_frozen else __file__
            return _get_win32_case_sensitive_name(os.path.abspath(os.path.dirname(s1)))
        else:
            s2 = sys.argv[0] if is_frozen else QtCore.__file__
            return _get_win32_case_sensitive_name(os.path.abspath(os.path.dirname(s2)))
else:
    def get_pyside_dir():
        is_frozen = hasattr(sys, 'frozen')
        try:
            from . import QtCore
        except ImportError:
            s1 = sys.argv[0] if is_frozen else __file__
            return os.path.abspath(os.path.dirname(s1))
        else:
            s2 = sys.argv[0] if is_frozen else QtCore.__file__
            return os.path.abspath(os.path.dirname(s2))

使用py2exe或其他“冷冻器”时,_utils.py中的__file__值将指向zip归档文件内部的文件,这显然不符合PySide的预期。因此,您需要处理此情况并强制_utils.py使用实际存在PySide dll和其他内容的路径(在我的情况下,是.exe文件所在的目录)。

这对我有用,谢谢。我在_utils.py 中看到了 get_pyside_dir 的第二个定义,涉及 64 位环境。这个也应该修改吗,还是问题只与 32 位有关?我安装的是 Python 2.7 32 位版本,现在无法测试它。 - Christoph Jüngling
是的,必须修复所有get_pyside_dir的出现。我编辑了我的答案来处理两种情况:win32和其他情况 - 您可以使用它。 - Nikolai Saiko

5
问题在于_utils.py使用了__file__,但是在冻结的可执行文件中不可用。这个问题在PySide 1.2.1中已经得到解决,该版本于几天前发布(通过提交817a5c9bd39d3a22e2a7db9aa497059be57d58d7进行修复)。

1
安装 PySide v1.2.1(从1.2.0)对我的问题没有解决。 - Scruffy
没错,今天在使用Pyside V1.2.1时又遇到了同样的错误。 - foresightyj

0

我尝试安装PySide 1.2.1,但仍然遇到了这个问题。

我刚刚更改了PySide._utils中的get_pyside_dir()函数,以返回我的pyside路径,对我来说是"C:\Python27\Lib\site-packages\PySide"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接