Source code for taurus.qt.qtgui.base.tauruscontroller

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ###########################################################################
#
# This file is part of Taurus
#
# http://taurus-scada.org
#
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
#
# Taurus is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Taurus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
#
# ###########################################################################

"""This module provides the set of base class taurus controllers.
"""

import weakref

from taurus.external.qt import Qt

from taurus.core.taurusbasetypes import DataFormat, TaurusEventType

from taurus.qt.qtgui.util import QT_ATTRIBUTE_QUALITY_PALETTE
from taurus.qt.qtgui.util import QT_DEVICE_STATE_PALETTE


__docformat__ = "restructuredtext"


[docs]class TaurusBaseController(object): """Base class for all taurus controllers""" def __init__(self, widget, updateAsPalette=True): self._widget = weakref.ref(widget) self._updateAsPalette = updateAsPalette self._stateObj = None self._last_value = None self._last_config_value = None self._last_error_value = None self._setStyle() def _setStyle(self): pass
[docs] def usePalette(self): return self._updateAsPalette
[docs] def widget(self): return self._widget()
[docs] def modelObj(self): return self.widget().getModelObj()
attrObj = configObj = deviceObj = modelObj
[docs] def valueObj(self): value = self._last_value if value is None: modelObj = self.modelObj() if modelObj is None: return None value = modelObj.getValueObj() return value
[docs] def value(self): valueObj = self.valueObj() return getattr(valueObj, "value", None)
[docs] def w_value(self): # TODO: adapt to tep14 valueObj = self.valueObj() return getattr(valueObj, "w_value", None)
[docs] def quality(self): valueObj = self.valueObj() return getattr(valueObj, "quality", None)
[docs] def state(self): return self._stateObj.state
[docs] def getDisplayValue(self, write=False, **kwargs): return self.widget().getDisplayValue(**kwargs)
[docs] def handleEvent(self, evt_src, evt_type, evt_value): # update the "_last" values only if the event source is the model # (it could be the background...) if evt_src == self.modelObj(): if evt_type in (TaurusEventType.Change, TaurusEventType.Periodic): if self._last_value is None: # reset the format so that it gets updated by displayValue self.widget().resetFormat() self._last_value = evt_value elif evt_type == TaurusEventType.Config: # TODO: adapt to tep14 self._last_config_value = evt_value self.widget().resetFormat() else: self._last_error_value = evt_value # In case of error, modify the last_value as well try: self._last_value = self.modelObj().getValueObj() except Exception: self._last_value = None self.update()
[docs] def eventReceived(self, evt_src, evt_type, evt_value): # should handle the state event here. Because this is invoked by a # random thread, we pass it to the widget, which will forward to the # proper thread # @todo: sometimes we get this method called but self.widget() is None. # Check why. For the moment I just protect it by substituting # the following line by the ones after it # self.widget().eventReceived(evt_src, evt_type, evt_value) w = self.widget() if w is not None: w.eventReceived(evt_src, evt_type, evt_value)
[docs] def update(self): widget = self.widget() self._updateConnections(widget) self._updateForeground(widget) self._updateBackground(widget) self._updateToolTip(widget)
def _needsStateConnection(self): return False def _updateConnections(self, widget): stateObj, newStateObj = self._stateObj, None if self._needsStateConnection(): newStateObj = self.deviceObj() if stateObj != newStateObj: if stateObj is not None: stateObj.removeListener(self) if newStateObj is not None: newStateObj.addListener(self) else: if stateObj is not None: stateObj.removeListener(self) self._stateObj = newStateObj def _updateForeground(self, widget): pass def _updateBackground(self, widget): pass def _updateToolTip(self, widget): if widget.getAutoTooltip(): widget.setToolTip(widget.getFormatedToolTip())
[docs]class TaurusAttributeControllerHelper(object):
[docs] def configObj(self): return self.attrObj() # they are the same object since tep14
# attrObj = self.attrObj() # if attrObj is None: return None # return attrObj.getConfig()
[docs] def deviceObj(self): attrObj = self.attrObj() if attrObj is None: return None return attrObj.getParentObj()
[docs]class TaurusScalarAttributeControllerHelper(TaurusAttributeControllerHelper):
[docs] def getDisplayValue(self, write=False, **kwargs): valueObj = self.valueObj() widget = self.widget() if valueObj is None or valueObj.rvalue is None: return widget.getDisplayValue(**kwargs) format = self.attrObj().data_format if format == DataFormat._0D: return self._getDisplayValue(widget, valueObj, None, write) idx = widget.getModelIndexValue() return self._getDisplayValue(widget, valueObj, idx, write)
def _getDisplayValue(self, widget, valueObj, idx, write): try: if write: value = valueObj.wvalue else: value = valueObj.rvalue if idx is not None and len(idx): for i in idx: value = value[i] return widget.displayValue(value) except Exception: return widget.getNoneValue()
[docs] def displayValue(self, value): if value is None: return None ret = None try: if self.isScalar(): format = self.getFormat() if self.isNumeric() and format is not None: format = self.getFormat() ret = self.getFormat() % value else: ret = str(value) elif self.isSpectrum(): ret = str(value) else: ret = str(value) except Exception: # if cannot calculate value based on the format just return the # value raise ret = str(value) return ret
[docs]class TaurusConfigurationControllerHelper(object): # TODO: Check if this is used. If so, rename to avoid "Configuration" def __init__(self): self._configParam = None
[docs] def attrObj(self): return self.configObj() # they are the same object since tep14
[docs] def deviceObj(self): attrObj = self.attrObj() if attrObj is None: return None return attrObj.getParentObj()
@property def configParam(self): if self._configParam is None: self._configParam = self.widget().modelFragmentName or "" return self._configParam
[docs] def getDisplayValue(self, write=False, **kwargs): widget = self.widget() model = self.getModelObj(**kwargs) if model is None: return widget.getNoneValue() param = self.configParam try: val = widget.getModelFragmentObj(**kwargs) try: no_val = getattr(model, "no_" + param) # TODO: Tango-centric if val.lower() == no_val.lower(): val = widget.getNoneValue() except Exception: pass except AttributeError: if param: val = str(param) attr = self.attrObj() if attr is not None: val = val.replace("<label>", attr.label or "---") val = val.replace("<attr_name>", attr.name or "---") val = val.replace( "<attr_fullname>", attr.getFullName() or "---" ) dev = self.deviceObj() if dev is not None: val = val.replace( "<dev_fullname>", dev.getFullName() or "---" ) val = val.replace( "<dev_alias>", dev.getSimpleName() or "---" ) val = val.replace( "<dev_name>", dev.getNormalName() or "---" ) else: val = widget.getNoneValue() except Exception: widget.debug("Invalid configuration parameter '%s'" % param) val = widget.getNoneValue() if val is None: val = widget.getNoneValue() return val
StyleSheetTemplate = """border-style: outset; border-width: 2px; border-color: {0}; {1} """ def _updatePaletteColors(widget, bgBrush, fgBrush, frameBrush): qt_palette = widget.palette() qt_palette.setBrush(Qt.QPalette.Window, bgBrush) qt_palette.setBrush(Qt.QPalette.Base, bgBrush) qt_palette.setBrush(Qt.QPalette.WindowText, fgBrush) qt_palette.setBrush(Qt.QPalette.Light, frameBrush) qt_palette.setBrush(Qt.QPalette.Dark, frameBrush) widget.setPalette(qt_palette)
[docs]def updateLabelBackground(ctrl, widget): """Helper method to setup background of taurus labels and lcds""" bgRole = widget.bgRole if ctrl.usePalette(): widget.setAutoFillBackground(True) if bgRole in ("", "none", "None"): transparentBrush = Qt.QBrush(Qt.Qt.transparent) frameBrush = transparentBrush bgBrush, fgBrush = transparentBrush, Qt.QBrush(Qt.Qt.black) else: frameBrush = Qt.QBrush(Qt.QColor(255, 255, 255, 128)) bgItem, palette = None, QT_DEVICE_STATE_PALETTE if bgRole == "quality": palette = QT_ATTRIBUTE_QUALITY_PALETTE bgItem = ctrl.quality() elif bgRole == "state": try: bgItem = ctrl.state() except AttributeError: pass # protect against calls with state not instantiated elif bgRole == "value": bgItem = ctrl.value() else: # TODO: this is an *experimental* extension of the bgRole API # added in v 4.1.2-alpha. It may change in future versions modelObj = widget.getModelObj() try: bgItem = modelObj.getFragmentObj(bgRole) except Exception: widget.warning('Invalid bgRole "%s"', bgRole) bgBrush, fgBrush = palette.qbrush(bgItem) _updatePaletteColors(widget, bgBrush, fgBrush, frameBrush) else: if bgRole in ("", "none", "None"): ss = StyleSheetTemplate.format("rgba(0,0,0,0)", "") else: bgItem, palette = None, QT_DEVICE_STATE_PALETTE if bgRole == "quality": palette = QT_ATTRIBUTE_QUALITY_PALETTE bgItem = ctrl.quality() elif bgRole == "state": bgItem = ctrl.state() elif bgRole == "value": bgItem = ctrl.value() else: # TODO: this is an *experimental* extension of the bgRole API # added in v 4.1.2-alpha. It may change in future versions modelObj = widget.getModelObj() try: bgItem = modelObj.getFragmentObj(bgRole) except Exception: widget.warning('Invalid bgRole "%s"', bgRole) color_ss = palette.qtStyleSheet(bgItem) ss = StyleSheetTemplate.format("rgba(255,255,255,128)", color_ss) widget.setStyleSheet(ss) widget.update() # necessary in pyqt <= 4.4