Source code for silx.gui.icons

# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
"""Set of icons for buttons.

Use :func:`getQIcon` to create Qt QIcon from the name identifying an icon.
"""

__authors__ = ["T. Vincent"]
__license__ = "MIT"
__date__ = "15/09/2016"


import logging
import weakref
from . import qt
from ..resources import resource_filename
from ..utils import weakref as silxweakref


_logger = logging.getLogger(__name__)
"""Module logger"""


_cached_icons = weakref.WeakValueDictionary()
"""Cache loaded icons in a weak structure"""


_supported_formats = None
"""Order of file format extension to check"""


_process_working = None
"""Cache an AnimatedIcon for working process"""


[docs]def getWaitIcon(): """Returns a cached version of the waiting AnimatedIcon. :rtype: AnimatedIcon """ global _process_working if _process_working is None: _process_working = AnimatedIcon("process-working") return _process_working
[docs]class AnimatedIcon(qt.QObject): """Store a looping QMovie to provide icons for each frames. Provides an event with the new icon everytime the movie frame is updated.""" def __init__(self, filename, parent=None): """Constructor :param str filename: An icon name to an animated format :param qt.QObject parent: Parent of the QObject :raises: ValueError when name is not known """ qt.QObject.__init__(self, parent) qfile = getQFile(filename) self.__movie = qt.QMovie(qfile.fileName(), qt.QByteArray(), parent) self.__movie.setCacheMode(qt.QMovie.CacheAll) self.__movie.frameChanged.connect(self.__frameChanged) self.__targets = silxweakref.WeakList() self.__currentIcon = None self.__cacheIcons = {} self.__movie.jumpToFrame(0) self.__updateIconAtFrame(0) iconChanged = qt.Signal(qt.QIcon) """Signal sent with a QIcon everytime the animation changed.""" def __frameChanged(self, frameId): """Callback everytime the QMovie frame change :param int frameId: Current frame id """ self.__updateIconAtFrame(frameId) def __updateIconAtFrame(self, frameId): """ Update the current stored QIcon :param int frameId: Current frame id """ if frameId in self.__cacheIcons: self.__currentIcon = self.__cacheIcons[frameId] else: self.__currentIcon = qt.QIcon(self.__movie.currentPixmap()) self.__cacheIcons[frameId] = self.__currentIcon self.iconChanged.emit(self.__currentIcon)
[docs] def register(self, obj): """Register an object to the AnimatedIcon. If no object are registred, the animation is paused. Object are stored in a weaked list. :param object obj: An object """ if obj not in self.__targets: self.__targets.append(obj) self.__updateMovie()
[docs] def unregister(self, obj): """Remove the object from the registration. If no object are registred the animation is paused. :param object obj: A registered object """ if obj in self.__targets: self.__targets.remove(obj) self.__updateMovie()
[docs] def isRegistered(self, obj): """Returns true if the object is registred in the AnimatedIcon. :param object obj: An object """ return obj in self.__targets
def __updateMovie(self): """Update the movie play according to internal stat of the AnimatedIcon.""" # FIXME it should take care of the item count of the registred list self.__movie.setPaused(len(self.__targets) == 0)
[docs] def currentIcon(self): """Returns the icon of the current frame. :rtype: qt.QIcon """ return self.__currentIcon
[docs]def getQIcon(name): """Create a QIcon from its name. :param str name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QIcon :raises: ValueError when name is not known """ if name not in _cached_icons: qfile = getQFile(name) icon = qt.QIcon(qfile.fileName()) _cached_icons[name] = icon else: icon = _cached_icons[name] return icon
[docs]def getQPixmap(name): """Create a QPixmap from its name. :param str name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QPixmap :raises: ValueError when name is not known """ qfile = getQFile(name) return qt.QPixmap(qfile.fileName())
[docs]def getQFile(name): """Create a QFile from an icon name. Filename is found according to supported Qt formats. :param str name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QFile :rtype: qt.QFile :raises: ValueError when name is not known """ global _supported_formats if _supported_formats is None: _supported_formats = [] supported_formats = qt.supportedImageFormats() order = ["mng", "gif", "svg", "png", "jpg"] for format_ in order: if format_ in supported_formats: _supported_formats.append(format_) if len(_supported_formats) == 0: _logger.error("No format supported for icons") else: _logger.debug("Format %s supported", ", ".join(_supported_formats)) for format_ in _supported_formats: format_ = str(format_) filename = resource_filename('gui/icons/%s.%s' % (name, format_)) qfile = qt.QFile(filename) if qfile.exists(): return qfile raise ValueError('Not an icon name: %s' % name)