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.<br>
<br>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:<br>
<br>Current code (from PyQt 4.3.3 installed on Linux):<br><br> def _iconset(self, prop):<br> return QtGui.QIcon(prop.text.replace("\\", "\\\\"))<br><br>Modified code:<br><br> def _iconset(self, prop):<br>
return QtGui.QIcon(os.path.join(self._basedirectory,prop.text).replace("\\", "\\\\"))<br>
<br>For current version of PyQt, it is possible to use the following ugly code do define a replacement function to loadUi:<br><br>import os<br>from functools import partial<br>from PyQt4 import QtGui, uic<br>from PyQt4.uic.Loader import loader<br>
<br>def _iconset(self, prop):<br> return QtGui.QIcon( os.path.join( self._basedirectory, prop.text ).replace("\\", "\\\\") )<br><br>def loadUiWithIcons( ui, *args, **kwargs ):<br> uiLoader = loader.DynamicUILoader()<br>
uiLoader.wprops._basedirectory = os.path.dirname( os.path.abspath( ui ) )<br> uiLoader.wprops._iconset = partial( _iconset, uiLoader.wprops )<br> return uiLoader.loadUi( ui, *args, **kwargs )<br><br><br> Yann<br>
<br>