class SummaryWidget(QWidget): """General widget for controlling a power supply.""" def __init__(self, name, visible_props, parent=None): """Build UI with dclink name.""" super().__init__(parent) self._name = PVName(name) self._psmodel = PSSearch.conv_psname_2_psmodel(name) self._pstype = PSSearch.conv_psname_2_pstype(name) self.visible_props = sort_propties(visible_props) self.filled_widgets = set() self._prefixed_name = self._name.substitute(prefix=VACA_PREFIX) self._analog_name = get_analog_name(self._name) self._strength_name = get_strength_name(self._name) self._is_pulsed = IsPulsed.match(self._name) self._is_linac = IsLinac.match(self._name) self._li_has_not_strength = LIQuadHasNotStrength.match(self._name) self._is_fofb = FastCorrector.match(self._name) self._is_dclink = IsDCLink.match(self._name) self._is_regatron = self._psmodel == 'REGATRON_DCLink' self._is_reg_slave = self._pstype == 'as-dclink-regatron-slave' self._bbb_name = '' self._udc_name = '' if not self._is_pulsed and not self._is_linac and \ not self._is_regatron and not self._is_fofb: self._bbb_name = PSSearch.conv_psname_2_bbbname(self._name) self._udc_name = PSSearch.conv_psname_2_udc(self._name) self._has_opmode = not self._is_linac and not self._is_pulsed\ and not self._is_fofb self._has_ctrlmode = not self._is_regatron and not self._is_linac\ and not self._is_fofb self._has_pwrstate = not self._is_reg_slave self._has_reset = not self._is_linac and not self._is_fofb\ and not self._is_reg_slave self._has_ctrlloop = not self._is_linac and not self._is_pulsed\ and not self._is_regatron self._has_parmupdt = not self._is_linac and not self._is_regatron\ and not self._is_fofb self._has_wfmupdt = self._has_parmupdt and not self._is_dclink self._has_analsp = not self._is_reg_slave self._has_analrb = not self._is_regatron self._has_analmon = not self._is_fofb self._has_strength = bool(self._strength_name and not self._li_has_not_strength) self._has_strength_mon = self._has_strength and not self._is_fofb self._has_trim = HasTrim.match(self._name) self._create_pvs() self._setup_ui() @property def devname(self): """PS name.""" return self._name @property def bbbname(self): """BBB name.""" return self._bbb_name @property def udcname(self): """UDC name.""" return self._udc_name def _setup_ui(self): """Setups widget UI.""" lay = QHBoxLayout() lay.setContentsMargins(0, 0, 0, 0) lay.setSpacing(10) self._widgets_dict = dict() self.detail_wid = self._build_widget(name='detail', orientation='v') self._widgets_dict['detail'] = self.detail_wid lay.addWidget(self.detail_wid) if self._bbb_name: self.bbb_wid = self._build_widget(name='bbb', orientation='v') self._widgets_dict['bbb'] = self.bbb_wid lay.addWidget(self.bbb_wid) if self._udc_name: self.udc_wid = self._build_widget(name='udc', orientation='v') self._widgets_dict['udc'] = self.udc_wid lay.addWidget(self.udc_wid) if self._has_opmode: self.opmode_wid = self._build_widget(name='opmode', orientation='v') self._widgets_dict['opmode'] = self.opmode_wid lay.addWidget(self.opmode_wid) if self._has_ctrlmode: self.ctrlmode_wid = self._build_widget(name='ctrlmode', orientation='v') self._widgets_dict['ctrlmode'] = self.ctrlmode_wid lay.addWidget(self.ctrlmode_wid) self.state_wid = self._build_widget(name='state') self._widgets_dict['state'] = self.state_wid lay.addWidget(self.state_wid) if self._is_pulsed: self.pulse_wid = self._build_widget(name='pulse') self._widgets_dict['pulse'] = self.pulse_wid lay.addWidget(self.pulse_wid) self.intlk_wid = self._build_widget(name='intlk') self._widgets_dict['intlk'] = self.intlk_wid lay.addWidget(self.intlk_wid) if self._is_linac: self.conn_wid = self._build_widget(name='conn') self._widgets_dict['conn'] = self.conn_wid lay.addWidget(self.conn_wid) if self._has_reset: self.reset_wid = self._build_widget(name='reset') self._widgets_dict['reset'] = self.reset_wid lay.addWidget(self.reset_wid) if self._has_ctrlloop: self.ctrlloop_wid = self._build_widget(name='ctrlloop') self._widgets_dict['ctrlloop'] = self.ctrlloop_wid lay.addWidget(self.ctrlloop_wid) if self._has_wfmupdt: self.wfmupdate_wid = self._build_widget(name='wfmupdate') self._widgets_dict['wfmupdate'] = self.wfmupdate_wid lay.addWidget(self.wfmupdate_wid) if self._has_parmupdt: self.updparms_wid = self._build_widget(name='updparms') self._widgets_dict['updparms'] = self.updparms_wid lay.addWidget(self.updparms_wid) self.setpoint_wid = self._build_widget(name='setpoint', orientation='v') self._widgets_dict['setpoint'] = self.setpoint_wid lay.addWidget(self.setpoint_wid) if self._has_analrb: self.readback_wid = self._build_widget(name='readback', orientation='v') self._widgets_dict['readback'] = self.readback_wid lay.addWidget(self.readback_wid) if self._has_analmon: self.monitor_wid = self._build_widget(name='monitor', orientation='v') self._widgets_dict['monitor'] = self.monitor_wid lay.addWidget(self.monitor_wid) if self._has_strength: self.strength_sp_wid = self._build_widget(name='strength_sp', orientation='v') self._widgets_dict['strength_sp'] = self.strength_sp_wid lay.addWidget(self.strength_sp_wid) self.strength_rb_wid = self._build_widget(name='strength_rb', orientation='v') self._widgets_dict['strength_rb'] = self.strength_rb_wid lay.addWidget(self.strength_rb_wid) if self._has_strength_mon: self.strength_mon_wid = self._build_widget(name='strength_mon', orientation='v') self._widgets_dict['strength_mon'] = self.strength_mon_wid lay.addWidget(self.strength_mon_wid) if self._has_trim: self.trim_wid = self._build_widget(name='trim', orientation='v') self._widgets_dict['trim'] = self.trim_wid lay.addWidget(self.trim_wid) _widths = get_prop2width(self._name) for name, widget in self._widgets_dict.items(): width = _widths[name] widget.setStyleSheet('#' + name + '{min-width:' + str(width) + 'em;' 'max-width:' + str(width) + 'em;}') widget.setSizePolicy(QSzPlcy.Fixed, QSzPlcy.Fixed) widget.setVisible(name in self.visible_props) self.setStyleSheet(""" PyDMStateButton{ min-width: 2.5em; max-width: 2.5em; min-height: 1.5em; max-height: 1.5em; } QLed{ min-width: 1.5em; max-width: 1.5em; min-height: 1.5em; max-height: 1.5em; } QLabel{ min-height: 1.5em; max-height: 1.5em; qproperty-alignment: AlignCenter; } """) lay.addStretch() self.setLayout(lay) for prop in self.visible_props: self.fillWidget(prop) def _create_pvs(self): if self._has_opmode: if self._is_reg_slave: self._opmode_sts = self._prefixed_name.substitute( propty='ModState-Mon') elif self._is_regatron: self._opmode_sts = self._prefixed_name.substitute( propty='OpMode-Sts') else: self._opmode_sel = self._prefixed_name.substitute( propty='OpMode-Sel') self._opmode_sts = self._prefixed_name.substitute( propty='OpMode-Sts') if self._has_ctrlmode: self._ctrlmode_sts = self._prefixed_name.substitute( propty='CtrlMode-Mon') if self._has_pwrstate: self._pwrstate_sel = self._prefixed_name.substitute( propty='PwrState-Sel') self._pwrstate_sts = self._prefixed_name.substitute( propty='PwrState-Sts') if self._is_pulsed: self._pulse_sel = self._prefixed_name.substitute( propty='Pulse-Sel') self._pulse_sts = self._prefixed_name.substitute( propty='Pulse-Sts') # interlock if self._is_pulsed: self._intlk = list() for i in range(1, 8): self._intlk.append( self._prefixed_name.substitute(propty='Intlk' + str(i) + '-Mon')) if 'Sept' not in self._name.dev: self._intlk.append( self._prefixed_name.substitute(propty='Intlk8-Mon')) elif self._is_linac: self._intlk = self._prefixed_name.substitute( propty='StatusIntlk-Mon') elif self._is_regatron: if not self._is_reg_slave: self._generr = self._prefixed_name.substitute( propty='GenIntlk-Mon') self._genwrn = self._prefixed_name.substitute( propty='GenWarn-Mon') elif self._is_fofb: self._intlk = [ self._prefixed_name.substitute( propty='PSAmpOverCurrFlagL-Sts'), self._prefixed_name.substitute( propty='PSAmpOverCurrFlagR-Sts'), self._prefixed_name.substitute( propty='PSAmpOverTempFlagL-Sts'), self._prefixed_name.substitute( propty='PSAmpOverTempFlagR-Sts'), ] else: self._soft_intlk = self._prefixed_name.substitute( propty='IntlkSoft-Mon') self._hard_intlk = self._prefixed_name.substitute( propty='IntlkHard-Mon') if self._is_linac: self._conn = self._prefixed_name.substitute(propty='Connected-Mon') if self._has_reset: self._reset_intlk = self._prefixed_name.substitute( propty='Reset-Cmd') if self._has_ctrlloop: self._ctrlloop_sel = self._prefixed_name.substitute( propty='CtrlLoop-Sel') self._ctrlloop_sts = self._prefixed_name.substitute( propty='CtrlLoop-Sts') if self._has_wfmupdt: self._wfmupdate_sel = self._prefixed_name.substitute( propty='WfmUpdateAuto-Sel') self._wfmupdate_sts = self._prefixed_name.substitute( propty='WfmUpdateAuto-Sts') if self._has_parmupdt: self._updparms_cmd = self._prefixed_name.substitute( propty='ParamUpdate-Cmd') # analog control sp = self._analog_name if self._has_analsp: self._analog_sp = self._prefixed_name.substitute( propty='{}-SP'.format(sp)) if self._has_analrb: self._analog_rb = self._prefixed_name.substitute( propty='{}-RB'.format(sp)) if self._has_analmon: if self._is_reg_slave: self._analog_mon = self._prefixed_name.substitute( propty='ModOutVolt-Mon') else: self._analog_mon = self._prefixed_name.substitute( propty='{}-Mon'.format(sp)) # strength if self._has_strength: st = self._strength_name self._strength_sp = self._prefixed_name.substitute( propty='{}-SP'.format(st)) self._strength_rb = self._prefixed_name.substitute( propty='{}-RB'.format(st)) if self._has_strength_mon: self._strength_mon = self._prefixed_name.substitute( propty='{}-Mon'.format(st)) def _build_widget(self, name='', orientation='h'): widget = QWidget(self) widget.setObjectName(name) if orientation == 'h': lay = QHBoxLayout(widget) else: lay = QVBoxLayout(widget) lay.setSpacing(0) lay.setContentsMargins(0, 3, 0, 3) return widget def fillWidget(self, name): if name in self.filled_widgets: return if name == 'detail': self.detail_bt = QPushButton(self) if self._name.dev == 'DCLink': self.detail_bt.setIcon(qta.icon('fa5s.list-ul')) self.detail_bt.setToolTip(self._name) else: self.detail_bt.setText(self._name) self.detail_wid.layout().addWidget(self.detail_bt) elif name == 'bbb' and self._bbb_name: self.bbb_lb = QLabel(self._bbb_name, self) self.bbb_wid.layout().addWidget(self.bbb_lb) elif name == 'udc' and self._udc_name: self.udc_lb = QLabel(self._udc_name, self) self.udc_wid.layout().addWidget(self.udc_lb) elif name == 'opmode' and self._has_opmode: opmode_list = list() if 'Voltage' not in self._analog_name: self.opmode_cb = SiriusEnumComboBox(self, self._opmode_sel) opmode_list.append(self.opmode_cb) self.opmode_lb = PyDMLabel(self, self._opmode_sts) opmode_list.append(self.opmode_lb) for wid in opmode_list: self.opmode_wid.layout().addWidget(wid) elif name == 'ctrlmode' and self._has_ctrlmode: self.ctrlmode_lb = PyDMLabel(self, self._ctrlmode_sts) self.ctrlmode_wid.layout().addWidget(self.ctrlmode_lb) elif name == 'state' and self._has_pwrstate: self.state_bt = PyDMStateButton(self, self._pwrstate_sel) self.state_led = SiriusLedState(self, self._pwrstate_sts) self.state_wid.layout().addWidget(self.state_bt) self.state_wid.layout().addWidget(self.state_led) elif name == 'pulse' and self._is_pulsed: self.pulse_bt = PyDMStateButton(self, self._pulse_sel) self.pulse_led = SiriusLedState(self, self._pulse_sts) self.pulse_wid.layout().addWidget(self.pulse_bt) self.pulse_wid.layout().addWidget(self.pulse_led) elif name == 'intlk': if self._is_pulsed: self.intlk_led = PyDMLedMultiChannel( self, channels2values={ch: 1 for ch in self._intlk}) self.intlk_wid.layout().addWidget(self.intlk_led) elif self._is_linac: if IsLinacSpect.match(self.devname): self.intlk_led = LISpectIntlkLed(self) else: self.intlk_led = PyDMLedMultiChannel(self, channels2values={ self._intlk: { 'value': _PS_LI_INTLK, 'comp': 'lt' } }) self.intlk_wid.layout().addWidget(self.intlk_led) elif self._is_regatron: if not self._is_reg_slave: self.generr_led = SiriusLedAlert(self, self._generr) self.genwrn_led = SiriusLedAlert(self, self._genwrn) self.intlk_wid.layout().addWidget(self.generr_led) self.intlk_wid.layout().addWidget(self.genwrn_led) elif self._is_fofb: self.intlk_led = PyDMLedMultiChannel( self, channels2values={ch: 1 for ch in self._intlk}) self.intlk_wid.layout().addWidget(self.intlk_led) else: self.soft_intlk_led = SiriusLedAlert(self, self._soft_intlk) self.hard_intlk_led = SiriusLedAlert(self, self._hard_intlk) self.intlk_wid.layout().addWidget(self.soft_intlk_led) self.intlk_wid.layout().addWidget(self.hard_intlk_led) elif name == 'conn' and self._is_linac: self.conn_led = PyDMLedMultiChannel( self, channels2values={self._conn: 0}) self.conn_wid.layout().addWidget(self.conn_led) elif name == 'reset' and self._has_reset: self.reset_bt = PyDMPushButton(parent=self, init_channel=self._reset_intlk, pressValue=1) self.reset_bt.setIcon(qta.icon('fa5s.sync')) self.reset_bt.setObjectName('reset_bt') self.reset_bt.setStyleSheet( '#reset_bt{min-width:25px; max-width:25px; icon-size:20px;}') self.reset_wid.layout().addWidget(self.reset_bt) elif name == 'ctrlloop' and self._has_ctrlloop: if self._is_fofb: self.ctrlloop_bt = PyDMStateButton(self, self._ctrlloop_sel) else: self.ctrlloop_bt = PyDMStateButton(self, self._ctrlloop_sel, invert=True) self.ctrlloop_lb = PyDMLabel(self, self._ctrlloop_sts) self.ctrlloop_wid.layout().addWidget(self.ctrlloop_bt) self.ctrlloop_wid.layout().addWidget(self.ctrlloop_lb) elif name == 'wfmupdate' and self._has_wfmupdt: self.wfmupdate_bt = PyDMStateButton(self, self._wfmupdate_sel) self.wfmupdate_led = SiriusLedState(self, self._wfmupdate_sts) self.wfmupdate_wid.layout().addWidget(self.wfmupdate_bt) self.wfmupdate_wid.layout().addWidget(self.wfmupdate_led) elif name == 'updparms' and self._has_parmupdt: self.updparms_bt = PyDMPushButton(parent=self, init_channel=self._updparms_cmd, pressValue=1) self.updparms_bt.setIcon(qta.icon('fa5s.redo-alt')) self.updparms_bt.setObjectName('updparms_bt') self.updparms_bt.setStyleSheet( '#updparms_bt{min-width:25px;max-width:25px;icon-size:20px;}') self.updparms_wid.layout().addWidget(self.updparms_bt) elif name == 'setpoint' and self._has_analsp: self.setpoint = PyDMSpinboxScrollbar(self, self._analog_sp) if self._is_fofb: self.setpoint.spinbox.precisionFromPV = False self.setpoint.spinbox.precision = 6 self.setpoint_wid.layout().addWidget(self.setpoint) elif name == 'readback' and self._has_analrb: self.readback = PyDMLabel(self, self._analog_rb) if self._is_fofb: self.readback.precisionFromPV = False self.readback.precision = 6 self.readback_wid.layout().addWidget(self.readback) elif name == 'monitor' and self._has_analmon: self.monitor = PyDMLabel(self, self._analog_mon) self.monitor_wid.layout().addWidget(self.monitor) elif name == 'strength_sp' and self._has_strength: self.strength_sp_le = PyDMSpinboxScrollbar(self, self._strength_sp) self.strength_sp_wid.layout().addWidget(self.strength_sp_le) elif name == 'strength_rb' and self._has_strength: self.strength_rb_lb = PyDMLabel(parent=self, init_channel=self._strength_rb) self.strength_rb_lb.showUnits = True self.strength_rb_wid.layout().addWidget(self.strength_rb_lb) elif name == 'strength_mon' and self._has_strength_mon: self.strength_mon_lb = PyDMLabel(parent=self, init_channel=self._strength_mon) self.strength_mon_lb.showUnits = True self.strength_mon_wid.layout().addWidget(self.strength_mon_lb) elif name == 'trim' and self._has_trim: self.trim_bt = QPushButton(qta.icon('fa5s.angle-right'), '', self) self.trim_wid.layout().addWidget(self.trim_bt) self.filled_widgets.add(name) def get_detail_button(self): """Return psname button.""" return self.detail_bt def get_trim_button(self): """Return trim button.""" if self._has_trim: return self.trim_bt return None def set_opmode_slowref(self): """Set power supply OpMode to SlowRef.""" if hasattr(self, 'opmode_cb'): if self.opmode_cb.isEnabled(): index = self.opmode_cb.findText('SlowRef') self.opmode_cb.internal_combo_box_activated_int(index) def turn_on(self): """Turn power supply on.""" if hasattr(self, 'state_bt'): if self.state_bt.isEnabled(): if not self.state_bt.value: self.state_bt.send_value() def turn_off(self): """Turn power supply off.""" if hasattr(self, 'state_bt'): if self.state_bt.isEnabled(): if self.state_bt.value: self.state_bt.send_value() def ctrlloop_close(self): """Close control loop.""" if hasattr(self, 'ctrlloop_bt'): if self.ctrlloop_bt.isEnabled(): if not self.ctrlloop_bt.value: self.ctrlloop_bt.send_value() def ctrlloop_open(self): """Open control loop.""" if hasattr(self, 'ctrlloop_bt'): if self.ctrlloop_bt.isEnabled(): if self.ctrlloop_bt.value: self.ctrlloop_bt.send_value() def pulse_on(self): """Turn power supply on.""" if hasattr(self, 'pulse_bt'): if self.pulse_bt.isEnabled(): if not self.pulse_bt.value: self.pulse_bt.send_value() def pulse_off(self): """Turn power supply off.""" if hasattr(self, 'pulse_bt'): if self.pulse_bt.isEnabled(): if self.pulse_bt.value: self.pulse_bt.send_value() def wfmupdate_on(self): """Enable WfmUpdateAuto.""" if hasattr(self, 'wfmupdate_bt'): if self.wfmupdate_bt.isEnabled(): if not self.wfmupdate_bt.value: self.wfmupdate_bt.send_value() def wfmupdate_off(self): """Disable WfmUpdateAuto.""" if hasattr(self, 'wfmupdate_bt'): if self.wfmupdate_bt.isEnabled(): if self.wfmupdate_bt.value: self.wfmupdate_bt.send_value() def reset(self): """Reset power supply.""" if hasattr(self, 'reset_bt'): if self.reset_bt.isEnabled(): self.reset_bt.sendValue() def update_params(self): """Update power supply parameters.""" if hasattr(self, 'updparms_bt'): if self.updparms_bt.isEnabled(): self.updparms_bt.sendValue()
class PosAngCorr(SiriusMainWindow): """Main Class.""" def __init__(self, parent=None, prefix='', tl=None): """Class construc.""" super(PosAngCorr, self).__init__(parent) if not prefix: self._prefix = _VACA_PREFIX else: self._prefix = prefix self._tl = tl.upper() base_name = _PVName('TL-Glob:AP-PosAng') self.posang_prefix = base_name.substitute( prefix=self._prefix, sec=self._tl) self.setObjectName(self._tl+'App') self.setWindowTitle(self._tl + ' Position and Angle Correction Window') if self._tl == 'TS': self._is_chsept = False ch3_pv = _PV(self.posang_prefix.substitute(propty='CH3-Cte'), connection_timeout=1) if not ch3_pv.wait_for_connection(): self._is_chsept = True if tl == 'ts': corr_h = (Const.TS_CORRH_POSANG_CHSEPT if self._is_chsept else Const.TS_CORRH_POSANG_SEPTSEPT) corr_v = Const.TS_CORRV_POSANG elif tl == 'tb': corr_h = Const.TB_CORRH_POSANG corr_v = Const.TB_CORRV_POSANG self.corrs = dict() self.corrs['CH1'] = _PVName(corr_h[0]) self.corrs['CH2'] = _PVName(corr_h[1]) if len(corr_h) == 3: self.corrs['CH3'] = _PVName(corr_h[2]) self.corrs['CV1'] = _PVName(corr_v[0]) self.corrs['CV2'] = _PVName(corr_v[1]) if len(corr_v) == 4: self.corrs['CV3'] = _PVName(corr_v[2]) self.corrs['CV4'] = _PVName(corr_v[3]) self._just_need_update = False self._update_ref_action = False self._my_input_widgets = list() self._setupUi() self.setFocus(True) self.setFocusPolicy(Qt.StrongFocus) self._ask_message = QMessageBox(self) self._ask_message.setWindowTitle('Message') self._ask_message.setText( 'The '+self._tl+' PosAng IOC indicates reference needs to ' 'be updated! Do you want to update the reference?') self._ask_message.setStandardButtons(QMessageBox.No | QMessageBox.Yes) self._ask_message.setDefaultButton(QMessageBox.No) self.app = QApplication.instance() self.app.focusChanged.connect(self._spinbox_onfocus) def _setupUi(self): cwt = QWidget(self) self.setCentralWidget(cwt) # label lab = QLabel( '<h3>'+self._tl+' Position and Angle Correction</h3>', cwt) lab.setStyleSheet(""" min-height:1.55em; max-height: 1.55em; qproperty-alignment: 'AlignVCenter | AlignRight'; background-color: qlineargradient(spread:pad, x1:1, y1:0.0227273, x2:0, y2:0, stop:0 rgba(173, 190, 207, 255), stop:1 rgba(213, 213, 213, 255));""") # apply button self.pb_updateref = PyDMPushButton( self, 'Update Reference', pressValue=1, init_channel=self.posang_prefix.substitute( propty='SetNewRefKick-Cmd')) self.pb_updateref.setStyleSheet( 'min-height: 2.4em; max-height: 2.4em;') self.led_needrefupdt = SiriusLedAlert( self, self.posang_prefix.substitute(propty='NeedRefUpdate-Mon')) self.ch_needrefupdt = SiriusConnectionSignal( self.posang_prefix.substitute(propty='NeedRefUpdate-Mon')) self.ch_needrefupdt.new_value_signal[int].connect( self._handle_need_update_ref_led) self.led_needrefupdt.setStyleSheet( 'QLed{min-width: 1.29em; max-width: 1.29em;}') box_ref = QHBoxLayout() box_ref.setContentsMargins(0, 0, 0, 0) box_ref.addWidget(self.pb_updateref) box_ref.addWidget(self.led_needrefupdt) # delta setters self.hgbox = QGroupBox('Horizontal', self) self.hgbox.setLayout(self._setupDeltaControlLayout('x')) self.vgbox = QGroupBox('Vertical', self) self.vgbox.setLayout(self._setupDeltaControlLayout('y')) # correctors self.corrgbox = QGroupBox('Correctors', self) self.corrgbox.setLayout(self._setupCorrectorsLayout()) # status self.statgbox = QGroupBox('Correction Status', self) self.statgbox.setLayout(self._setupStatusLayout()) glay = QGridLayout(cwt) glay.setHorizontalSpacing(12) glay.setVerticalSpacing(12) glay.addWidget(lab, 0, 0, 1, 2) glay.addLayout(box_ref, 1, 0, 1, 2) glay.addWidget(self.hgbox, 2, 0) glay.addWidget(self.vgbox, 2, 1) glay.addWidget(self.corrgbox, 3, 0, 1, 2) glay.addWidget(self.statgbox, 4, 0, 1, 2) # menu act_settings = self.menuBar().addAction('Settings') _hlautil.connect_window(act_settings, CorrParamsDetailWindow, parent=self, tl=self._tl, prefix=self._prefix) # stlesheet self.setStyleSheet(""" PyDMSpinbox{ min-width: 5em; max-width: 5em; } PyDMLabel, PyDMSpinboxScrollbar{ min-width: 6em; max-width: 6em; } QPushButton{ min-width: 8em; } QLabel{ min-height: 1.35em; qproperty-alignment: AlignCenter; } """) def _setupDeltaControlLayout(self, axis=''): # pos label_pos = QLabel("<h4>Δ"+axis+"</h4>", self) sb_deltapos = PyDMSpinbox(self, self.posang_prefix.substitute( propty='DeltaPos'+axis.upper()+'-SP')) sb_deltapos.step_exponent = -2 sb_deltapos.update_step_size() sb_deltapos.showStepExponent = False lb_deltapos = PyDMLabel(self, self.posang_prefix.substitute( propty='DeltaPos'+axis.upper()+'-RB')) lb_deltapos.showUnits = True self._my_input_widgets.append(sb_deltapos) # ang label_ang = QLabel("<h4>Δ"+axis+"'</h4>", self) sb_deltaang = PyDMSpinbox(self, self.posang_prefix.substitute( propty='DeltaAng'+axis.upper()+'-SP')) sb_deltaang.step_exponent = -2 sb_deltaang.update_step_size() sb_deltaang.showStepExponent = False lb_deltaang = PyDMLabel(self, self.posang_prefix.substitute( propty='DeltaAng'+axis.upper()+'-RB')) lb_deltaang.showUnits = True self._my_input_widgets.append(sb_deltaang) lay = QGridLayout() lay.setVerticalSpacing(12) lay.setHorizontalSpacing(12) lay.addItem( QSpacerItem(10, 0, QSzPlcy.Expanding, QSzPlcy.Ignored), 0, 0) lay.addWidget(label_pos, 0, 1) lay.addWidget(sb_deltapos, 0, 2) lay.addWidget(lb_deltapos, 0, 3) lay.addWidget(label_ang, 1, 1) lay.addWidget(sb_deltaang, 1, 2) lay.addWidget(lb_deltaang, 1, 3) lay.addItem( QSpacerItem(10, 0, QSzPlcy.Expanding, QSzPlcy.Ignored), 0, 4) return lay def _setupCorrectorsLayout(self): lay = QGridLayout() lay.setVerticalSpacing(9) lay.setHorizontalSpacing(9) label_kicksp = QLabel('<h4>Kick-SP</h4>', self) label_kickrb = QLabel('<h4>Kick-RB</h4>', self) label_kickref = QLabel('<h4>RefKick-Mon</h4>', self) lay.addWidget(label_kicksp, 0, 2) lay.addWidget(label_kickrb, 0, 3) lay.addWidget(label_kickref, 0, 4) idx = 1 for corrid, corr in self.corrs.items(): pbt = QPushButton(qta.icon('fa5s.list-ul'), '', self) pbt.setObjectName('pbt') pbt.setStyleSheet(""" #pbt{ min-width:25px; max-width:25px; min-height:25px; max-height:25px; icon-size:20px;} """) if corr.dis == 'PU': _hlautil.connect_window( pbt, _PUDetailWindow, self, devname=corr) else: _hlautil.connect_window( pbt, _PSDetailWindow, self, psname=corr) lb_name = QLabel(corr, self) le_sp = PyDMSpinboxScrollbar( self, corr.substitute(prefix=self._prefix, propty='Kick-SP')) le_sp.spinbox.setAlignment(Qt.AlignCenter) le_sp.scrollbar.limitsFromPV = True lb_rb = PyDMLabel(self, corr.substitute( prefix=self._prefix, propty='Kick-RB')) lb_ref = PyDMLabel(self, self.posang_prefix.substitute( propty='RefKick'+corrid+'-Mon')) lay.addWidget(pbt, idx, 0, alignment=Qt.AlignTop) lay.addWidget( lb_name, idx, 1, alignment=Qt.AlignLeft | Qt.AlignTop) lay.addWidget(le_sp, idx, 2, alignment=Qt.AlignTop) lay.addWidget(lb_rb, idx, 3, alignment=Qt.AlignTop) lay.addWidget(lb_ref, idx, 4, alignment=Qt.AlignTop) idx += 1 if self._tl == 'TB': pref = self._prefix + ('-' if self._prefix else '') lay.addItem(QSpacerItem(0, 8, QSzPlcy.Ignored, QSzPlcy.Fixed)) label_voltsp = QLabel('<h4>Amplitude-SP</h4>', self) label_voltrb = QLabel('<h4>Amplitude-RB</h4>', self) lay.addWidget(label_voltsp, idx+2, 2) lay.addWidget(label_voltrb, idx+2, 3) lb_kly2_name = QLabel('Klystron 2', self) le_kly2_sp = PyDMSpinboxScrollbar( self, pref+'LA-RF:LLRF:KLY2:SET_AMP') le_kly2_sp.spinbox.precisionFromPV = False le_kly2_sp.spinbox.precision = 2 le_kly2_sp.spinbox.setAlignment(Qt.AlignCenter) le_kly2_sp.scrollbar.limitsFromPV = True lb_kly2_rb = PyDMLabel(self, pref+'LA-RF:LLRF:KLY2:GET_AMP') lb_kly2_rb.precisionFromPV = False lb_kly2_rb.precision = 2 lay.addWidget(lb_kly2_name, idx+3, 1, alignment=Qt.AlignLeft | Qt.AlignTop) lay.addWidget(le_kly2_sp, idx+3, 2, alignment=Qt.AlignTop) lay.addWidget(lb_kly2_rb, idx+3, 3, alignment=Qt.AlignTop) self._kckr_name = _PVName('BO-01D:PU-InjKckr') else: self._kckr_name = _PVName('SI-01SA:PU-InjNLKckr') label_voltsp = QLabel('<h4>Voltage-SP</h4>', self) label_voltrb = QLabel('<h4>Voltage-RB</h4>', self) lay.addWidget(label_voltsp, idx+4, 2) lay.addWidget(label_voltrb, idx+4, 3) lay.addItem(QSpacerItem(0, 8, QSzPlcy.Ignored, QSzPlcy.Fixed)) pb_kckr = QPushButton(qta.icon('fa5s.list-ul'), '', self) pb_kckr.setObjectName('pb') pb_kckr.setStyleSheet(""" #pb{ min-width:25px; max-width:25px; min-height:25px; max-height:25px; icon-size:20px;} """) lb_kckr_name = QLabel(self._kckr_name, self) _hlautil.connect_window( pb_kckr, _PUDetailWindow, self, devname=self._kckr_name) lb_kckr_sp = PyDMSpinboxScrollbar( self, self._kckr_name.substitute( prefix=self._prefix, propty='Voltage-SP')) lb_kckr_sp.scrollbar.limitsFromPV = True lb_kckr_rb = PyDMLabel(self, self._kckr_name.substitute( prefix=self._prefix, propty='Voltage-RB')) lay.addWidget(pb_kckr, idx+5, 0, alignment=Qt.AlignTop) lay.addWidget( lb_kckr_name, idx+5, 1, alignment=Qt.AlignLeft | Qt.AlignTop) lay.addWidget(lb_kckr_sp, idx+5, 2, alignment=Qt.AlignTop) lay.addWidget(lb_kckr_rb, idx+5, 3, alignment=Qt.AlignTop) return lay def _setupStatusLayout(self): self.log = PyDMLogLabel( self, self.posang_prefix.substitute(propty='Log-Mon')) self.lb_sts0 = QLabel(Const.STATUSLABELS[0], self) self.led_sts0 = SiriusLedAlert( self, self.posang_prefix.substitute(propty='Status-Mon'), bit=0) self.lb_sts1 = QLabel(Const.STATUSLABELS[1], self) self.led_sts1 = SiriusLedAlert( self, self.posang_prefix.substitute(propty='Status-Mon'), bit=1) self.lb_sts2 = QLabel(Const.STATUSLABELS[2], self) self.led_sts2 = SiriusLedAlert( self, self.posang_prefix.substitute(propty='Status-Mon'), bit=2) self.lb_sts3 = QLabel(Const.STATUSLABELS[3], self) self.led_sts3 = SiriusLedAlert( self, self.posang_prefix.substitute(propty='Status-Mon'), bit=3) self.pb_config = PyDMPushButton( self, label='Config Correctors', pressValue=1, init_channel=self.posang_prefix.substitute(propty='ConfigPS-Cmd')) lay = QGridLayout() lay.setVerticalSpacing(12) lay.setHorizontalSpacing(12) lay.addWidget(self.log, 0, 0, 6, 1) lay.addWidget(self.lb_sts0, 1, 2) lay.addWidget(self.led_sts0, 1, 1) lay.addWidget(self.lb_sts1, 2, 2) lay.addWidget(self.led_sts1, 2, 1) lay.addWidget(self.lb_sts2, 3, 2) lay.addWidget(self.led_sts2, 3, 1) lay.addWidget(self.lb_sts3, 4, 2) lay.addWidget(self.led_sts3, 4, 1) lay.addWidget(self.pb_config, 5, 1, 1, 2) if self._tl == 'TS': self.led_corrtype = PyDMLedMultiChannel( self, {self.posang_prefix.substitute( propty='CH1-Cte'): self.corrs['CH1']}) self.lb_corrtype = QLabel( 'Control ' + ('CH-Sept' if self._is_chsept else 'Sept-Sept')) lay.addWidget(self.led_corrtype, 0, 1) lay.addWidget(self.lb_corrtype, 0, 2) return lay def _set_correctors_channels(self, corrs): self.centralwidget.pushButton_CH1.setText(corrs[0]) _hlautil.connect_window( self.centralwidget.pushButton_CH1, _PSDetailWindow, self, psname=corrs[0]) self.centralwidget.PyDMLabel_KickRBCH1.channel = ( corrs[0].substitute(prefix=self._prefix, propty='Kick-RB')) self.centralwidget.pushButton_CH2.setText(corrs[1]) if corrs[1].dis == 'PU': _hlautil.connect_window( self.centralwidget.pushButton_CH2, _PUDetailWindow, self, devname=corrs[1]) else: _hlautil.connect_window( self.centralwidget.pushButton_CH2, _PSDetailWindow, self, psname=corrs[1]) self.centralwidget.PyDMLabel_KickRBCH2.channel = ( corrs[1].substitute(prefix=self._prefix, propty='Kick-RB')) self.centralwidget.pushButton_CV1.setText(corrs[2]) _hlautil.connect_window( self.centralwidget.pushButton_CV1, _PSDetailWindow, self, psname=corrs[2]) self.centralwidget.PyDMLabel_KickRBCV1.channel = ( corrs[2].substitute(prefix=self._prefix, propty='Kick-RB')) self.centralwidget.pushButton_CV2.setText(corrs[3]) _hlautil.connect_window( self.centralwidget.pushButton_CV2, _PSDetailWindow, self, psname=corrs[3]) self.centralwidget.PyDMLabel_KickRBCV2.channel = ( corrs[3].substitute(prefix=self._prefix, propty='Kick-RB')) def _handle_need_update_ref_led(self, value): self._just_need_update = bool(value) def _spinbox_onfocus(self, old_focus, new_focus): if not self._update_ref_action and not self._just_need_update: return if self.led_needrefupdt.value != 0: if new_focus in self._my_input_widgets and self._just_need_update: ans = self._ask_message.exec_() if ans == QMessageBox.No: self._update_ref_action = False else: self._update_ref_action = True self.pb_updateref.sendValue() self._just_need_update = False