Changeset 1596


Ignore:
Timestamp:
Dec 3, 2014 5:25:41 PM (8 years ago)
Author:
jemian
Message:

add RBV widget, other UI corrections

Location:
bcdaqwidgets/trunk/src/bcdaqwidgets
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • bcdaqwidgets/trunk/src/bcdaqwidgets/__init__.py

    r1451 r1596  
    1414__project__     = u'BcdaQWidgets'
    1515__description__ = u"PyEpics-aware PySide widgets for the APS."
    16 __copyright__   = u'2009-2013, UChicago Argonne, LLC'
     16__copyright__   = u'2009-2014, UChicago Argonne, LLC'
    1717__authors__     = [u'Pete Jemian', u'Cayla Suarez']
    1818__institution__ = u"Advanced Photon Source, Argonne National Laboratory"
     
    2525
    2626__yyyymmdd__      = str(datetime.datetime.now()).split()[0]
    27 __version__       = u"0.1.1"
     27__version__       = u"0.1.2"
    2828__minor_version__ = u""
    2929__svnid__         = u"$Id$"
  • bcdaqwidgets/trunk/src/bcdaqwidgets/bcdaqwidgets.py

    r1451 r1596  
    1515See LICENSE file for details.
    1616
    17 The bcdaqwidgets [#]_ module provides a set of PySide (also Qt4)
     17The bcdaqwidgets [#]_ module provides a set of PySide (also PyQt4)
    1818widgets that are EPICS-aware.  These include:
    1919
     
    2121widget                         description
    2222=============================  ================================================================
    23 :func:`BcdaQLabel`             EPICS-aware QLabel widget
    24 :func:`BcdaQLineEdit`          EPICS-aware QLineEdit widget
    25 :func:`BcdaQPushButton`        EPICS-aware QPushButton widget
    26 :func:`BcdaQMomentaryButton`   sends a value when pressed or released, label does not change
    27 :func:`BcdaQToggleButton`      toggles boolean PV when pressed
     23:class:`BcdaQLabel`            EPICS-aware QLabel widget
     24:class:`BcdaQLineEdit`         EPICS-aware QLineEdit widget
     25:class:`BcdaQPushButton`       EPICS-aware QPushButton widget
     26:class:`BcdaQMomentaryButton`  sends a value when pressed or released, label does not change
     27:class:`BcdaQToggleButton`     toggles boolean PV when pressed
     28:class:`RBV_BcdaQLabel`        makes motor RBV field background green when motor is moving
    2829=============================  ================================================================
    2930
     
    7576SeverityColor.MAJOR =        "red"          # red
    7677SeverityColor.CALC_INVALID = "pink"         # pink
     78
     79BACKGROUND_DEFAULT = '#efefef'
     80BACKGROUND_DONE_MOVING = BACKGROUND_DEFAULT
     81BACKGROUND_MOVING = 'lightgreen'
     82DMOV_COLOR_TABLE = {1: BACKGROUND_DONE_MOVING, 0: BACKGROUND_MOVING}
     83
     84BLANKS = ' '*4
    7785
    7886
     
    111119        '''change specified styles and apply all to widget'''
    112120        self._updateCache(sty)
    113         self.widget.setStyleSheet(str(self))
     121        if self.widget is not None:
     122            self.widget.setStyleSheet(str(self))
    114123
    115124    def _updateCache(self, sty={}):
     
    137146    newFgColor = pyqtSignal()
    138147    newBgColor = pyqtSignal()
    139     newText    = pyqtSignal()
     148    newText    = pyqtSignal(str)
     149    dmov       = pyqtSignal(int)
    140150
    141151
     
    145155    def __init__(self, pvname=None, useAlarmState=False):
    146156        self.style_dict = {}
    147         self.text_cache = ' ' * 4
    148157        self.pv = None                           # PyEpics PV object
    149158        self.ca_callback = None
     
    188197            self.ca_connect_callback = None
    189198            self.state = AllowedStates.DISCONNECTED
    190             self.text_cache = ' ' * 4
    191             self.SetText()
     199            self.SetText(BLANKS)
    192200            self.SetBackgroundColor()
    193201            self.setToolTip(pvname + ' not connected')
     
    196204        '''respond to a PyEpics CA connection event'''
    197205        conn = kw['conn']
    198         self.text_cache = {      # adjust the text
    199                           False: '',    #'disconnected',
    200                           True:  'connected',
    201                       }[conn]
    202         self.labelSignal.newText.emit()      # threadsafe update of the widget
    203206        self.state = {      # adjust the state
    204207                          False: AllowedStates.DISCONNECTED,
     
    212215    def onPVChange(self, pvname=None, char_value=None, **kw):
    213216        '''respond to a PyEpics camonitor() event'''
    214         self.text_cache = char_value         # cache the new text locally
    215         self.labelSignal.newText.emit()      # threadsafe update of the widget
     217        self.labelSignal.newText.emit(char_value)      # threadsafe update of the widget
    216218        if self.ca_callback is not None:
    217219            # caller wants to be notified of this camonitor event
    218220            self.ca_callback(pvname=pvname, char_value=char_value, **kw)
    219221
    220     def SetText(self, *args, **kw):
     222    def SetText(self, text, *args, **kw):
    221223        '''set the text of the widget (threadsafe update)'''
    222224        # pull the new text from the cache (set by onPVChange() method)
    223         self.setText(self.text_cache)
     225        self.setText(text)
    224226
    225227        # if desired, color the text based on the alarm severity
     
    257259   
    258260    '''
     261    css = {
     262           'background-color': 'bisque',
     263           'border': '1px solid gray',
     264           'font': 'bold',
     265           }
    259266
    260267    def __init__(self, pvname=None, useAlarmState=False, bgColorPv=None):
    261268        ''':param str text: initial Label text (really, we can ignore this)'''
    262269        BcdaQWidgetSuper.__init__(self, useAlarmState=useAlarmState)
    263         QtGui.QLabel.__init__(self, self.text_cache)
     270        QtGui.QLabel.__init__(self, BLANKS)
    264271
    265272        # define the signals we'll use in the camonitor handler to update the GUI
     
    268275        self.labelSignal.newText.connect(self.SetText)
    269276
    270         self.updateStyleSheet({
    271                                'background-color': 'bisque',
    272                                'border': '1px solid gray',
    273                                'font': 'bold',
    274                                })
     277        self.updateStyleSheet(self.css)
    275278
    276279        self.clut = dict(CLUT)
     
    331334
    332335    '''
     336    css = {
     337           'background-color': 'bisque',
     338           'border': '3px inset gray',
     339           }
    333340
    334341    def __init__(self, pvname=None, useAlarmState=False):
    335342        ''':param str text: initial Label text (really, we can ignore this)'''
    336343        BcdaQWidgetSuper.__init__(self)
    337         QtGui.QLineEdit.__init__(self, self.text_cache)
     344        QtGui.QLineEdit.__init__(self, BLANKS)
    338345
    339346        # define the signals we'll use in the camonitor handler to update the GUI
     
    343350        self.clut = dict(CLUT)
    344351        self.clut[AllowedStates.CONNECTED] = "bisque"
    345         self.updateStyleSheet({
    346                                'background-color': 'bisque',
    347                                'border': '3px inset gray',
    348                                })
     352        self.updateStyleSheet(self.css)
    349353
    350354        self.SetBackgroundColor()
     
    386390   
    387391    '''
     392    css = {'font': 'bold',}
    388393
    389394    def __init__(self, label='', pvname=None):
    390395        ''':param str text: initial Label text (really, we can ignore this)'''
    391396        BcdaQWidgetSuper.__init__(self)
    392         QtGui.QPushButton.__init__(self, self.text_cache)
    393         self.setText(label)
     397        QtGui.QPushButton.__init__(self, label)
    394398
    395399        self.labelSignal = BcdaQSignalDef()
     
    398402
    399403        self.clut = dict(CLUT)
    400         self.updateStyleSheet({'font': 'bold',})
     404        self.updateStyleSheet(self.css)
    401405
    402406        self.pv = None
     
    520524
    521525
     526class RBV_BcdaQLabel(BcdaQLabel):
     527    '''
     528    makes motor readback field (BcdaQLabel) background green when motor is moving
     529   
     530    EXAMPLE::
     531
     532        pvname = 'ioc:m1'
     533        w = bcdaqwidgets.RBV_BcdaQLabel()
     534        layout.addWidget(w)
     535        w.ca_connect(pvname+'.RBV')
     536
     537    '''
     538   
     539    def __init__(self, *args):
     540        super(RBV_BcdaQLabel, self).__init__(*args)
     541        self.sty = StyleSheet(self)
     542        self.signal = BcdaQSignalDef()
     543        self.dmov = None
     544   
     545    def ca_connect(self, rbv_pv):
     546        dmov_pv = rbv_pv.split('.')[0] + '.DMOV'
     547        super(RBV_BcdaQLabel, self).ca_connect(rbv_pv)
     548        self.dmov = epics.PV(dmov_pv, callback=self.dmov_callback)
     549        self.signal.dmov.connect(self.setBackgroundColor)
     550   
     551    def dmov_callback(self, *args, **kw):
     552        # called in PyEpics thread
     553        self.signal.dmov.emit(kw['value'])
     554   
     555    def setBackgroundColor(self, value):
     556        # called in GUI thread
     557        color = DMOV_COLOR_TABLE[value]
     558        self.sty.updateStyleSheet({'background-color': color})
     559
     560
    522561#------------------------------------------------------------------
    523562
     
    531570    '''
    532571
    533     def __init__(self, parent=None, pvname=None, bgColorPvname=None):
     572    def __init__(self, parent=None, pvname=None):
    534573        QtGui.QWidget.__init__(self, parent)
    535 
    536         layout = QtGui.QGridLayout()
    537         layout.addWidget(QtGui.QLabel('BcdaQLabel'), 0, 0)
    538         self.value = BcdaQLabel()
    539         layout.addWidget(self.value, 0, 1)
    540         self.setLayout(layout)
    541574
    542575        self.sig = BcdaQSignalDef()
     
    544577        self.toggle = False
    545578
     579        layout = QtGui.QFormLayout()
     580        self.setLayout(layout)
     581
     582        lbl  = QtGui.QLabel('PV')
     583        wid = QtGui.QLabel(str(pvname))
     584        layout.addRow(lbl, wid)
     585
     586        self.value = BcdaQLabel()
     587        layout.addRow(QtGui.QLabel('BcdaQLabel'), self.value)
     588
    546589        self.setWindowTitle("Demo bcdaqwidgets module")
    547590        if pvname is not None:
    548591            self.ca_connect(pvname)
    549592
    550             layout.addWidget(QtGui.QLabel('BcdaQLabel with alarm colors'), 1, 0)
    551             layout.addWidget(BcdaQLabel(pvname=pvname, useAlarmState=True), 1, 1)
    552 
    553             pvnameBg = pvname.split('.')[0] + '.DMOV'
    554             lblWidget = BcdaQLabel(pvname=pvname, bgColorPvname=pvnameBg)
    555             layout.addWidget(QtGui.QLabel('BcdaQLabel with BG color change due to moving motor'), 2, 0)
    556             layout.addWidget(lblWidget, 2, 1)
    557 
    558             layout.addWidget(QtGui.QLabel('BcdaQLineEdit'), 3, 0)
    559             layout.addWidget(BcdaQLineEdit(pvname=pvname), 3, 1)
     593            lbl = QtGui.QLabel('BcdaQLabel with alarm colors')
     594            wid = BcdaQLabel(pvname=pvname, useAlarmState=True)
     595            layout.addRow(lbl, wid)
     596
     597            lbl = QtGui.QLabel('RBV_BcdaQLabel')
     598            wid = RBV_BcdaQLabel()
     599            wid.ca_connect(pvname+'.RBV')
     600            layout.addRow(lbl, wid)
     601
     602            lbl = QtGui.QLabel('BcdaQLineEdit')
     603            wid = BcdaQLineEdit(pvname=pvname)
     604            layout.addRow(lbl, wid)
    560605
    561606            pvname = pvname.split('.')[0] + '.PROC'
    562             widget = BcdaQMomentaryButton(label=pvname, pvname=pvname)
    563             layout.addWidget(QtGui.QLabel('BcdaQMomentaryButton'), 4, 0)
    564             layout.addWidget(widget, 4, 1)
     607            lbl = QtGui.QLabel('BcdaQMomentaryButton')
     608            wid = BcdaQMomentaryButton(label=pvname, pvname=pvname)
     609            layout.addRow(lbl, wid)
    565610
    566611    def ca_connect(self, pvname):
     
    592637                        nargs='?',
    593638                        help="EPICS PV name",
    594                         default="prj:m1.RBV",
     639                        default="prj:m1",
    595640                        )
    596641    results = parser.parse_args()
Note: See TracChangeset for help on using the changeset viewer.