Source code for polo.widgets.unit_combo

from PyQt5 import QtCore, QtGui, QtWidgets

from polo import ALLOWED_IMAGE_COUNTS, COLORS, IMAGE_CLASSIFICATIONS, make_default_logger
from polo.crystallography.cocktail import UnitValue
from polo.crystallography.run import HWIRun, Run
from polo.designer.UI_unit_combo import Ui_unitCombo
from polo.utils.math_utils import *

logger = make_default_logger(__name__)


[docs]class UnitComboBox(QtWidgets.QWidget): '''Widget that is a combination of a spinbox and a comboBox that allows a user to select a value using the spinBox and a unit using the comboBox. Example: Lets say we want to create a UnitComboBox that allows someone to select a Molar concentration using micro-molar, milli-molar, centi-molar or molar. .. code-block:: python # create the scaler dictionary s = { 'u': 1e-6, 'm': 1e-3, 'c': 1e-2 } # values are in reference to the base unit unit_combo = UnitComboBox( parent=None, base_unit='M', scalers=s ) :param parent: Parent widget, defaults to None :type parent: QWidget, optional :param base_unit: Base unit string, defaults to None :type base_unit: str, optional :param scalers: Dictionary of prefixes to apply to the baseunit. Keys should be string prefixes and values should be value that scales the baseunit, defaults to {} :type scalers: dict, optional ''' saved_scalers = {'u': 1e-6, 'm': 1e-3, 'c': 1e-2} def __init__(self, parent=None, base_unit=None, scalers={}): super(UnitComboBox, self).__init__(parent) self.ui = Ui_unitCombo() self.ui.setupUi(self) self.base_unit = base_unit self.scalers = scalers # dict @property def scalers(self): '''The current scalers. :return: List of scaler values :rtype: list ''' return self.__scalers @scalers.setter def scalers(self, scaler_list): if scaler_list == self.saved_scalers: self.__scalers = scaler_list else: scalers = {} for each_scaler in scaler_list: if isinstance(each_scaler, (tuple, list)): if len(each_scaler) == 2: scalers[each_scaler[0]] = each_scaler[1] else: continue elif each_scaler in self.saved_scalers: scalers[each_scaler] = self.saved_scalers[each_scaler] self.__scalers = scalers if self.scalers: self._set_unit_combobox_text() @property def sorted_scalers(self): '''Scalers sorted by their magnitude. :return: List of scalers :rtype: list ''' if self.scalers: return sorted( [s for s in self.scalers], key=lambda s: self.scalers[s]) else: return [] @property def unit_combobox_text(self): '''The text in unit comboBox which corresponds to a specific scaler. :return: List of all scalers in the unit comboBox :rtype: list ''' if self.scalers: scaler_text = ['{}{}'.format(s, str(self.base_unit)) for s in self.sorted_scalers] scaler_text.append(str(self.base_unit)) return scaler_text else: logger.warning('Returned empty list at {}'.format(self)) return []
[docs] def _set_unit_combobox_text(self): '''Private method to add units to the unit comboBox based on the `base_unit` and the `scalers` attributes. :return: Items added to the comboBox :rtype: list ''' items = self.unit_combobox_text if items: self.ui.comboBox.addItems(items) self.ui.comboBox.setCurrentIndex(len(items)-1) # set base unit return items
[docs] def unit_text_parser(self, unit_text=None): if not unit_text: unit_text = self.ui.comboBox.currentText() if unit_text: if len(unit_text) > 1: return unit_text[0], unit_text[1:] else: return unit_text
[docs] def get_value(self): '''Return a UnitValue constructed from the value of the spinBox value and unit from the comboBox. :return: UnitValue constructed from current spinBox value and comboBox unit :rtype: UnitValue ''' value = self.ui.doubleSpinBox.value() unit_text = self.ui.comboBox.currentText() return UnitValue(value, unit_text)
[docs] def set_zero(self): '''Set the spinbox value to 0 ''' self.ui.doubleSpinBox.setValue(0.0)
[docs] def set_value(self, value, *args): '''Set the spinBox value and the comboBox unit based on the value and unit of a `UnitValue` instance :param value: UnitValue :type value: UnitValue ''' if isinstance(value, UnitValue): self.ui.doubleSpinBox.setValue(value.value) unit_index = self.ui.comboBox.findText(value.units) self.ui.comboBox.setCurrentIndex(unit_index) else: self.set_zero() logger.warning('Forced to set zero at {}'.format(self))