[PyQt] Bug: PyQt4 4.3.3 with py2exe 0.6.9 and pywin32 2.13 on Python 2.5

Pierre Raybaut contact at pythonxy.com
Sat Jun 20 07:31:33 BST 2009


Hi all,

FYI, here is a viscious bug I found: it may appear if you have installed 
py2exe 0.6.9, pywin32 2.13 and PyQt4 4.3.3 on Python 2.5 (using the 
official binaries for each of these packages).


Example:

#-------------------------------------------------------------------------------
from PyQt4.QtGui import QApplication, QFileDialog
import sys
STDOUT = sys.stdout

def file_open(parent=None):
    """File open dialog usable inside/outside a PyQt4 application"""
    if QApplication.startingUp():
        QApplication([]) # You have to create a QApplication instance first

    default_dir = "" # Default directory
    sys.stdout = None # Avoid the "Redirecting output to win32trace
                      # remote collector" message from showing in stdout
    filename = QFileDialog.getOpenFileName(parent, "Title", default_dir,
                                           "All files (*.*)")
    sys.stdout = STDOUT
    if filename:
        return unicode(filename)

print file_open()
#-------------------------------------------------------------------------------

Traceback:

Traceback (most recent call last):
  File "boot_com_servers.py", line 21, in <module>
  File "C:\Python25\lib\site-packages\pythoncom.py", line 3, in <module>
    pywintypes.__import_pywin32_system_module__("pythoncom", globals())
  File "C:\Python25\lib\site-packages\win32\lib\pywintypes.py", line 
111, in __import_pywin32_system_module__
    mod = imp.load_dynamic(modname, found)
ImportError: DLL load failed [...]


So, with this configuration, if you call any of the QFileDialog 
(PyQt4.QtGui) static methods - i.e. getSaveFileName, 
getExistingDirectory and so on, an exception will be raised showing a 
message like "ImportError: DLL load failed [...]".
The reason of this ImportError is quite clear: some PyQt4's DLL are 
loaded at static memory addresses (that's the way the official binaries 
have been built), so an import order has to be respected, otherwise when 
importing pywin32's pywintypes25.dll the memory address is already 
occupied and the module can't be imported.
On the contrary, I have no idea (I must confess that as soon as I found 
a way to avoid this error, I stop looking for answers) why py2exe's 
"boot_com_servers.py" (see traceback below) is executed when calling 
these QFileDialog methods, causing the pywin32's pythoncom module to be 
imported.


Solution:

#-------------------------------------------------------------------------------
try:
    # PyQt4 4.3.3 on Windows (static DLLs) with py2exe and pywin32 
installed:
    # -> pythoncom must be imported first, otherwise py2exe's 
boot_com_servers
    #    will raise an exception ("ImportError: DLL load failed") when 
calling
    #    any of the QFileDialog static methods (getOpenFileName, ...)
    import pythoncom
except ImportError:
    pass

from PyQt4.QtGui import QApplication, QFileDialog
import sys
STDOUT = sys.stdout

def file_open(parent=None):
    """File open dialog usable inside/outside a PyQt4 application"""
    if QApplication.startingUp():
        QApplication([]) # You have to create a QApplication instance first

    default_dir = "" # Default directory
    sys.stdout = None # Avoid the "Redirecting output to win32trace
                      # remote collector" message from showing in stdout
    filename = QFileDialog.getOpenFileName(parent, "Title", default_dir,
                                           "All files (*.*)")
    sys.stdout = STDOUT
    if filename:
        return unicode(filename)

print file_open()
#-------------------------------------------------------------------------------

Bug fixed! (or at least avoided)

Cheers,
Pierre


More information about the PyQt mailing list