| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- #############################################################################
- ##
- ## Copyright (c) 2026 Riverbank Computing Limited <info@riverbankcomputing.com>
- ##
- ## This file is part of PyQt6.
- ##
- ## This file may be used under the terms of the GNU General Public License
- ## version 3.0 as published by the Free Software Foundation and appearing in
- ## the file LICENSE included in the packaging of this file. Please review the
- ## following information to ensure the GNU General Public License version 3.0
- ## requirements will be met: http://www.gnu.org/copyleft/gpl.html.
- ##
- ## If you do not wish to use this file under the terms of the GPL version 3.0
- ## then you may purchase a commercial license. For more information contact
- ## info@riverbankcomputing.com.
- ##
- ## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- ##
- #############################################################################
- import os.path
- class IconCache(object):
- """Maintain a cache of icons. If an icon is used more than once by a GUI
- then ensure that only one copy is created.
- """
- def __init__(self, object_factory, qtgui_module):
- """Initialise the cache."""
- self._object_factory = object_factory
- self._qtgui_module = qtgui_module
- self._base_dir = ''
- self._cache = []
- def set_base_dir(self, base_dir):
- """ Set the base directory to be used for all relative filenames. """
- self._base_dir = base_dir
- def get_icon(self, iconset):
- """Return an icon described by the given iconset tag."""
- # Handle a themed icon.
- theme = iconset.attrib.get('theme')
- if theme is not None:
- # Qt v6.7 supports QIcon::ThemeIcon.
- if theme.startswith('QIcon::ThemeIcon'):
- obj = self._qtgui_module
- for name in theme.split('::'):
- obj = getattr(obj, name)
- theme = obj
- else:
- theme = self._object_factory.asString(theme)
- return self._object_factory.createQtObject('QIcon.fromTheme',
- 'icon', ctor_args=(theme, ), is_attribute=False)
- # Handle an empty iconset property.
- if iconset.text is None:
- return None
- iset = _IconSet(iconset, self._base_dir)
- try:
- idx = self._cache.index(iset)
- except ValueError:
- idx = -1
- if idx >= 0:
- # Return the icon from the cache.
- iset = self._cache[idx]
- else:
- # Follow uic's naming convention.
- name = 'icon'
- idx = len(self._cache)
- if idx > 0:
- name += str(idx)
- icon = self._object_factory.createQtObject('QIcon', name,
- is_attribute=False)
- iset.set_icon(icon, self._qtgui_module)
- self._cache.append(iset)
- return iset.icon
- class _IconSet(object):
- """An icon set, ie. the mode and state and the pixmap used for each."""
- def __init__(self, iconset, base_dir):
- """Initialise the icon set from an XML tag."""
- # Set the pre-Qt v4.4 fallback (ie. with no roles).
- self._fallback = self._file_name(iconset.text, base_dir)
- self._use_fallback = True
- # Parse the icon set.
- self._roles = {}
- for i in iconset:
- file_name = i.text
- if file_name is not None:
- file_name = self._file_name(file_name, base_dir)
- self._roles[i.tag] = file_name
- self._use_fallback = False
- # There is no real icon yet.
- self.icon = None
- @staticmethod
- def _file_name(fname, base_dir):
- """ Convert a relative filename if we have a base directory. """
- fname = fname.replace("\\", "\\\\")
- if base_dir != '' and fname[0] != ':' and not os.path.isabs(fname):
- fname = os.path.join(base_dir, fname)
- return fname
- def set_icon(self, icon, qtgui_module):
- """Save the icon and set its attributes."""
- if self._use_fallback:
- icon.addFile(self._fallback)
- else:
- for role, pixmap in self._roles.items():
- if role.endswith("off"):
- mode = role[:-3]
- state = qtgui_module.QIcon.State.Off
- elif role.endswith("on"):
- mode = role[:-2]
- state = qtgui_module.QIcon.State.On
- else:
- continue
- mode = getattr(qtgui_module.QIcon.Mode, mode.title())
- if pixmap:
- icon.addPixmap(qtgui_module.QPixmap(pixmap), mode, state)
- else:
- icon.addPixmap(qtgui_module.QPixmap(), mode, state)
- self.icon = icon
- def __eq__(self, other):
- """Compare two icon sets for equality."""
- if not isinstance(other, type(self)):
- return NotImplemented
- if self._use_fallback:
- if other._use_fallback:
- return self._fallback == other._fallback
- return False
- if other._use_fallback:
- return False
- return self._roles == other._roles
|