Source code for schrodinger.ui.qt.style

"""
Module to manage Schrodinger-wide Qt style sheet. The function
apply_style_sheet() will read the


Copyright Schrodinger, LLC. All rights reserved.
"""
#Contributors: Quentin McDonald

import os
import warnings

from schrodinger import get_maestro
from schrodinger.application.utils import find_product_package_dir
from schrodinger.Qt import QtWidgets
from schrodinger.ui.qt import utils as qt_utils
from schrodinger.ui.qt.schrodingerstyle import apply_schrodingerstyle
from schrodinger.ui.qt.schrodingerstyle import \
    get_legacy_spacing_style_sheet_file
from schrodinger.ui.qt.schrodingerstyle import get_schrodinger_style_sheet_file
from schrodinger.ui.qt.schrodingerstyle import read_style_sheet_file
from schrodinger.utils.imputils import import_module_from_file
from schrodinger.ui.qt.standard import panelx_stylesheet

maestro = get_maestro()
if not maestro:
    try:
        _d = find_product_package_dir('maestro', 'schrodinger_maestro')
        import_module_from_file(os.path.join(_d, "maestro_rc.py"))
        del _d
    except (ImportError, IOError):
        warnings.warn(
            "Maestro resources are not found, some images may be missing.",
            RuntimeWarning)

_style_sheet_read = False
_styles_applied = False


[docs]def apply_styles(): global _styles_applied if _styles_applied: return apply_schrodingerstyle() apply_style_sheet(inmodule=True) _styles_applied = True
[docs]def apply_style_sheet(inmodule=False): """ Read the schrodinger-wide style sheet and set that as the Application-level style sheet. If running in Maestro then we don't bother doing that as Maestro will have already performed this operation. :param immodule: True when called from inside style.py. This is the only valid way to call this function :type inmodule: bool """ global _style_sheet_read if not inmodule: msg = "Calling apply_style_sheet directly can result in a runtime " msg += "crash. Call schrodinger.ui.qt.style.apply_styles()." warnings.warn(msg, RuntimeWarning) if maestro: # In Maestro, don't need to do anything as style sheet is already # applied. return if _style_sheet_read: # Already done it, don't need to do it again return _style_sheet_read = True file_name = get_schrodinger_style_sheet_file() style_sheet_text = get_style_sheet_text(file_name) if style_sheet_text is None: return qp = QtWidgets.QApplication.instance() if qp: qp.setStyleSheet(style_sheet_text) return
[docs]def get_style_sheet_text(style_file_name): """ Return the contents of the style sheet file at $SCHRODINGER/mmshare-v*/data/{style_file_name}. :param style_file_name: the name of a .sty file in the mmshare build data directory :type style_file_name: str :return: the contents of the style file, if it can be retrieved :rtype: str or NoneType """ mmshare_exec = os.getenv("MMSHARE_EXEC") if not mmshare_exec: return "Warning: MMSHARE_EXEC is not set, cannot locate style sheet" mmshare_idx = mmshare_exec.rfind('bin') mmshare_path = mmshare_exec[0:mmshare_idx] style_sheet_file = os.path.join(mmshare_path, 'data', style_file_name) status, text, error_msg = read_style_sheet_file(style_sheet_file) if status: return text else: print(error_msg)
[docs]def apply_legacy_spacing_style(widget): """ Attempt to set the legacy spacing style sheet on the supplied widget. :param widget: a widget :type widget: QtWidgets.QWidget """ file_name = get_legacy_spacing_style_sheet_file() style_sheet_text = get_style_sheet_text(file_name) if style_sheet_text is not None: widget.setStyleSheet(style_sheet_text)
[docs]def skip_legacy_spacing_style(widget: QtWidgets.QWidget): """ Instruct the given widget to ignore legacy spacing styling from the legacy spacing style sheet. :param widget: a widget """ widget.setProperty('skip_legacy_styling', True) qt_utils.update_widget_style(widget)
[docs]def apply_panelx_style(widget): """ Apply the PanelX style sheet on the supplied widget and ignore the legacy spacing style sheet. :param widget: a widget :type widget: QtWidgets.QWidget """ widget.setStyleSheet(panelx_stylesheet.STYLESHEET) skip_legacy_spacing_style(widget)
[docs]def apply_panelx_combo_settings(combo_box: QtWidgets.QComboBox): """ Apply necessary settings for PanelX on the given combo box. :param combo_box: A QComboBox """ if not isinstance(combo_box, QtWidgets.QComboBox): raise TypeError(f'Expected {type(combo_box)} to inherit QComboBox.') combo_box.setItemDelegate(QtWidgets.QStyledItemDelegate()) combo_box.setSizeAdjustPolicy(combo_box.AdjustToContents)