Source code for psi.experiment.util

import logging
from importlib import resources
from pathlib import Path

from enaml.icon import Icon, IconImage
from enaml.image import Image

from psi import get_config


log = logging.getLogger(__name__)


PREFERENCES_WILDCARD = 'Preferences (*.preferences)'
LAYOUT_WILDCARD = 'Workspace layout (*.layout)'


[docs] def list_preferences(experiment, include_default=False): if not isinstance(experiment, str): experiment = experiment.name p_root = Path(get_config('PREFERENCES_ROOT')) / experiment p_glob = PREFERENCES_WILDCARD[:-1].split('(')[1] matches = p_root.glob(p_glob) if not include_default: matches = [p for p in matches if not p.stem == 'default'] return sorted(Path(p) for p in matches)
[docs] def load_icon(): # Use importlib.resources rather than a `__file__`-relative path so this # keeps working if psi is ever installed/accessed via a loader that # doesn't expose package contents as plain files on disk (e.g., a zipped # install). This does *not* by itself guarantee the file is bundled in a # frozen (PyInstaller) build -- that's handled by psi/__pyinstaller's # hook, which declares this data file to PyInstaller's static analysis. # If, despite that, the icon is missing at runtime, fail soft: a missing # window icon is cosmetic and shouldn't prevent the app from starting. try: data = resources.files('psi.experiment').joinpath('psi-logo.png').read_bytes() except (FileNotFoundError, ModuleNotFoundError): log.warning('Unable to load window icon psi-logo.png', exc_info=True) return Icon(images=[]) image = Image(data=data) icon_image = IconImage(image=image) return Icon(images=[icon_image])
main_icon = load_icon()
[docs] def set_application_icon(icon=None): ''' Make an icon the default for every window of the running application. Setting the icon on the main window alone is not enough. A dialog built without a parent -- such as the popup reporting how an experiment ended, or the error shown when an experiment fails to start -- is a top-level window with a taskbar button of its own, and without an application-wide default it shows Qt's generic window icon. On Windows the taskbar can then show that generic icon for the whole group of psi windows. Parameters ---------- icon : enaml Icon, optional The icon to use. Defaults to `main_icon`, psi's own icon. Notes ----- Call once the Qt application exists (in psi, as soon as the enaml UI plugin has started). Does nothing if there is no application yet. Windows that set their own icon keep it. ''' from enaml.qt.QtWidgets import QApplication from enaml.qt.q_resource_helpers import get_cached_qicon app = QApplication.instance() if app is None: return app.setWindowIcon(get_cached_qicon(main_icon if icon is None else icon))