PyQt и py2exe или cx_freeze: AttributeError

Здесь у меня Python 2.7.3 (x64), PyQt 4.9.5-1 (x64), работающий на Win7 x64. Я хочу преобразовать простой скрипт PyQt в исполняемый файл.
Это мой скрипт на 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_()

Запуск из командной строки работает как положено. Я использую setup.py для py2exe:

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

Однако, если я попытаюсь преобразовать его в exe-файл с помощью py2exe 0.6.9 с python setup.py py2exe, я получаю эту ошибку при запуске 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'

Я также пробовал cx_freeze 4.3 с \Python27\Scripts\cxfreeze pyqt-example.py --target-dir dist. Это приводит к:

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. Что именно мне не хватает?


person André    schedule 05.10.2012    source источник
comment
Вы пробовали использовать QtGui.QApplication вместо Qt.QApplication?   -  person Bakuriu    schedule 05.10.2012
comment
Если я это сделаю, сам скрипт больше не будет работать: NameError: name 'QtGui' is not defined   -  person André    schedule 05.10.2012
comment
Вы изменили импорт с from PyQt4 import Qt на from PyQt4 import QtGui?. Также имейте в виду, что при импорте PyQt4.Qt загружаются все модули, а при импорте PyQt4.QtGui загружаются только те модули, которые вам нужны.   -  person Bakuriu    schedule 05.10.2012
comment
Скрипт нормально работает как сказано выше - проблемы только если лечить py2exe или cx_freeze. Однако, если я внесу ваши изменения и использую с ним cx_freeze, сообщение об ошибке изменится на: AttributeError: 'module' object has no attribute 'QPushButton'   -  person André    schedule 05.10.2012
comment
Упаковка приложений PyQt с помощью py2exe или cx_freeze требует дополнительных обходных путей, а модуль Qt в PyQt4 — это просто удобный модуль для импорта всего. Возможно, обходные пути, используемые этими системами пакетов, не включают Qt. Попробуйте использовать явные имена для QtGui, QtCore и т. д.   -  person Avaris    schedule 06.10.2012


Ответы (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. И это работает!

person André    schedule 08.10.2012