Files
ecmc_plugin_motion/tools/ecmcOneMotorGUI.py

787 lines
28 KiB
Python

#!/usr/bin/env python3.6
import epics
import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
#from PyQt5 import QtWidgets, QtGui, QtCore
from ecmcArrayStat import *
#Define pvs
# Axis
ECMC_PV_AXIS_DIAG_ARRAY_SUFFIX = '-Arr-Stat'
ECMC_PV_AXIS_ERROR_RESET_SUFFIX = '-ErrRst'
# Controller
ECMC_PV_CNTROLLER_ERROR_ID_SUFFIX = 'MCU-ErrId'
ECMC_PV_CNTROLLER_ERROR_MSG_SUFFIX = 'MCU-ErrMsg'
ECMC_PV_CNTROLLER_ERROR_RESET_SUFFIX = 'MCU-ErrRst'
ECMC_PV_CNTROLLER_ERROR_CND_SUFFIX = 'MCU-Cmd'
BLANK = ' '*4
BACKGROUND_DEFAULT = '#efefef'
#BACKGROUND_DONE_MOVING = 'beige'
BACKGROUND_DONE_MOVING = BACKGROUND_DEFAULT
BACKGROUND_MOVING = 'lightgreen'
BACKGROUND_LVIO_ON = 'yellow'
BACKGROUND_LIMIT_ON = 'red'
TOOLTIPS = {
'DESC': 'DESC: short description',
'NAME': 'NAME: EPICS PV name',
'RBV': 'RBV: motor readback value',
'VAL': 'VAL: motor target value',
'EGU': 'EGU: engineering units',
'STOP': 'STOP: command this motor to stop moving',
'TWV': 'TWV: tweak value',
'TWF': 'TWF: increment motor by tweak value',
'TWR': 'TWR: decrement motor by tweak value',
'*10': 'multiply tweak value by 10',
'/10': 'divide tweak value by 10',
'CNEN': 'enable/disable drive',
'ArrayStat': 'axis Status',
'ErrRst': 'reset axis error',
'JOGR': 'JOGR: jog backward',
'JOGF': 'JOGF: jog forward',
'HOMR': 'HOMR: Home reverse',
'HOMF': 'HOMF: Home forward',
'MSTA': 'MSTA: Status',
'JVEL': 'JVEL: Jog velocity',
'VELO': 'VELO: Velocity (positioning)'
}
STYLES = { ### http://doc.qt.digia.com/qt/stylesheet-reference.html
'self': '''
MotorPanel {
border-style: solid;
border-color: black;
border-width: 1px;
}
''',
'DESC': '''
QLabel {
qproperty-alignment: AlignRight;
font: bold;
}
''',
'NAME': '''
QLabel {
qproperty-alignment: AlignRight;
font: bold;
}
''',
'RBV': '''
QLabel {
qproperty-alignment: AlignRight;
}
''',
'EGU': '''
QLabel {
qproperty-alignment: AlignRight;
}
''',
'VAL': '''
QLineEdit {
background-color: white;
text-align: right;
}
''',
'STOP': '''
QPushButton {
background-color: red;
color: black;
text-align: center;
height: 50px;
min-height: 50px;
max-height: 50px;
}
QPushButton:hover {
background-color: red;
color: yellow;
font: bold;
text-align: center;
}
''',
'CNEN': '''
QPushButton {
background-color: red;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
QPushButton:hover {
background-color: red;
color: yellow;
font: bold;
text-align: center;
}
''',
'BUTTON_ON': '''
QPushButton {
background-color: green;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
QPushButton:hover {
background-color: green;
color: yellow;
font: bold;
text-align: center;
}
''',
'TWV': '''
QLineEdit {
background-color: white;
text-align: right;
width: 80px;
min-width: 80px;
max-width: 80px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'TWF': '''
QPushButton {
width: 40px;
min-width: 40px;
max-width: 40px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'TWR': '''
QPushButton {
width: 40px;
min-width: 40px;
max-width: 40px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'*10': '''
QPushButton {
width: 40px;
min-width: 40px;
max-width: 40px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'/10': '''
QPushButton {
width: 40px;
min-width: 40px;
max-width: 40px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'ArrayStat': '''
QTableView {
background-color: white;
font: bold;
width: 350px;
min-width: 350px;
max-width: 350px;
font-size:10pt;
height:770px;
min-height:770px;
max-height:770px;
}
''',
'ErrRst': '''
QPushButton {
background-color: red;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
QPushButton:hover {
background-color: red;
color: yellow;
font: bold;
text-align: center;
}
''',
'JOGR': '''
QPushButton {
background-color: grey;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'JOGF': '''
QPushButton {
background-color: grey;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'HOMR': '''
QPushButton {
background-color: grey;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'HOMF': '''
QPushButton {
background-color: grey;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'MSTA': '''
QLabel {
text-align: right;
}
''',
'PLOT': '''
QPushButton {
background-color: grey;
color: black;
text-align: center;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'VELO': '''
QLineEdit {
background-color: white;
text-align: right;
width: 80px;
min-width: 80px;
max-width: 80px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
'JVEL': '''
QLineEdit {
background-color: white;
text-align: right;
width: 80px;
min-width: 80px;
max-width: 80px;
height: 40px;
min-height: 40px;
max-height: 40px;
}
''',
}
class MotorPanel(QtWidgets.QDialog):
def __init__(self, parent=None,iocPrefix=None,axisName=None):
super(MotorPanel, self).__init__(parent)
QtWidgets.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
self.motorPv = None
self.motorPvName = ""
self.axisDiagPvName=""
self.axisErrorResetPv = None
self.axisErrorResetPvName = ""
self.cntrlErrorIdPv = None
self.cntrlErrorIdPvName = ""
self.cntrlErrorResetPv = None
self.cntrlErrorResetPvName = ""
self.cntrlErrorMsgPv = None
self.cntrlErrorMsgPvName = ""
self.cntrlErrorMsg=""
self.cntrlCmdPv = None
self.cntrlCmdPvName = ""
self.create_GUI()
self.apply_styles()
self.create_actions()
if isinstance(axisName, str) and isinstance(iocPrefix, str):
self.connect(iocPrefix,axisName)
def create_GUI(self):
'''define controls AND set the layout'''
self.controls = {}
for field in ['DESC', 'NAME', 'EGU', 'RBV']:
self.controls[field] = QtWidgets.QLabel(BLANK)
self.controls['VAL'] = QtWidgets.QLineEdit()
self.controls['STOP'] = QtWidgets.QPushButton('STOP',default=False, autoDefault=False)
self.controls['TWF'] = QtWidgets.QPushButton('>>',default=False, autoDefault=False)
self.controls['TWV'] = QtWidgets.QLineEdit()
self.controls['TWR'] = QtWidgets.QPushButton('<<',default=False, autoDefault=False)
self.controls['*10'] = QtWidgets.QPushButton('*10',default=False, autoDefault=False)
self.controls['/10'] = QtWidgets.QPushButton('/10',default=False, autoDefault=False)
self.controls['CNEN'] = QtWidgets.QPushButton('CNEN',default=False, autoDefault=False)
self.controls['ArrayStat']=ecmcArrayStat(self)
self.controls['JVEL'] = QtWidgets.QLineEdit()
self.controls['VELO'] = QtWidgets.QLineEdit()
self.controls['ErrRst'] = QtWidgets.QPushButton('Reset Error',default=False, autoDefault=False)
self.controls['JOGR'] = QtWidgets.QPushButton('JOGR',default=False, autoDefault=False)
self.controls['JOGF'] = QtWidgets.QPushButton('JOGF',default=False, autoDefault=False)
self.controls['HOMR'] = QtWidgets.QPushButton('HOMR',default=False, autoDefault=False)
self.controls['HOMF'] = QtWidgets.QPushButton('HOMF',default=False, autoDefault=False)
self.controls['PLOT'] = QtWidgets.QPushButton('Plot',default=False, autoDefault=False)
self.controls['MSTA'] = QtWidgets.QLabel()
self.controls['RBV'].setAutoFillBackground(True)
self.setLabelBackground(self.controls['RBV'], BACKGROUND_DONE_MOVING)
main_frame= QtWidgets.QFrame(self)
main_layout = QtWidgets.QHBoxLayout()
left_frame = QtWidgets.QFrame(self)
left_layout = QtWidgets.QVBoxLayout()
for field in ['NAME','DESC', 'EGU', 'RBV', 'VAL','VELO','MSTA']:
tmp_frame = QtWidgets.QFrame(self)
tmp_layout = QtWidgets.QHBoxLayout()
tmp_label=QtWidgets.QLabel()
tmp_label.setText(field+ ':')
tmp_layout.addWidget(tmp_label)
tmp_layout.addWidget(self.controls[field])
tmp_frame.setLayout(tmp_layout)
left_layout.addWidget(tmp_frame)
#Tweak
tweak_label= QtWidgets.QLabel()
tweak_label.setText('TWEAK:')
left_layout.addWidget(tweak_label)
tweak_frame = QtWidgets.QFrame(self)
tweak_layout = QtWidgets.QHBoxLayout()
for field in ['TWR', '/10', 'TWV', '*10', 'TWF']:
tweak_layout.addWidget(self.controls[field])
tweak_frame.setLayout(tweak_layout)
left_layout.addWidget(tweak_frame)
#Jog
jog_label= QtWidgets.QLabel()
jog_label.setText('JOG:')
left_layout.addWidget(jog_label)
jvel_frame = QtWidgets.QFrame(self)
jvel_layout = QtWidgets.QHBoxLayout()
jvel_label=QtWidgets.QLabel()
jvel_label.setText('JVEL' + ':')
jvel_layout.addWidget(jvel_label)
jvel_layout.addWidget(self.controls['JVEL'])
jvel_frame.setLayout(jvel_layout)
left_layout.addWidget(jvel_frame)
jog_frame = QtWidgets.QFrame(self)
jog_layout = QtWidgets.QHBoxLayout()
jog_layout.addWidget(self.controls['JOGR'])
jog_layout.addWidget(self.controls['JOGF'])
jog_frame.setLayout(jog_layout)
left_layout.addWidget(jog_frame)
#Home
home_label= QtWidgets.QLabel()
home_label.setText('HOME:')
left_layout.addWidget(home_label)
home_frame = QtWidgets.QFrame(self)
home_layout = QtWidgets.QHBoxLayout()
home_layout.addWidget(self.controls['HOMR'])
home_layout.addWidget(self.controls['HOMF'])
home_frame.setLayout(home_layout)
left_layout.addWidget(home_frame)
control_label= QtWidgets.QLabel()
control_label.setText('CONTROL:')
left_layout.addWidget(control_label)
left_layout.addWidget(self.controls['STOP'])
left_layout.addWidget(self.controls['CNEN'])
left_layout.addWidget(self.controls['ErrRst'])
left_frame.setLayout(left_layout)
main_layout.addWidget(left_frame)
right_frame = QtWidgets.QFrame(self)
right_layout = QtWidgets.QVBoxLayout()
right_layout.addWidget(self.controls['ArrayStat'])
right_layout.addWidget(self.controls['PLOT'])
right_frame.setLayout(right_layout);
main_layout.addWidget(right_frame)
main_frame.setLayout(main_layout)
self.setLayout(main_layout)
self.setWindowTitle("ecmc: axis control")
def apply_styles(self):
'''apply styles and tips'''
for field in ['DESC', 'NAME', 'EGU', 'RBV', 'VAL',
'STOP','CNEN','TWV', 'TWF', 'TWR', '*10',
'/10','ArrayStat','ErrRst','JOGR','JOGF',
'HOMR','HOMF','MSTA','JVEL','VELO']:
if field in STYLES:
self.controls[field].setStyleSheet(STYLES[field])
if field in TOOLTIPS:
self.controls[field].setToolTip(TOOLTIPS[field])
self.setStyleSheet(STYLES['self'])
def create_actions(self):
'''define actions'''
self.controls['VAL'].returnPressed.connect(self.onReturnVAL)
self.controls['VELO'].returnPressed.connect(self.onReturnVELO)
self.controls['TWV'].returnPressed.connect(self.onReturnTWV)
self.controls['TWR'].clicked.connect(self.onPushTWR)
self.controls['TWF'].clicked.connect(self.onPushTWF)
self.controls['*10'].clicked.connect(self.onPush10x)
self.controls['/10'].clicked.connect(self.onPush_1x)
self.controls['STOP'].clicked.connect(self.onPushSTOP)
self.controls['CNEN'].clicked.connect(self.onPushCNEN)
self.controls['ErrRst'].clicked.connect(self.onPushErrRst)
self.controls['JVEL'].returnPressed.connect(self.onReturnJVEL)
self.controls['JOGR'].clicked.connect(self.onPushJOGR)
self.controls['JOGF'].clicked.connect(self.onPushJOGF)
self.controls['HOMR'].clicked.connect(self.onPushHOMR)
self.controls['HOMF'].clicked.connect(self.onPushHOMF)
self.controls['PLOT'].clicked.connect(self.onPushPLOT)
def setPvNames(self,iocPrefix=None,axisName=None):
self.motorPvName = (iocPrefix + axisName).split('.')[0] # keep everything to left of first dot
self.axisDiagPvName = self.motorPvName + ECMC_PV_AXIS_DIAG_ARRAY_SUFFIX
self.axisErrorResetPvName = self.motorPvName + ECMC_PV_AXIS_ERROR_RESET_SUFFIX
self.cntrlErrorIdPvName = iocPrefix + ECMC_PV_CNTROLLER_ERROR_ID_SUFFIX
self.cntrlErrorResetPvName = iocPrefix + ECMC_PV_CNTROLLER_ERROR_RESET_SUFFIX
self.cntrlErrorMsgPvName = iocPrefix + ECMC_PV_CNTROLLER_ERROR_MSG_SUFFIX
self.cntrlCmdPvName = iocPrefix + ECMC_PV_CNTROLLER_ERROR_CND_SUFFIX
def connect(self, iocPrefix=None,axisName=None):
'''connect this panel with an EPICS motor PV'''
if iocPrefix is None:
raise RuntimeError("iocPrefix must not be 'None'")
if axisName is None:
raise RuntimeError("axisName must not be 'None'")
self.setPvNames(iocPrefix,axisName)
if len(iocPrefix) == 0 or len(axisName) == 0:
raise RuntimeError("iocPrefix or axisName must not be ''")
if self.motorPv is not None:
self.disconnect()
self.controls['NAME'].setText(self.motorPvName)
self.motorPv = epics.Motor(self.motorPvName) # verifies that self.motor_pv has RTYP='motor'
callback_dict = {
#field: callback function
'DESC': self.onChangeDESC,
'EGU': self.onChangeEGU,
'RBV': self.onChangeRBV,
'VAL': self.onChangeVAL,
'VELO': self.onChangeVELO,
'TWV': self.onChangeTWV,
'DMOV': self.onChangeDMOV,
'HLS': self.onChangeHLS,
'LLS': self.onChangeLLS,
'CNEN': self.onChangeCNEN,
'JOGR': self.onChangeJOGR,
'JOGF': self.onChangeJOGF,
'JVEL': self.onChangeJVEL,
'HOMR': self.onChangeHOMR,
'HOMF': self.onChangeHOMF,
'MSTA': self.onChangeMSTA,
}
for field, func in callback_dict.items():
self.motorPv.set_callback(attr=field, callback=func)
self.controls['DESC'].setText(self.motorPv.description)
self.controls['EGU'].setText(self.motorPv.units)
# display initial values
self.onChangeRBV(value=self.motorPv.get('RBV'))
self.onChangeVAL(value=self.motorPv.get('VAL'))
self.onChangeTWV(value=self.motorPv.get('TWV'))
self.onChangeDMOV(value=self.motorPv.get('DMOV'))
self.onChangeCNEN(value=self.motorPv.get('CNEN'))
self.onChangeJOGR(value=self.motorPv.get('JOGR'))
self.onChangeJOGF(value=self.motorPv.get('JOGF'))
self.onChangeHOMR(value=self.motorPv.get('HOMR'))
self.onChangeHOMF(value=self.motorPv.get('HOMF'))
self.onChangeMSTA(value=self.motorPv.get('MSTA'))
self.onChangeVELO(value=self.motorPv.get('VELO'))
self.onChangeJVEL(value=self.motorPv.get('JVEL'))
# additional records
self.axisErrorResetPv = epics.PV(self.axisErrorResetPvName)
self.cntrlErrorIdPv = epics.PV(self.cntrlErrorIdPvName)
self.cntrlErrorIdPv.add_callback(self.onChangeCntrlErrorIdPv)
self.cntrlErrorResetPv = epics.PV(self.cntrlErrorResetPvName)
self.cntrlErrorMsgPv = epics.PV(self.cntrlErrorMsgPvName)
self.cntrlCmdPv = epics.PV(self.cntrlCmdPvName)
self.cntrlCmdPv.add_callback(self.onChangeCntrlCmdPv)
if self.controls['ArrayStat'] is not None:
self.controls['ArrayStat'].connect(self.axisDiagPvName)
def disconnect(self):
'''disconnect this panel from EPICS'''
if self.motorPv is not None:
for field in ['VAL', 'RBV', 'DESC', 'EGU', 'TWV', 'DMOV', 'HLS', 'LLS']:
self.motorPv.clear_callback(attr=field)
self.motorPv = None
for field in ['DESC', 'NAME', 'EGU', 'RBV', 'VAL', 'TWV']:
self.controls[field].setText(BLANK)
if self.cntrlErrorIdPv is not None:
self.cntrlErrorIdPv.clear_callbacks()
if self.cntrlCmdPv is not None:
self.cntrlCmdPv.clear_callbacks()
if self.controls['ArrayStat'] is not None:
self.controls['ArrayStat'].disconnect()
def closeEvent(self, event):
'''be sure to disconnect from EPICS when closing'''
self.disconnect()
def onPushSTOP(self):
'''stop button was pressed'''
if self.motorPv is not None:
self.motorPv.stop()
def onPushCNEN(self):
'''cnen button was pressed'''
if self.motorPv is not None:
self.motorPv.put('CNEN',not self.motorPv.get('CNEN'))
def onPushErrRst(self):
'''ErrRst button was pressed'''
if self.axisErrorResetPv is not None:
self.axisErrorResetPv.put(1)
def onPushJOGR(self):
'''jogr button was pressed'''
if self.motorPv is not None:
self.motorPv.put('JOGR',not self.motorPv.get('JOGR'))
def onPushJOGF(self):
'''jogf button was pressed'''
if self.motorPv is not None:
self.motorPv.put('JOGF',not self.motorPv.get('JOGF'))
def onPushHOMR(self):
'''homr button was pressed'''
if self.motorPv is not None:
self.motorPv.put('HOMR',1)
def onPushHOMF(self):
'''homf button was pressed'''
if self.motorPv is not None:
self.motorPv.put('HOMF',1)
def onPushPLOT(self):
'''plot button was pressed'''
self.controls['ArrayStat'].startPlot()
def onPushTWF(self):
'''tweak forward button was pressed'''
if self.motorPv is not None:
self.motorPv.put('TWF', 1)
def onPushTWR(self):
'''tweak reverse button was pressed'''
if self.motorPv is not None:
self.motorPv.put('TWR', 1)
def onPush10x(self):
'''multiply TWV*10 button was pressed'''
if self.motorPv is not None:
self.motorPv.put('TWV', 10*self.motorPv.get('TWV'))
def onPush_1x(self):
'''multiply TWV*0.1 button was pressed'''
if self.motorPv is not None:
self.motorPv.put('TWV', 0.1*self.motorPv.get('TWV'))
def onReturnTWV(self):
'''new target value was entered in this panel'''
if self.motorPv is not None:
number = float(self.controls['TWV'].text())
self.motorPv.put('TWV', number)
def onReturnVAL(self):
'''new target value was entered in this panel'''
if self.motorPv is not None:
number = float(self.controls['VAL'].text())
#self.motorPv.move(number)
self.motorPv.put('VAL',number)
def onReturnVELO(self):
'''new target velocity was entered in this panel'''
if self.motorPv is not None:
number = float(self.controls['VELO'].text())
self.motorPv.put('VELO',number)
def onReturnJVEL(self):
'''new target jog velocity was entered in this panel'''
if self.motorPv is not None:
number = float(self.controls['JVEL'].text())
self.motorPv.put('JVEL',number)
def onChangeCNEN(self, value = None, **kws):
'''EPICS monitor on CNEN called this'''
field='CNEN'
if value:
self.controls[field].setStyleSheet(STYLES['BUTTON_ON'])
else:
self.controls[field].setStyleSheet(STYLES[field])
def onChangeJOGR(self, value = None, **kws):
'''EPICS monitor on JOGR called this'''
field='JOGR'
if value:
self.controls[field].setStyleSheet(STYLES['BUTTON_ON'])
else:
self.controls[field].setStyleSheet(STYLES[field])
def onChangeJOGF(self, value = None, **kws):
'''EPICS monitor on JOGF called this'''
field='JOGF'
if value:
self.controls[field].setStyleSheet(STYLES['BUTTON_ON'])
else:
self.controls[field].setStyleSheet(STYLES[field])
def onChangeHOMR(self, value = None, **kws):
'''EPICS monitor on HOMR called this'''
field='HOMR'
if value:
self.controls[field].setStyleSheet(STYLES['BUTTON_ON'])
else:
self.controls[field].setStyleSheet(STYLES[field])
def onChangeHOMF(self, value = None, **kws):
'''EPICS monitor on HOMF called this'''
field='HOMF'
if value:
self.controls[field].setStyleSheet(STYLES['BUTTON_ON'])
else:
self.controls[field].setStyleSheet(STYLES[field])
def onChangeMSTA(self, value = None, **kws):
'''EPICS monitor on MSTA called this'''
field='MSTA'
self.controls[field].setText(bin(int(value))[2:])
def onChangeDESC(self, char_value=None, **kws):
'''EPICS monitor on DESC called this'''
self.controls['DESC'].setText(char_value)
def onChangeDMOV(self, value = None, **kws):
'''EPICS monitor on DMOV called this, change the color of the RBV label'''
if value is not None:
color = {1: BACKGROUND_DONE_MOVING, 0: BACKGROUND_MOVING}[value]
self.setLabelBackground(self.controls['RBV'], color)
def onChangeHLS(self, value=None, **kws):
'''EPICS monitor on HLS called this, change the color of the TWF button'''
if value is not None:
color = {0: BACKGROUND_DEFAULT, 1: BACKGROUND_LIMIT_ON}[value]
self.setLabelBackground(self.controls['TWF'], color)
def onChangeLLS(self, value=None, **kws):
'''EPICS monitor on LLS called this, change the color of the TWR button'''
if value is not None:
color = {0: BACKGROUND_DEFAULT, 1: BACKGROUND_LIMIT_ON}[value]
self.setLabelBackground(self.controls['TWR'], color)
def onChangeEGU(self, char_value=None, **kws):
'''EPICS monitor on EGU called this'''
self.controls['EGU'].setText(char_value)
def onChangeRBV(self, value=None, **kws):
'''EPICS monitor on RBV called this'''
field='RBV'
if value is not None:
self.controls[field].setText(str(value))
def onChangeTWV(self, value=None, **kws):
'''EPICS monitor on TWV called this'''
field='TWV'
if value is not None:
self.controls[field].setText(str(value))
self.controls[field].setAlignment(QtCore.Qt.AlignRight)
def onChangeVAL(self, value=None, **kws):
'''EPICS monitor on VAL called this'''
field='VAL'
if value is not None:
self.controls[field].setText(str(value))
self.controls[field].setAlignment(QtCore.Qt.AlignRight)
def onChangeVELO(self, value=None, **kws):
'''EPICS monitor on VELO called this'''
field='VELO'
if value is not None:
self.controls[field].setText(str(value))
self.controls[field].setAlignment(QtCore.Qt.AlignRight)
def onChangeJVEL(self, value=None, **kws):
'''EPICS monitor on JVEL called this'''
field='JVEL'
if value is not None:
self.controls[field].setText(str(value))
self.controls[field].setAlignment(QtCore.Qt.AlignRight)
def onChangeCntrlErrorIdPv(self,pvname=None, value=None, char_value=None, **kw):
self.cntrlErrorMsg=self.cntrlErrorMsgPv.get(as_string=True)
print("new Error message: " +str(self.cntrlErrorMsg))
def onChangeCntrlErrorMsgPv(self,pvname=None, value=None, char_value=None, **kw):
print("onChangeCntrlErrorMsgPv:" + char_value)
def onChangeCntrlCmdPv(self,pvname=None, value=None, char_value=None, **kw):
print("onChangeCntrlCmdPv")
def setLabelBackground(self, widget = None, color = BACKGROUND_DEFAULT):
'''change the background color of a Qt widget'''
if widget is not None:
palette = QtGui.QPalette()
palette.setColor(widget.backgroundRole(), QtGui.QColor(color))
widget.setPalette(palette)
def main():
'''demo: display the named motors in a horizontal block'''
if len(sys.argv) != 2:
raise RuntimeError ("usage: %s motor".format(sys.argv[0]))
app = QtWidgets.QApplication(sys.argv)
panel = MotorPanel(pvname=sys.argv[1])
#panel.connect()
panel.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()