【问题标题】:PyQt and py2exe or cx_freeze: AttributeErrorPyQt 和 py2exe 或 cx_freeze:AttributeError
【发布时间】:2012-10-05 13:13:36
【问题描述】:

在这里,我在 Win7 x64 上运行 Python 2.7.3 (x64)、PyQt 4.9.5-1 (x64)。我想将一个简单的 PyQt 脚本转换为一个 exe 文件。
这是我的 python 脚本:

#!/usr/bin/env python

import sys
from PyQt4 import Qt

a = Qt.QApplication(sys.argv)

def sayHello():
    print "Hello, World!"

hellobutton = Qt.QPushButton("Say 'Hello world!'",None)

a.connect(hellobutton, Qt.SIGNAL("clicked()"), sayHello)

hellobutton.show()
a.exec_()

从命令行运行它可以按预期工作。 我为 py2exe 使用 setup.py:

from distutils.core import setup
import py2exe
setup(console=['pyqt-example.py'])

但是,如果我尝试使用 py2exe 0.6.9 将其转换为带有 python setup.py py2exe 的 exe 文件,则在运行该 exe 文件时会出现此错误:

Traceback (most recent call last):
  File "pyqt-example.py", line 6, in <module>
    a = Qt.QApplication(sys.argv)
AttributeError: 'module' object has no attribute 'QApplication'

我还用\Python27\Scripts\cxfreeze pyqt-example.py --target-dir dist 尝试了 cx_freeze 4.3。这导致:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>
    exec code in m.__dict__
  File "pyqt-example.py", line 6, in <module>
    a = Qt.QApplication(sys.argv)
AttributeError: 'module' object has no attribute 'QApplication'

所以我假设我错过了通知这两个工具一些 Qt 组件的位置。我到底错过了什么?

【问题讨论】:

  • 你试过用QtGui.QApplication代替Qt.QApplication吗?
  • 如果我这样做,脚本本身将不再运行:NameError: name 'QtGui' is not defined
  • 您确实将导入从 from PyQt4 import Qt 更改为 from PyQt4 import QtGui?。还要考虑到导入 PyQt4.Qt 会加载 所有 模块,而导入 PyQt4.QtGui 只会加载您需要的模块。
  • 脚本工作正常,如上所述 - 只有当我使用 py2exe 或 cx_freeze 处理它时才会出现问题。但是,如果我进行更改并使用 cx_freeze,错误消息将更改为:AttributeError: 'module' object has no attribute 'QPushButton'
  • 使用 py2exe 或 cx_freeze 打包 PyQt 应用程序需要额外的解决方法,PyQt4 中的 Qt 模块只是一个方便导入所有内容的模块。这些软件包系统使用的解决方法可能不包括Qt。尝试为QtGuiQtCore 等使用明确的名称。

标签: python pyqt4 py2exe cx-freeze


【解决方案1】:

感谢 Avaris,您的提示是正确的。避免使用模块 Qt 就是答案。这是运行良好的脚本:

#!/usr/bin/env python

import sys
from PyQt4 import QtGui,QtCore

a = QtGui.QApplication(sys.argv)

def sayHello():
    print "Hello, World!"

hellobutton = QtGui.QPushButton("Say 'Hello world!'",None)

a.connect(hellobutton, QtCore.SIGNAL("clicked()"), sayHello)

hellobutton.show()
a.exec_()

之后,我必须调用 cx_freeze:cxfreeze pyqt-example.py --include-modules atexit --target-dir dist。它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多