[PyQt] Changing current runtime directory prevent icons to be loaded from *.ui files

Phil Thompson phil at riverbankcomputing.com
Fri Apr 23 18:15:00 BST 2010


On Fri, 16 Apr 2010 13:10:53 +0200, Yann Cointepas <yann at sapetnioc.org>
wrote:
> Icons file names are relative  in *.ui files. When loadUi is used, PyQt4
> (at
> least for version 4.3.3) directly sends this relative path to QIcon
> constructor. As a result icons cannot be loaded if Python current
directory
> is not the directory of the *.ui file. Changing the runtime directory
> before
> calling loadUi is not always possible. For instance if you are in a
> multithreaded application you may have problems if some threads are using
> the current directory.
> 
> A solution could be to have a base directory for relative paths for each
> *.ui file parser. This base directory would be set to the directory
> containing the ui file. This can be done by modifying the
> PyQt4.uic.properties.Property class so that the _iconset method uses this
> base directory. Others methods could be changed in the same way (_pixmap
> for
> instance). The following example show how _iconset could be modified to
> take
> into account a base directory stored in an attribute named
_basedirectory:
> 
> Current code (from PyQt 4.3.3 installed on Linux):
> 
>     def _iconset(self, prop):
>         return QtGui.QIcon(prop.text.replace("\\", "\\\\"))
> 
> Modified code:
> 
>     def _iconset(self, prop):
>         return
> QtGui.QIcon(os.path.join(self._basedirectory,prop.text).replace("\\",
> "\\\\"))
> 
> For current version of PyQt, it is possible to use the following ugly
code
> do define a replacement function to loadUi:
> 
> import os
> from functools import partial
> from PyQt4 import QtGui, uic
> from PyQt4.uic.Loader import loader
> 
> def _iconset(self, prop):
>   return QtGui.QIcon( os.path.join( self._basedirectory, prop.text
> ).replace("\\", "\\\\") )
> 
> def loadUiWithIcons( ui, *args, **kwargs ):
>   uiLoader = loader.DynamicUILoader()
>   uiLoader.wprops._basedirectory = os.path.dirname( os.path.abspath( ui )
)
>   uiLoader.wprops._iconset = partial( _iconset, uiLoader.wprops )
>   return uiLoader.loadUi( ui, *args, **kwargs )
> 
> 
>       Yann

I've changed loadUi() so that image files with relative names (and not
referring to resource files) will be relative to the directory containing
the .ui file.

Phil


More information about the PyQt mailing list