def setupui(self): vbl = QVBoxLayout(self) tip = 'Configure ' + ('Acquisition' if self.is_orb else 'Correctors') pv = 'TrigAcqConfig-Cmd' if self.is_orb else 'CorrConfig-Cmd' conf = PyDMPushButton(self, init_channel=self.devpref.substitute(propty=pv), pressValue=1) conf.setToolTip(tip) conf.setIcon(qta.icon('fa5s.sync')) conf.setObjectName('conf') conf.setStyleSheet( '#conf{min-width:25px; max-width:25px; icon-size:20px;}') vbl.addWidget(conf) pv = 'Orb' if self.is_orb else 'Corr' pdm_led = SiriusLedAlert( self, self.devpref.substitute(propty=pv + 'Status-Mon')) hbl = QHBoxLayout() hbl.setSpacing(9) hbl.addWidget(pdm_led) hbl.addWidget(QLabel('Global Status', self)) hbl.addStretch() hbl.addWidget(conf) vbl.addItem(hbl) grpbx = self.creategroupbox() vbl.addWidget(grpbx)
def _setupCoeffSettingsWidget(self): ld_coefchoo = QLabel('Choose Set', self, alignment=Qt.AlignRight) cb_coefchoo = PyDMEnumComboBox(self, self.dev_pref + ':LDSET') pb_coefload = PyDMPushButton(parent=self, label='Apply Set', icon=qta.icon('mdi.upload'), init_channel=self.dev_pref + ':BO_CPCOEFF', pressValue=1) pb_coefload.setStyleSheet("icon-size:20px;") pb_coefvrfy = PyDMPushButton(parent=self, label='Verify Set', icon=qta.icon('mdi.check-circle-outline'), init_channel=self.dev_pref + ':BO_CVERIFY', pressValue=1) pb_coefvrfy.setStyleSheet("icon-size:20px;") ld_gen = QLabel('<h4>Generate Coefficients</h4>', self, alignment=Qt.AlignCenter) ld_gengain = QLabel('Gain [0-1]', self, alignment=Qt.AlignRight) sb_gengain = PyDMSpinbox(self, self.dev_pref + ':FLT_GAIN') sb_gengain.showStepExponent = False ld_genphs = QLabel('Phase [°]', self, alignment=Qt.AlignRight) sb_genphs = PyDMSpinbox(self, self.dev_pref + ':FLT_PHASE') sb_genphs.showStepExponent = False ld_genfreq = QLabel('Frequency [0-1]', self, alignment=Qt.AlignRight) sb_genfreq = PyDMSpinbox(self, self.dev_pref + ':FLT_FREQ') sb_genfreq.showStepExponent = False ld_genntap = QLabel('Number of taps', self, alignment=Qt.AlignRight) sb_genntap = PyDMSpinbox(self, self.dev_pref + ':FLT_TAPS') sb_genntap.showStepExponent = False wid = QWidget(self) lay_genset = QGridLayout(wid) lay_genset.setVerticalSpacing(6) lay_genset.setHorizontalSpacing(9) lay_genset.addWidget(ld_gen, 0, 1, 1, 2) lay_genset.addWidget(ld_gengain, 1, 1) lay_genset.addWidget(sb_gengain, 1, 2) lay_genset.addWidget(ld_genphs, 2, 1) lay_genset.addWidget(sb_genphs, 2, 2) lay_genset.addWidget(ld_genfreq, 3, 1) lay_genset.addWidget(sb_genfreq, 3, 2) lay_genset.addWidget(ld_genntap, 4, 1) lay_genset.addWidget(sb_genntap, 4, 2) lay_genset.addWidget(ld_coefchoo, 5, 1) lay_genset.addWidget(cb_coefchoo, 5, 2) lay = QGridLayout() lay_genset.addLayout(lay, 6, 1, 1, 2) lay.addWidget(pb_coefload, 0, 0) lay.addWidget(pb_coefvrfy, 0, 2) lay.setColumnStretch(1, 2) lay_genset.setRowStretch(7, 2) lay_genset.setColumnStretch(0, 2) lay_genset.setColumnStretch(3, 2) return wid
def _get_multturn_acq_grpbx(self): grp_bx = QWidget(self) fbl = QFormLayout(grp_bx) lbl = QLabel('Downsampling', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'MTurnDownSample') fbl.addRow(lbl, wid) lbl = QLabel('Index', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'MTurnIdx') fbl.addRow(lbl, wid) lbl = QLabel('Index Time', grp_bx, alignment=Qt.AlignCenter) wid = QWidget(grp_bx) pdm_lbl = SiriusLabel( wid, self.devpref.substitute(propty='MTurnIdxTime-Mon')) pdm_lbl.showUnits = True pdm_lbl.setAlignment(Qt.AlignCenter) conf = PyDMPushButton( wid, pressValue=1, init_channel=self.devpref.substitute(propty='MTurnAcquire-Cmd')) conf.setToolTip('Update MTurn PVs') conf.setIcon(qta.icon('fa5s.sync')) conf.setObjectName('conf') conf.setStyleSheet( '#conf{min-width:25px; max-width:25px; icon-size:20px;}') hbl = QHBoxLayout(wid) hbl.addWidget(pdm_lbl) hbl.addWidget(conf) fbl.addRow(lbl, wid) lbl = QLabel('TbT Sync', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_butled(grp_bx, 'MTurnSyncTim') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('TbT Mask', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_butled(grp_bx, 'MTurnUseMask') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('Mask Begin', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'MTurnMaskSplBeg') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('Mask End', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'MTurnMaskSplEnd') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) return grp_bx
class ICTChannelEntry(QFrame): def __init__(self, side, num): self.side = side self.num = num self.layout = QHBoxLayout() self.setLayout(self.layout) self.objectName = 'ICT_Channel_' + str(side) + str(num) # Add the toggle button colorButtonTable = { "CLOSED": [ "rgb(0, 255, 0)", # Background "rgb(0, 0, 0)" # Foreground ], "OPEN": ["rgb(255, 0, 0)", "rgb(255, 255, 255)"] } colorButtonLabelTable = {"ENABLED": "ONLINE", "DISABLED": "OFFLINE"} # Add the OFF button self.offBtn = PyDMPushButton( parent=self, label='TURN OFF', pressValue='1', init_channel='ca://$\{BASE\}:Output{0}{1}:SetState'.format( num, side)) self.offBtn.setStyleSheet("\ PyDMPushButton { \ background-color: rgb(255, 0, 0); \ color: rgb(255, 255, 255); \ }") self.layout.addWidget(self.offBtn) # Add the ON button self.onBtn = PyDMPushButton( parent=self, label='TURN ON', pressValue='0', init_channel='ca://$\{BASE\}:Output{0}{1}:SetState'.format( num, side)) self.onBtn.setStyleSheet("\ PyDMPushButton { \ background-color: rgb(0, 255, 0); \ color: rgb(0, 0, 0); \ }") self.layout.addWidget(self.onBtn) self.setLayout(self.layout)
class ModEmerStopDialog(SiriusDialog): """Modulator Emergency Stop Window.""" def __init__(self, parent=None, device='', prefix=VACA_PREFIX): """Init.""" super().__init__(parent) self.setObjectName('LIApp') self._prefix = prefix self._device = _PVName(device) self._mod_prefix = self._device.substitute(prefix=prefix) self.setWindowTitle(self._device.dev + ' ' + self._device.idx + ' - Emergency Stop') self._setupUi() def _setupUi(self): self._lb_desc = QLabel('<h3>Are you sure to Poweroff ' + self._device.dev + ' ' + self._device.idx + '?</h3>') self._pb_yes = PyDMPushButton(self, label='YES', pressValue=1, init_channel=self._mod_prefix + ':EMER_STOP') self._pb_yes.setObjectName('yes') self._pb_yes.setStyleSheet('#yes{background-color:red;}') self._pb_exit = QPushButton('EXIT', self) self._pb_exit.clicked.connect(self.close) lay = QGridLayout(self) lay.setHorizontalSpacing(20) lay.setVerticalSpacing(20) lay.addWidget(self._lb_desc, 0, 0, 1, 2) lay.addWidget(self._pb_yes, 1, 0, alignment=Qt.AlignCenter) lay.addWidget(self._pb_exit, 1, 1, alignment=Qt.AlignCenter)
def get_manual_correction_widget(self, parent): """.""" man_wid = QWidget(parent) man_wid.setObjectName('grp') gdl = QGridLayout(man_wid) gdl.setSpacing(9) calc = PyDMPushButton( man_wid, '', pressValue=1, init_channel=self.devpref.substitute(propty='CalcDelta-Cmd')) calc.setIcon(qta.icon('mdi.calculator-variant')) calc.setToolTip('Calculate Kicks') calc.setObjectName('button') calc.setStyleSheet('#button {\ min-height: 45px; min-width: 45px;\ max-height: 45px; max-width: 45px;\ icon-size: 40px;}') rules = ( '[{"name": "EnblRule", "property": "Enable", ' + '"expression": "not ch[0]", "channels": [{"channel": "' + self.devpref.substitute(propty='LoopState-Sts') + '", "trigger": true}]}]') calc.rules = rules if self.acc == 'BO': gdl.addWidget(calc, 1, 1) gdl.setColumnStretch(0, 2) gdl.setColumnStretch(2, 2) gdl.setRowStretch(0, 2) gdl.setRowStretch(2, 2) return man_wid exp = 'ch[0] in (1, 2, 3)' ch = '' if self.isring: exp = 'ch[1] in (1, 2, 3) and not ch[0]' ch = '{"channel": "' + self.devpref.substitute( propty='LoopState-Sts') + '", "trigger": true},' rules = ( '[{"name": "EnblRule", "property": "Enable", ' + '"expression": "'+exp+'", "channels": ['+ch + '{"channel": "'+self.devpref.substitute(propty='SOFBMode-Sts') + '", "trigger": true}]}]') lst = [ ('All', self._csorb.ApplyDelta.All), ('CH', self._csorb.ApplyDelta.CH), ('CV', self._csorb.ApplyDelta.CV)] if self.acc in {'SI', 'BO'}: lst.append(('RF', self._csorb.ApplyDelta.RF)) btns = dict() for itm, val in lst: btn = PyDMPushButton( man_wid, ' '+itm, pressValue=val, init_channel=self.devpref.substitute(propty='ApplyDelta-Cmd')) btn.rules = rules btn.setIcon(qta.icon('fa5s.hammer')) btn.setToolTip('Apply ' + itm) btn.setObjectName('button') btn.setStyleSheet('#button {\ min-height: 25px; min-width: 45px;\ max-height: 25px;\ icon-size: 20px;}') if self.acc == 'BO': btn.setVisible(False) btns[itm] = btn gdl.addWidget(calc, 0, 0, 2, 1) gdl.addWidget(btns['CH'], 0, 1) gdl.addWidget(btns['CV'], 0, 2) if self.acc in {'SI', 'BO'}: gdl.addWidget(btns['RF'], 0, 3) gdl.addWidget(btns['All'], 1, 1, 1, 3) else: gdl.addWidget(btns['All'], 1, 1, 1, 2) gdl.setColumnMinimumWidth(0, 60) grpbx = QWidget(man_wid) grpbx.setObjectName('gbx') if self.acc in {'SI', 'BO'}: planes = ('CH', 'CV', 'RF') gdl.addWidget(grpbx, 2, 0, 1, 4) else: planes = ('CH', 'CV') gdl.addWidget(grpbx, 2, 0, 1, 3) fbl = QFormLayout(grpbx) for pln in planes: lbl = QLabel(pln+' [%] ', grpbx) lbl.setObjectName('lbl') lbl.setStyleSheet('#lbl{min-height:1em;}') wid = self.create_pair(grpbx, 'ManCorrGain'+pln) wid.setObjectName('wid') wid.setStyleSheet('#wid{min-height:1.2em;}') if self.acc == 'BO': lbl.setVisible(False) wid.setVisible(False) fbl.addRow(lbl, wid) vlay = QVBoxLayout() vlay.addStretch() gdl.addLayout(vlay, 3, 0) return man_wid
class BPMOrbIntlkDetailWindow(BaseObject, SiriusMainWindow): """Individual BPM Orbit Interlock Window.""" def __init__(self, parent=None, prefix=_vaca_prefix, device=''): """Init.""" BaseObject.__init__(self, prefix) SiriusMainWindow.__init__(self, parent) self.prefix = prefix self.device = SiriusPVName(device) self.devpref = self.device.substitute(prefix=prefix) self.setObjectName('SIApp') self.setWindowTitle(device + ' Orbit Interlock Control Window') self._setupUi() self.setFocusPolicy(Qt.StrongFocus) def _setupUi(self): wid = QWidget(self) self.setCentralWidget(wid) title = QLabel('<h3>' + self.device + ' Orbit Interlock Control</h3>', self, alignment=Qt.AlignCenter) title.setStyleSheet("font-weight: bold;") # General Interlock self._gb_gen = QGroupBox('General Interlock') lay_gen = self._setupIntlkGenLayout() self._gb_gen.setLayout(lay_gen) # Translation Interlock self._gb_trans = QGroupBox('Translation Interlock') lay_trans = self._setupIntlkTypeLayout('Trans') self._gb_trans.setLayout(lay_trans) # Angulation Interlock self._gb_ang = QGroupBox('Angulation Interlock') lay_ang = self._setupIntlkTypeLayout('Ang') self._gb_ang.setLayout(lay_ang) lay = QGridLayout(wid) lay.addWidget(title, 0, 0, 1, 2) lay.addWidget(self._gb_gen, 1, 0, 1, 2) lay.addWidget(self._gb_trans, 2, 0) lay.addWidget(self._gb_ang, 2, 1) def _setupIntlkGenLayout(self): self._ld_genenbl = QLabel('Enable: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) self._sb_genenbl = PyDMStateButton( self, self.devpref.substitute(propty='IntlkEn-Sel')) self._led_genenbl = SiriusLedState( self, self.devpref.substitute(propty='IntlkEn-Sts')) self._ld_genclr = QLabel('Reset: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) self._bt_genclr = PyDMPushButton( self, init_channel=self.devpref.substitute(propty='IntlkClr-Sel'), pressValue=1) self._bt_genclr.setIcon(qta.icon('fa5s.sync')) self._bt_genclr.setObjectName('clr') self._bt_genclr.setStyleSheet( '#clr{min-width:25px; max-width:25px; icon-size:20px;}') self._ld_intlkinst = QLabel('Intantaneous Interlock: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) self._led_intlkinst = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk-Mon')) self._ld_intlkltc = QLabel('Latch Interlock: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) self._led_intlkltc = SiriusLedAlert( self, self.devpref.substitute(propty='IntlkLtc-Mon')) self._ld_minsumenbl = QLabel('Min.Sum.Thres. Enable: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) self._ld_minsumenbl.setToolTip( 'If enabled, enable interlock only if minimum sum' ' threshold is exceeded.') self._sb_minsumenbl = PyDMStateButton( self, self.devpref.substitute(propty='IntlkMinSumEn-Sel')) self._led_minsumenbl = SiriusLedState( self, self.devpref.substitute(propty='IntlkMinSumEn-Sts')) self._ld_minsumlim = QLabel('Min.Sum.Thres.[sum count]: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) self._sb_minsumlim = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmtMinSum-SP')) self._sb_minsumlim.showStepExponent = False self._sb_minsumlim.limitsFromChannel = False self._sb_minsumlim.setMinimum(-1e12) self._sb_minsumlim.setMaximum(+1e12) self._lb_minsumlim = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmtMinSum-RB')) lay = QGridLayout() lay.setAlignment(Qt.AlignCenter) lay.addWidget(self._ld_genenbl, 0, 0) lay.addWidget(self._sb_genenbl, 0, 1) lay.addWidget(self._led_genenbl, 0, 2) lay.addWidget(self._ld_genclr, 1, 0) lay.addWidget(self._bt_genclr, 1, 1, alignment=Qt.AlignCenter) lay.addWidget(self._ld_intlkinst, 2, 0) lay.addWidget(self._led_intlkinst, 2, 1) lay.addWidget(self._ld_intlkltc, 3, 0) lay.addWidget(self._led_intlkltc, 3, 1) lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 4, 0) lay.addWidget(self._ld_minsumenbl, 5, 0) lay.addWidget(self._sb_minsumenbl, 5, 1) lay.addWidget(self._led_minsumenbl, 5, 2) lay.addWidget(self._ld_minsumlim, 6, 0) lay.addWidget(self._sb_minsumlim, 6, 1) lay.addWidget(self._lb_minsumlim, 6, 2) return lay def _setupIntlkTypeLayout(self, intlk): unit = 'nm' ld_enbl = QLabel('Enable: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) sb_enbl = PyDMStateButton( self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sel')) led_enbl = SiriusLedState( self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sts')) ld_clr = QLabel('Reset: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) bt_clr = PyDMPushButton(self, init_channel=self.devpref.substitute( propty='Intlk' + intlk + 'Clr-Sel'), pressValue=1) bt_clr.setIcon(qta.icon('fa5s.sync')) bt_clr.setObjectName('clr') bt_clr.setStyleSheet( '#clr{min-width:25px; max-width:25px; icon-size:20px;}') ld_minx = QLabel('Min.X Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_minx = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-SP')) sb_minx.showStepExponent = False sb_minx.limitsFromChannel = False sb_minx.setMinimum(-1e9) sb_minx.setMaximum(+1e9) lb_minx = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-RB')) ld_maxx = QLabel('Max.X Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_maxx = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-SP')) sb_maxx.showStepExponent = False sb_maxx.limitsFromChannel = False sb_maxx.setMinimum(-1e9) sb_maxx.setMaximum(+1e9) lb_maxx = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-RB')) ld_miny = QLabel('Min.Y Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_miny = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-SP')) sb_miny.showStepExponent = False sb_miny.limitsFromChannel = False sb_miny.setMinimum(-1e9) sb_miny.setMaximum(+1e9) lb_miny = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-RB')) ld_maxy = QLabel('Max.Y Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_maxy = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-SP')) sb_maxy.showStepExponent = False sb_maxy.limitsFromChannel = False sb_maxy.setMinimum(-1e9) sb_maxy.setMaximum(+1e9) lb_maxy = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-RB')) ld_leglow = QLabel('Smaller', self, alignment=Qt.AlignCenter) ld_leghigh = QLabel('Bigger', self, alignment=Qt.AlignCenter) ld_legmask = QLabel('<h4>Masked By Enable</h4>', self, alignment=Qt.AlignCenter) ld_legmask_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_mask_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'Smaller-Mon')) led_mask_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'Bigger-Mon')) ld_leginst = QLabel('<h4>Instantaneous</h4>', self, alignment=Qt.AlignCenter) ld_leginst_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerAny-Mon')) led_inst_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerAny-Mon')) ld_leginst_x = QLabel('X', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_xlow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerX-Mon')) led_inst_xhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerX-Mon')) ld_leginst_y = QLabel('Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_ylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerY-Mon')) led_inst_yhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerY-Mon')) ld_legltc = QLabel('<h4>Latch</h4>', self, alignment=Qt.AlignCenter) ld_legltc_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtc-Mon')) led_ltc_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtc-Mon')) ld_legltc_x = QLabel('X', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_xlow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtcX-Mon')) led_ltc_xhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcX-Mon')) ld_legltc_y = QLabel('Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_ylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtcY-Mon')) led_ltc_yhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcY-Mon')) lay_mon = QGridLayout() lay_mon.setAlignment(Qt.AlignCenter) lay_mon.addWidget(ld_leglow, 0, 1) lay_mon.addWidget(ld_leghigh, 0, 2) lay_mon.addWidget(ld_legmask, 1, 0) lay_mon.addWidget(ld_legmask_any, 2, 0) lay_mon.addWidget(led_mask_anylow, 2, 1) lay_mon.addWidget(led_mask_anyhigh, 2, 2) lay_mon.addWidget(ld_leginst, 3, 0) lay_mon.addWidget(ld_leginst_any, 4, 0) lay_mon.addWidget(led_inst_anylow, 4, 1) lay_mon.addWidget(led_inst_anyhigh, 4, 2) lay_mon.addWidget(ld_leginst_x, 5, 0) lay_mon.addWidget(led_inst_xlow, 5, 1) lay_mon.addWidget(led_inst_xhigh, 5, 2) lay_mon.addWidget(ld_leginst_y, 6, 0) lay_mon.addWidget(led_inst_ylow, 6, 1) lay_mon.addWidget(led_inst_yhigh, 6, 2) lay_mon.addWidget(ld_legltc, 7, 0) lay_mon.addWidget(ld_legltc_any, 8, 0) lay_mon.addWidget(led_ltc_anylow, 8, 1) lay_mon.addWidget(led_ltc_anyhigh, 8, 2) lay_mon.addWidget(ld_legltc_x, 9, 0) lay_mon.addWidget(led_ltc_xlow, 9, 1) lay_mon.addWidget(led_ltc_xhigh, 9, 2) lay_mon.addWidget(ld_legltc_y, 10, 0) lay_mon.addWidget(led_ltc_ylow, 10, 1) lay_mon.addWidget(led_ltc_yhigh, 10, 2) lay = QGridLayout() lay.setAlignment(Qt.AlignTop) lay.addWidget(ld_enbl, 0, 0) lay.addWidget(sb_enbl, 0, 1) lay.addWidget(led_enbl, 0, 2) lay.addWidget(ld_clr, 1, 0) lay.addWidget(bt_clr, 1, 1, alignment=Qt.AlignCenter) lay.addWidget(ld_minx, 2, 0) lay.addWidget(sb_minx, 2, 1) lay.addWidget(lb_minx, 2, 2) lay.addWidget(ld_maxx, 3, 0) lay.addWidget(sb_maxx, 3, 1) lay.addWidget(lb_maxx, 3, 2) lay.addWidget(ld_miny, 4, 0) lay.addWidget(sb_miny, 4, 1) lay.addWidget(lb_miny, 4, 2) lay.addWidget(ld_maxy, 5, 0) lay.addWidget(sb_maxy, 5, 1) lay.addWidget(lb_maxy, 5, 2) lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 6, 0) lay.addLayout(lay_mon, 7, 0, 1, 3) return lay
class InjCtrlWindow(SiriusMainWindow): """InjCtrl Main Window.""" showMonitor = Signal() showStatus = Signal() showEgun = Signal() def __init__(self, parent=None, prefix=''): """Init.""" super().__init__(parent) self._prefix = prefix self._inj_dev = SiriusPVName('AS-Glob:AP-InjCtrl') self._inj_prefix = self._inj_dev.substitute(prefix=prefix) self.setWindowTitle('Injection Controls') self.setObjectName('ASApp') self.setWindowIcon( qta.icon('fa5s.syringe', color=get_appropriate_color('AS'))) self._setupUi() self.setFocus(True) self.setFocusPolicy(Qt.StrongFocus) def _setupUi(self): self.title = QLabel('<h3>Injection Control<h3>', self, alignment=Qt.AlignCenter) self.title.setStyleSheet('QLabel{max-height:1.6em;}') self.wid_comm = self._setupMainBarWidget() self.wid_comm.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed) self.wid_sett = self._setupSettingsWidget() self.wid_sett.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.MinimumExpanding) self.wid_mon = self._setupMonitorWidget() self.wid_log = self._setupLogWidget() wid_row = QWidget() wid_row.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed) hbox_row = QHBoxLayout(wid_row) hbox_row.setContentsMargins(0, 0, 0, 0) hbox_row.setStretch(0, 3) hbox_row.setStretch(1, 5) hbox_row.addWidget(self.wid_mon) hbox_row.addWidget(self.wid_log) wid = QWidget(self) lay = QVBoxLayout(wid) lay.addWidget(self.title) lay.addWidget(self.wid_comm) lay.addWidget(self.wid_comm) lay.addWidget(self.wid_sett) lay.addWidget(wid_row) lay.setStretch(1, 1) lay.setStretch(2, 3) lay.setStretch(3, 2) self.setCentralWidget(wid) self._ch_injmode = SiriusConnectionSignal( self._inj_prefix.substitute(propty='Mode-Sel')) self._ch_injmode.new_value_signal[int].connect( self._handle_injmode_settings_vis) # connect window signals connect_newprocess(self, 'sirius-hla-as-ap-monitor.py', parent=self, signal=self.showMonitor) connect_newprocess(self, 'sirius-hla-si-ap-genstatus.py', parent=self, signal=self.showStatus) connect_newprocess(self, 'sirius-hla-li-eg-control.py', parent=self, signal=self.showEgun) def _setupMainBarWidget(self): # Shift machshift_pvname = SiriusPVName( 'AS-Glob:AP-MachShift:Mode-Sel').substitute(prefix=self._prefix) self._cb_shift = SiriusEnumComboBox(self, machshift_pvname) self._lb_shift = MachShiftLabel(self, prefix=self._prefix) self._lb_shift.setStyleSheet( 'QLabel{max-height: 2em; min-width: 7em;}') self.wid_shift = QGroupBox('Mach.Shift', self) lay_shift = QVBoxLayout(self.wid_shift) lay_shift.addWidget(self._cb_shift) lay_shift.addWidget(self._lb_shift) # Injection System self.wid_is_summ = InjSysStbyControlWidget(self, is_summary=True) self.wid_injsys = QGroupBox('Inj.System', self) lay_injsys = QGridLayout(self.wid_injsys) lay_injsys.setContentsMargins(0, 0, 0, 0) lay_injsys.addWidget(self.wid_is_summ, 0, 0) # self.wid_is_full = InjSysStbyControlWidget(self, is_summary=False) # self.wid_is_full.setVisible(False) # lay_injsys.addWidget(self.wid_is_full, 0, 0) # self._icon_expd = qta.icon('fa5s.plus') # self._icon_comp = qta.icon('fa5s.minus') # self.bt_is_tgl = QPushButton(self._icon_expd, '', self) # self.bt_is_tgl.clicked.connect(self._handle_injsys_details_vis) # self.bt_is_tgl.setObjectName('bt') # self.bt_is_tgl.setStyleSheet(""" # #bt{ # min-width: 0.8em; max-width: 0.8em; # min-height: 0.8em; max-height: 0.8em; # icon-size:12px;} # """) # lay_injsys.addWidget( # self.bt_is_tgl, 0, 1, alignment=Qt.AlignRight | Qt.AlignBottom) # EGun egun_dev = SiriusPVName('LI-01:EG-TriggerPS').substitute( prefix=self._prefix) self._sb_eguntrg = PyDMStateButton( self, egun_dev.substitute(propty_name='enable')) self._led_eguntrg = SiriusLedState( self, egun_dev.substitute(propty_name='enablereal')) self._led_eguntrg.setStyleSheet( 'QLed{min-width: 1.29em; max-width: 1.29em;}') self.wid_egun = self._create_groupwidget('EGun Trig.', [ self._sb_eguntrg, ], [ self._led_eguntrg, ]) # Injection self._pb_tiinj = EVGInjectionButton(self, self._prefix) self._pb_topup = PyDMStateButton( self, init_channel=self._inj_prefix.substitute(propty='TopUpState-Sel')) self._pb_topup.setVisible(False) self._led_injti = EVGInjectionLed(self, self._prefix) self._lb_injcnt = PyDMLabel(self) self._lb_injcnt.setToolTip( 'Count injection pulses when Egun Trigger is enabled.') ch_injcnt = SiriusPVName( 'AS-Glob:AP-CurrInfo:InjCount-Mon').substitute(prefix=self._prefix) self._lb_injcnt.channel = ch_injcnt self._lb_injcnt.setStyleSheet('QLabel{max-width: 3.5em;}') hbox_injsts = QHBoxLayout() hbox_injsts.setContentsMargins(0, 0, 0, 0) hbox_injsts.addWidget(self._led_injti) hbox_injsts.addWidget(self._lb_injcnt) self.wid_inj = QGroupBox('Injection', self) lay_inj = QGridLayout(self.wid_inj) lay_inj.setAlignment(Qt.AlignCenter) lay_inj.addWidget(self._pb_tiinj, 0, 0) lay_inj.addWidget(self._pb_topup, 0, 0) lay_inj.addLayout(hbox_injsts, 1, 0) # Current curr_pvname = SiriusPVName( 'SI-Glob:AP-CurrInfo:Current-Mon').substitute(prefix=self._prefix) self._lb_curr = PyDMLabel(self, curr_pvname) self._lb_curr.showUnits = True self._lb_curr.setStyleSheet(""" QLabel{ font-size: 18pt; qproperty-alignment: AlignCenter; min-width: 5.5em; max-width: 5.5em; }""") self.wid_curr = QGroupBox('Current', self) lay_curr = QHBoxLayout(self.wid_curr) lay_curr.addWidget(self._lb_curr) # TopUp status self._lb_tusts = PyDMLabel( self, self._inj_prefix.substitute(propty='TopUpState-Sts')) self._lb_tusts.setAlignment(Qt.AlignCenter) self._lb_tusts.setStyleSheet('QLabel{max-height:2em;}') self._ld_tunow = QLabel('Now:', self, alignment=Qt.AlignRight | Qt.AlignVCenter) self._lb_tunow = ClockLabel(self) self._lb_tunow.setStyleSheet('QLabel{max-height:2em;}') self._ld_tunxt = QLabel('Next:', self, alignment=Qt.AlignRight | Qt.AlignVCenter) self._lb_tunxt = SiriusLabel( self, self._inj_prefix.substitute(propty='TopUpNextInj-Mon')) self._lb_tunxt.displayFormat = SiriusLabel.DisplayFormat.Time self._lb_tunxt.setAlignment(Qt.AlignCenter) self._lb_tunxt.setStyleSheet('QLabel{max-height:2em;}') self._pb_round = PyDMPushButton( self, label='', icon=qta.icon('mdi.tilde'), pressValue=1, init_channel=self._inj_prefix.substitute( propty='TopUpNextInjRound-Cmd')) self._pb_round.setObjectName('but') self._pb_round.setStyleSheet( '#but{min-width:18px; max-width:18px; icon-size:16px;}') self.wid_tusts = QGroupBox('Top-up status') self.wid_tusts.setVisible(False) lay_tusts = QGridLayout(self.wid_tusts) lay_tusts.addWidget(self._lb_tusts, 0, 0, 1, 2) lay_tusts.addWidget(self._ld_tunow, 1, 0) lay_tusts.addWidget(self._lb_tunow, 1, 1) lay_tusts.addWidget(self._ld_tunxt, 2, 0) lay_tusts.addWidget(self._lb_tunxt, 2, 1) lay_tusts.addWidget(self._pb_round, 2, 2) wid = QWidget() lay = QGridLayout(wid) lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(self.wid_shift, 0, 0) lay.addWidget(self.wid_injsys, 0, 1) lay.addWidget(self.wid_egun, 0, 2) lay.addWidget(self.wid_inj, 0, 3) lay.addWidget(self.wid_tusts, 0, 4) lay.addWidget(self.wid_curr, 0, 5) lay.setColumnStretch(0, 3) lay.setColumnStretch(1, 2) lay.setColumnStretch(2, 2) lay.setColumnStretch(3, 2) lay.setColumnStretch(4, 4) lay.setColumnStretch(5, 3) wid.setStyleSheet('.QLabel{min-height: 1em; max-height: 1em;}') return wid def _setupSettingsWidget(self): # group of labels to set the same stylesheet labelsdesc, labelsmon = list(), list() # Mode self._ld_injmode = QLabel('Mode', self) labelsdesc.append(self._ld_injmode) self._cb_injmode = SiriusEnumComboBox( self, self._inj_prefix.substitute(propty='Mode-Sel')) self._lb_injmode = PyDMLabel( self, self._inj_prefix.substitute(propty='Mode-Sts')) self._lb_injmode.showUnits = True labelsmon.append(self._lb_injmode) # Target current self._ld_currtgt = QLabel('Target Curr.', self) labelsdesc.append(self._ld_currtgt) self._sb_currtgt = SiriusSpinbox( self, self._inj_prefix.substitute(propty='TargetCurrent-SP')) self._sb_currtgt.showStepExponent = False self._lb_currtgt = PyDMLabel( self, self._inj_prefix.substitute(propty='TargetCurrent-RB')) self._lb_currtgt.showUnits = True labelsmon.append(self._lb_currtgt) # mode specific configurations self.wid_dcdtls = self._setupDecayModeWidget() self.wid_tudtls = self._setupTopUpModeWidget() self.wid_tudtls.setVisible(False) # Mon self._ld_injset = QLabel('Setup ok', self) labelsdesc.append(self._ld_injset) self._led_injset = InjDiagLed(self) # Type self._ld_injtype = QLabel('Type', self) labelsdesc.append(self._ld_injtype) self._cb_injtype = SiriusEnumComboBox( self, self._inj_prefix.substitute(propty='Type-Sel')) self._lb_injtype = PyDMLabel( self, self._inj_prefix.substitute(propty='Type-Sts')) labelsmon.append(self._lb_injtype) self._lb_injtype_mon = PyDMLabel( self, self._inj_prefix.substitute(propty='Type-Mon')) labelsmon.append(self._lb_injtype_mon) self._ch_injtype = SiriusConnectionSignal( self._inj_prefix.substitute(propty='Type-Sel')) self._ch_injtype.new_value_signal[int].connect( self._handle_injtype_settings_vis) # Single bunch bias voltage self._ld_sbbias = QLabel('SB Bias Voltage', self) labelsdesc.append(self._ld_sbbias) self._sb_sbbias = SiriusSpinbox( self, self._inj_prefix.substitute(propty='SglBunBiasVolt-SP')) self._sb_sbbias.showStepExponent = False self._lb_sbbias = PyDMLabel( self, self._inj_prefix.substitute(propty='SglBunBiasVolt-RB')) self._lb_sbbias.showUnits = True labelsmon.append(self._lb_sbbias) self._ld_sbbias.setVisible(False) self._sb_sbbias.setVisible(False) self._lb_sbbias.setVisible(False) # Multi bunch bias voltage self._ld_mbbias = QLabel('MB Bias Volt.', self) labelsdesc.append(self._ld_mbbias) self._sb_mbbias = SiriusSpinbox( self, self._inj_prefix.substitute(propty='MultBunBiasVolt-SP')) self._sb_mbbias.showStepExponent = False self._lb_mbbias = PyDMLabel( self, self._inj_prefix.substitute(propty='MultBunBiasVolt-RB')) self._lb_mbbias.showUnits = True labelsmon.append(self._lb_mbbias) # bias voltage mon ch_bias_mon = SiriusPVName('LI-01:EG-BiasPS').substitute( prefix=self._prefix, propty_name='voltinsoft') self._lb_bias_mon = PyDMLabel(self, ch_bias_mon) self._lb_bias_mon.showUnits = True labelsmon.append(self._lb_bias_mon) # Filament current op value self._ld_filaopcurr = QLabel('Fila.Op. Curr.', self) labelsdesc.append(self._ld_filaopcurr) self._sb_filaopcurr = SiriusSpinbox( self, self._inj_prefix.substitute(propty='FilaOpCurr-SP')) self._sb_filaopcurr.showStepExponent = False self._lb_filaopcurr = PyDMLabel( self, self._inj_prefix.substitute(propty='FilaOpCurr-RB')) self._lb_filaopcurr.showUnits = True labelsmon.append(self._lb_filaopcurr) ch_filacurr_mon = SiriusPVName('LI-01:EG-FilaPS').substitute( prefix=self._prefix, propty_name='currentinsoft') self._lb_filaopcurr_mon = PyDMLabel(self, ch_filacurr_mon) self._lb_filaopcurr_mon.showUnits = True labelsmon.append(self._lb_filaopcurr_mon) # High voltage op value self._ld_hvopvolt = QLabel('HV.Op. Volt.', self) labelsdesc.append(self._ld_hvopvolt) self._sb_hvopvolt = SiriusSpinbox( self, self._inj_prefix.substitute(propty='HVOpVolt-SP')) self._sb_hvopvolt.showStepExponent = False self._lb_hvopvolt = PyDMLabel( self, self._inj_prefix.substitute(propty='HVOpVolt-RB')) self._lb_hvopvolt.showUnits = True labelsmon.append(self._lb_hvopvolt) ch_hvvolt_mon = SiriusPVName('LI-01:EG-HVPS').substitute( prefix=self._prefix, propty_name='voltinsoft') self._lb_hvopvolt_mon = PyDMLabel(self, ch_hvvolt_mon) self._lb_hvopvolt_mon.showUnits = True labelsmon.append(self._lb_hvopvolt_mon) # header ld_sp = QLabel('<h4>SP</h4>', self, alignment=Qt.AlignCenter) ld_rb = QLabel('<h4>RB</h4>', self, alignment=Qt.AlignCenter) ld_mon = QLabel('<h4>Mon</h4>', self, alignment=Qt.AlignCenter) # Bucket list self._wid_bl = BucketList(self, prefix=self._prefix, min_size=15, show_graph=True) self._wid_bl.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.MinimumExpanding) wid1 = QWidget() wid1.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed) glay1 = QGridLayout(wid1) glay1.setAlignment(Qt.AlignTop) glay1.addWidget(self._ld_injset, 0, 0) glay1.addWidget(self._led_injset, 0, 1) glay1.addWidget(self._ld_injmode, 1, 0) glay1.addWidget(self._cb_injmode, 1, 1) glay1.addWidget(self._lb_injmode, 1, 2) glay1.addWidget(self._ld_currtgt, 2, 0) glay1.addWidget(self._sb_currtgt, 2, 1) glay1.addWidget(self._lb_currtgt, 2, 2) glay1.addWidget(self.wid_tudtls, 3, 0, 2, 3) glay1.addWidget(self.wid_dcdtls, 3, 0, 2, 3) glay1.setColumnStretch(0, 3) glay1.setColumnStretch(1, 2) glay1.setColumnStretch(2, 2) wid2 = QWidget() wid2.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Fixed) glay2 = QGridLayout(wid2) glay2.setAlignment(Qt.AlignTop) glay2.addWidget(ld_sp, 0, 1) glay2.addWidget(ld_rb, 0, 2) glay2.addWidget(ld_mon, 0, 3) glay2.addWidget(self._ld_injtype, 1, 0) glay2.addWidget(self._cb_injtype, 1, 1) glay2.addWidget(self._lb_injtype, 1, 2) glay2.addWidget(self._lb_injtype_mon, 1, 3) glay2.addWidget(self._ld_sbbias, 2, 0) glay2.addWidget(self._sb_sbbias, 2, 1) glay2.addWidget(self._lb_sbbias, 2, 2) glay2.addWidget(self._ld_mbbias, 2, 0) glay2.addWidget(self._sb_mbbias, 2, 1) glay2.addWidget(self._lb_mbbias, 2, 2) glay2.addWidget(self._lb_bias_mon, 2, 3) glay2.addWidget(self._ld_filaopcurr, 4, 0) glay2.addWidget(self._sb_filaopcurr, 4, 1) glay2.addWidget(self._lb_filaopcurr, 4, 2) glay2.addWidget(self._lb_filaopcurr_mon, 4, 3) glay2.addWidget(self._ld_hvopvolt, 5, 0) glay2.addWidget(self._sb_hvopvolt, 5, 1) glay2.addWidget(self._lb_hvopvolt, 5, 2) glay2.addWidget(self._lb_hvopvolt_mon, 5, 3) glay2.setColumnStretch(0, 3) glay2.setColumnStretch(1, 2) glay2.setColumnStretch(2, 2) glay2.setColumnStretch(3, 2) wid = QGroupBox('Settings') lay = QGridLayout(wid) lay.addWidget(wid1, 0, 0, alignment=Qt.AlignTop) lay.addWidget(wid2, 0, 1, alignment=Qt.AlignTop) lay.addWidget(self._wid_bl, 1, 0, 1, 2) lay.setColumnStretch(0, 3) lay.setColumnStretch(1, 4) for lbl in labelsdesc: lbl.setStyleSheet(""" QLabel{ min-width: 6.5em; max-width: 6.5em; min-height: 1.5em; qproperty-alignment: 'AlignRight | AlignVCenter'; }""") for lbl in labelsmon: lbl.setStyleSheet("PyDMLabel{qproperty-alignment: AlignCenter;}") return wid def _setupTopUpModeWidget(self): self._ld_tuperd = QLabel('Period', self) self._sb_tuperd = SiriusSpinbox( self, self._inj_prefix.substitute(propty='TopUpPeriod-SP')) self._sb_tuperd.showStepExponent = False self._lb_tuperd = PyDMLabel( self, self._inj_prefix.substitute(propty='TopUpPeriod-RB')) self._lb_tuperd.showUnits = True self._ld_tumaxpu = QLabel('Max.Nr.Pulses', self) self._sb_tumaxpu = SiriusSpinbox( self, self._inj_prefix.substitute(propty='TopUpMaxNrPulses-SP')) self._sb_tumaxpu.showStepExponent = False self._lb_tumaxpu = PyDMLabel( self, self._inj_prefix.substitute(propty='TopUpMaxNrPulses-RB')) self._lb_tumaxpu.showUnits = True wid = QWidget() lay = QGridLayout(wid) lay.setContentsMargins(0, 6, 0, 0) lay.setAlignment(Qt.AlignTop) lay.addWidget(self._ld_tuperd, 0, 0) lay.addWidget(self._sb_tuperd, 0, 1) lay.addWidget(self._lb_tuperd, 0, 2) lay.addWidget(self._ld_tumaxpu, 1, 0) lay.addWidget(self._sb_tumaxpu, 1, 1) lay.addWidget(self._lb_tumaxpu, 1, 2) lay.setColumnStretch(0, 3) lay.setColumnStretch(1, 2) lay.setColumnStretch(2, 2) wid.setStyleSheet(""" .QLabel{ min-width: 6.5em; max-width: 6.5em; min-height: 1.5em; qproperty-alignment: 'AlignRight | AlignVCenter'; } PyDMLabel{ qproperty-alignment: AlignCenter; }""") return wid def _setupDecayModeWidget(self): self._ld_autostop = QLabel('Auto Stop', self) self._cb_autostop = PyDMStateButton( self, self._inj_prefix.substitute(propty='AutoStop-Sel')) self._cb_autostop.shape = 1 self._led_autostop = SiriusLedState( self, self._inj_prefix.substitute(propty='AutoStop-Sts')) wid = QWidget() lay = QGridLayout(wid) lay.setAlignment(Qt.AlignTop) lay.setContentsMargins(0, 6, 0, 0) lay.addWidget(self._ld_autostop, 0, 0) lay.addWidget(self._cb_autostop, 0, 1) lay.addWidget(self._led_autostop, 0, 2) lay.setColumnStretch(0, 3) lay.setColumnStretch(1, 2) lay.setColumnStretch(2, 2) wid.setStyleSheet(""" .QLabel{ min-width: 6.5em; max-width: 6.5em; min-height: 1.5em; qproperty-alignment: 'AlignRight | AlignVCenter'; } PyDMLabel{ qproperty-alignment: AlignCenter; }""") return wid def _setupLogWidget(self): self._log = PyDMLogLabel(self, self._inj_prefix.substitute(propty='Log-Mon'), [ 'Remaining time', ]) wid = QGroupBox('Log') lay = QHBoxLayout(wid) lay.addWidget(self._log) return wid def _setupMonitorWidget(self): self.wid_mon = MonitorSummaryWidget(self) wid = QWidget(self) lay = QGridLayout(wid) lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(self.wid_mon, 0, 0) return wid # ---- auxiliary commands ---- @Slot(int) def _handle_injtype_settings_vis(self, new_type): is_sb = new_type == _Const.InjType.SingleBunch self._ld_sbbias.setVisible(is_sb) self._sb_sbbias.setVisible(is_sb) self._lb_sbbias.setVisible(is_sb) self._ld_mbbias.setVisible(not is_sb) self._sb_mbbias.setVisible(not is_sb) self._lb_mbbias.setVisible(not is_sb) self.centralWidget().adjustSize() self.adjustSize() @Slot(int) def _handle_injmode_settings_vis(self, new_mode): is_topoup = new_mode == _Const.InjMode.TopUp self.wid_tudtls.setVisible(is_topoup) self._pb_topup.setVisible(is_topoup) self.wid_dcdtls.setVisible(not is_topoup) self._pb_tiinj.setVisible(not is_topoup) self.wid_tusts.setVisible(is_topoup) def _handle_injsys_details_vis(self): exp = self.wid_is_summ.isVisible() icon = self._icon_comp if exp else self._icon_expd self.sender().setIcon(icon) self.wid_is_summ.setVisible(not exp) self.wid_is_full.setVisible(exp) self.centralWidget().adjustSize() self.adjustSize() def _create_groupwidget(self, title, sp_wids, rb_wids, aux_wids=None): hbox_sp = QHBoxLayout() hbox_sp.setAlignment(Qt.AlignCenter) hbox_sp.setContentsMargins(0, 0, 0, 0) for wid in sp_wids: hbox_sp.addWidget(wid) hbox_rb = QHBoxLayout() hbox_rb.setAlignment(Qt.AlignCenter) hbox_rb.setContentsMargins(0, 0, 0, 0) for wid in rb_wids: hbox_rb.addWidget(wid) box = QGroupBox(title, self) if title else QWidget(self) lay = QVBoxLayout(box) lay.setAlignment(Qt.AlignCenter) if not isinstance(box, QGroupBox): lay.setContentsMargins(0, 0, 0, 0) lay.addLayout(hbox_sp) lay.addLayout(hbox_rb) if aux_wids: hbox_aux = QHBoxLayout() hbox_aux.setAlignment(Qt.AlignCenter) hbox_aux.setContentsMargins(0, 0, 0, 0) for wid in aux_wids: hbox_aux.addWidget(wid) lay.addLayout(hbox_aux) return box # ---- events ---- def mouseDoubleClickEvent(self, event): """Implement mouseDoubleClickEvent.""" if event.button() == Qt.LeftButton: if self.wid_curr.underMouse(): self.showStatus.emit() elif self.wid_shift.underMouse(): self.showStatus.emit() elif self.wid_egun.underMouse(): self.showEgun.emit() elif self.wid_mon.underMouse(): self.showMonitor.emit() super().mouseDoubleClickEvent(event) def changeEvent(self, event): """Implement changeEvent.""" if event.type() == QEvent.FontChange: fontsize = self.app.font().pointSize() self._lb_curr.setStyleSheet('QLabel{' ' font-size: ' + str(fontsize + 8) + 'pt;' ' qproperty-alignment: AlignCenter;' ' min-width: 6em; max-width: 6em;' '}') self.ensurePolished()
def setglobalparameters(self): wid = QWidget(self.centralWidget()) wid.setSizePolicy(QSzPol.Preferred, QSzPol.Maximum) lay = QGridLayout(wid) evg_dev = SiriusPVName(LLTimeSearch.get_evg_name()) evg_pref = evg_dev.substitute(prefix=self.prefix) sp = PyDMPushButton( self, init_channel=evg_pref.substitute(propty='UpdateEvt-Cmd'), pressValue=1) sp.setIcon(qta.icon('fa5s.sync')) sp.setToolTip('Update Events Table') sp.setObjectName('but') sp.setStyleSheet( '#but{min-width:25px; max-width:25px; icon-size:20px;}') rb = PyDMLed( self, init_channel=evg_pref.substitute(propty='EvtSyncStatus-Mon')) rb.setOffColor(rb.Red) rb.setOnColor(rb.LightGreen) lay.addWidget( self._create_prop_widget('<h4>Update Evts</h4>', wid, (sp, rb)), 0, 0) sp = PyDMStateButton( self, init_channel=evg_pref.substitute(propty='ContinuousEvt-Sel')) rb = PyDMLed( self, init_channel=evg_pref.substitute(propty='ContinuousEvt-Sts')) lay.addWidget( self._create_prop_widget('<h4>Continuous</h4>', wid, (sp, rb)), 0, 1) sp = PyDMStateButton( self, init_channel=evg_pref.substitute(propty='InjectionEvt-Sel')) rb = PyDMLed( self, init_channel=evg_pref.substitute(propty='InjectionEvt-Sts')) lay.addWidget( self._create_prop_widget('<h4>Injection</h4>', wid, (sp, rb)), 0, 2) bucketlist_wid = BucketList(self.centralWidget(), evg_dev, self.prefix) bucketlist_wid.setSizePolicy(QSzPol.MinimumExpanding, QSzPol.Preferred) lay.addWidget(bucketlist_wid, 0, 3, 2, 1) hlay = QHBoxLayout() lab = QLabel('Inj Count:', wid) pydmlab = PyDMLabel( wid, init_channel=evg_pref.substitute(propty='InjCount-Mon')) pydmlab.setStyleSheet('min-width:5em;') pydmlab.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) hlay.addStretch() hlay.addWidget(lab) hlay.addWidget(pydmlab) hlay.addStretch() pydmlab = PyDMLabel( wid, init_channel=evg_pref.substitute(propty='STATEMACHINE')) pydmlab.setStyleSheet('min-width:10em;') hlay.addWidget(pydmlab) hlay.addStretch() pydmlab = PyDMLabel( wid, init_channel=evg_pref.substitute(propty='SeqCount-SP')) pydmlab.rules =\ '[{"name": "VisibleRule", "property": "Visible", ' +\ '"expression": "ch[0]==5", "channels": [{"channel": "' +\ evg_pref.substitute(propty_name='STATEMACHINE') +\ '", "trigger": true}]}]' pydmlab.setStyleSheet('min-width:3em;') hlay.addWidget(pydmlab) hlay.addStretch() lay.addItem(hlay, 1, 0, 1, 3) return wid
class SiriusScrnView(QWidget): """ Class to read Sirius screen cameras image data. To allow saving a grid correctly, control calibrationgrid_flag, which indicates if the screen is in calibration grid position. You can control it by using the method/Slot updateCalibrationGridFlag. """ save_files = Signal() def __init__(self, parent=None, prefix=_VACA_PREFIX, device=None): """Initialize object.""" QWidget.__init__(self, parent=parent) self.prefix = prefix self.device = SiriusPVName(device) self.scrn_prefix = self.device.substitute(prefix=prefix) self._receivedData = False self.setObjectName(self.scrn_prefix.sec + 'App') self.screen_type_conn = SiriusConnectionSignal( self.scrn_prefix.substitute(propty='ScrnType-Sts')) self.screen_type_conn.new_value_signal.connect( self.updateCalibrationGridFlag) self._calibrationgrid_flag = self.screen_type_conn.getvalue() self.save_files.connect(self._saveGridLocalFiles) self.ch_ImgROIHeight = SiriusConnectionSignal( self.scrn_prefix.substitute(propty='ImgROIHeight-RB')) self.ch_ImgROIWidth = SiriusConnectionSignal( self.scrn_prefix.substitute(propty='ImgROIWidth-RB')) self.ch_ImgROIOffsetX = SiriusConnectionSignal( self.scrn_prefix.substitute(propty='ImgROIOffsetX-RB')) self.ch_ImgROIOffsetY = SiriusConnectionSignal( self.scrn_prefix.substitute(propty='ImgROIOffsetY-RB')) self._setupUi() self.setFocus(True) self.setFocusPolicy(Qt.StrongFocus) self._loadCalibrationGrid(default=True) @property def calibrationgrid_flag(self): """Indicate if the screen device is in calibration grid position.""" return self._calibrationgrid_flag @Slot(int) def updateCalibrationGridFlag(self, new_state): """Update calibrationgrid_flag property.""" self._calibrationgrid_flag = new_state if new_state == 1: self.pushbutton_savegrid.setEnabled(True) else: self.pushbutton_savegrid.setEnabled(False) def _setupUi(self): self.cameraview_widget = QWidget() self.cameraview_widget.setLayout(self._cameraviewLayout()) self.settings_widget = QWidget(self) self.settings_widget.setLayout(self._settingsLayout()) self.settings_widget.setStyleSheet(""" .QLabel{ min-width: 5em;} QLabel{ qproperty-alignment: AlignCenter;}""") self.calibrationgrid_widget = QWidget(self) self.calibrationgrid_widget.setLayout(self._calibrationgridLayout()) self.calibrationgrid_widget.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Expanding) self.calibrationgrid_widget.layout().setAlignment(Qt.AlignHCenter) self.tab = QTabWidget(self) self.tab.setStyleSheet(""" QTabWidget::pane { border-left: 2px solid gray; border-bottom: 2px solid gray; border-right: 2px solid gray; }""") self.tab.addTab(self.settings_widget, 'Camera Settings') self.tab.addTab(self.calibrationgrid_widget, 'Calibration') self.statistics_groupBox = QGroupBox('Statistics', self) self.statistics_groupBox.setLayout(self._statisticsLayout()) self.statistics_groupBox.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Expanding) self.statistics_groupBox.setStyleSheet(""" .QLabel{ min-width:0.28em; max-width:0.28em; min-height:1.29em; max-height:1.29em;} QLabel{ qproperty-alignment: AlignCenter;} PyDMWidget{ min-width:4.84em; max-width:4.84em; min-height:1.29em; max-height:1.29em;}""") self.trigger_groupBox = QGroupBox('Trigger', self) if 'TB' in self.device or 'BO' in self.device: trg_prefix = 'AS-Fam:TI-Scrn-TBBO' elif 'TS' in self.device: trg_prefix = 'TS-Fam:TI-Scrn' hbl = QHBoxLayout(self.trigger_groupBox) hbl.addWidget( HLTriggerSimple(parent=self.trigger_groupBox, device=trg_prefix, prefix=self.prefix)) self.trigger_groupBox.setLayout(hbl) self.trigger_groupBox.setStyleSheet(""" PyDMWidget{ min-width:4.84em; max-width:4.84em; min-height:1.29em; max-height:1.29em;}""") vlay = QVBoxLayout() vlay.addWidget(self.statistics_groupBox) vlay.addWidget(self.trigger_groupBox) vlay.setSpacing(10) lay = QGridLayout(self) lay.setHorizontalSpacing(10) lay.setVerticalSpacing(10) lay.addWidget(self.cameraview_widget, 0, 0, 1, 2) lay.addWidget(self.tab, 1, 0) lay.addLayout(vlay, 1, 1) lay.setRowStretch(0, 15) lay.setRowStretch(1, 7) def _cameraviewLayout(self): label = QLabel(self.device, self) label.setStyleSheet("""font-weight: bold;max-height:1.29em;""") label.setAlignment(Qt.AlignCenter) self.image_view = _SiriusImageView( parent=self, image_channel=self.scrn_prefix.substitute(propty='ImgData-Mon'), width_channel=self.scrn_prefix.substitute(propty='ImgROIWidth-RB'), offsetx_channel=self.scrn_prefix.substitute( propty='ImgROIOffsetX-RB'), offsety_channel=self.scrn_prefix.substitute( propty='ImgROIOffsetY-RB'), maxwidth_channel=self.scrn_prefix.substitute( propty='ImgMaxWidth-Cte'), maxheight_channel=self.scrn_prefix.substitute( propty='ImgMaxHeight-Cte')) self.image_view.setObjectName('ScrnView') self.image_view.normalizeData = True self.image_view.readingOrder = self.image_view.Clike self.image_view.maxRedrawRate = 15 self.image_view.setStyleSheet(""" #ScrnView{min-width:30em; min-height:24em;}""") self.image_view.failToSaveGrid.connect(self._showFailToSaveGridMsg) self.image_view.receivedData.connect(self._setReceivedDataFlag) lay = QGridLayout() lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(label, 0, 1) lay.addItem(QSpacerItem(40, 2, QSzPlcy.Preferred, QSzPlcy.Fixed), 1, 1) lay.addWidget(self.image_view, 2, 1) return lay def _calibrationgridLayout(self): self.checkBox_showgrid = QCheckBox('Show', self) self.checkBox_showgrid.setEnabled(False) self.checkBox_showgrid.setStyleSheet(""" min-width:4em; max-width:4em; min-height:1.29em; max-height:1.29em;""") self.checkBox_showgrid.toggled.connect( self.image_view.showCalibrationGrid) self.pushbutton_savegrid = QPushButton('Save', self) self.pushbutton_savegrid.setEnabled(False) self.pushbutton_savegrid.setStyleSheet(""" min-width:4em; max-width:4em; min-height:1.29em; max-height:1.29em;""") self.pushbutton_savegrid.clicked.connect(self._saveCalibrationGrid) self.pushbutton_loadgrid = QPushButton('Load', self) self.pushbutton_loadgrid.setStyleSheet(""" min-width:4em; max-width:4em; min-height:1.29em; max-height:1.29em;""") self.pushbutton_loadgrid.clicked.connect(self._loadCalibrationGrid) hbox_grid = QHBoxLayout() hbox_grid.addWidget(self.checkBox_showgrid) hbox_grid.addWidget(self.pushbutton_savegrid) hbox_grid.addWidget(self.pushbutton_loadgrid) lb = QLabel('Show levels <') lb.setStyleSheet("min-width:7em;max-width:7em;") self.spinbox_gridfilterfactor = QSpinBoxPlus() self.spinbox_gridfilterfactor.setMaximum(100) self.spinbox_gridfilterfactor.setMinimum(0) self.spinbox_gridfilterfactor.setValue( self.image_view.calibration_grid_filterfactor) self.spinbox_gridfilterfactor.editingFinished.connect( self._setCalibrationGridFilterFactor) self.spinbox_gridfilterfactor.setStyleSheet(""" min-width:4em; max-width:4em;""") hbox_filter = QHBoxLayout() hbox_filter.setSpacing(0) hbox_filter.addWidget(lb) hbox_filter.addWidget(self.spinbox_gridfilterfactor) hbox_filter.addWidget(QLabel(' %')) lb = QLabel('Remove border: ') lb.setStyleSheet("min-width:7em;max-width:7em;") self.spinbox_removeborder = QSpinBoxPlus() self.spinbox_removeborder.setMaximum(512) self.spinbox_removeborder.setMinimum(0) self.spinbox_removeborder.setValue( self.image_view.calibration_grid_removeborder) self.spinbox_removeborder.editingFinished.connect( self._setCalibrationGridBorder2Remove) self.spinbox_removeborder.setStyleSheet(""" min-width:4em; max-width:4em;""") hbox_remove = QHBoxLayout() hbox_remove.setSpacing(0) hbox_remove.addWidget(lb) hbox_remove.addWidget(self.spinbox_removeborder) hbox_remove.addWidget(QLabel(' px')) hbox_EnblLED = _create_propty_layout(parent=self, prefix=self.scrn_prefix, propty='EnblLED', propty_type='enbldisabl', width=4.68) lay = QFormLayout() lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred)) lay.addRow(' Grid: ', hbox_grid) lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred)) lay.addRow(' ', hbox_filter) lay.addRow(' ', hbox_remove) lay.addItem(QSpacerItem(1, 20, QSzPlcy.Ignored, QSzPlcy.Preferred)) lay.addRow(' LED: ', hbox_EnblLED) lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Preferred)) lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) return lay def _settingsLayout(self): label_CamEnbl = QLabel('Enable: ', self) hbox_CamEnbl = _create_propty_layout(parent=self, prefix=self.scrn_prefix, propty='CamEnbl', propty_type='enbldisabl') label_CamAcqPeriod = QLabel('Acquire\nPeriod [s]:', self) hbox_CamAcqPeriod = _create_propty_layout(parent=self, prefix=self.scrn_prefix, propty='CamAcqPeriod', propty_type='sprb', width=5.0) label_CamExposureTime = QLabel('Exposure\nTime [us]:', self) hbox_CamExposureTime = _create_propty_layout(parent=self, prefix=self.scrn_prefix, propty='CamExposureTime', propty_type='sprb', width=5.0) label_CamGain = QLabel('Gain[dB]:', self) hbox_CamGain = _create_propty_layout(parent=self, prefix=self.scrn_prefix, propty='CamGain', width=5.0, propty_type='sprb') label_AutoGain = QLabel('Auto Gain: ', self) self.pb_autogain = PyDMPushButton( label='', icon=qta.icon('mdi.auto-fix'), parent=self, pressValue=1, init_channel=self.scrn_prefix.substitute(propty='CamAutoGain-Cmd')) self.pb_autogain.setObjectName('autog') self.pb_autogain.setStyleSheet( "#autog{min-width:25px; max-width:25px; icon-size:20px;}") cam_prefix = SiriusPVName(self.scrn_prefix).substitute(dev='ScrnCam') label_Reset = QLabel('Reset: ', self) self.pb_dtl = PyDMPushButton( label='', icon=qta.icon('fa5s.sync'), parent=self, pressValue=1, init_channel=cam_prefix.substitute(propty='Rst-Cmd')) self.pb_dtl.setObjectName('reset') self.pb_dtl.setStyleSheet( "#reset{min-width:25px; max-width:25px; icon-size:20px;}") self.pb_details = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self) self.pb_details.setToolTip('More settings') self.pb_details.setObjectName('detail') self.pb_details.setStyleSheet( "#detail{min-width:25px; max-width:25px; icon-size:20px;}") self.pb_details.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Preferred) util.connect_window(self.pb_details, _ScrnSettingsDetails, parent=self, prefix=self.prefix, device=self.device) hbox_aux = QHBoxLayout() hbox_aux.addWidget(self.pb_dtl, alignment=Qt.AlignLeft) hbox_aux.addWidget(self.pb_details, alignment=Qt.AlignRight) lay = QFormLayout() lay.setFormAlignment(Qt.AlignCenter) lay.addRow(label_CamEnbl, hbox_CamEnbl) lay.addRow(label_CamAcqPeriod, hbox_CamAcqPeriod) lay.addRow(label_CamExposureTime, hbox_CamExposureTime) lay.addRow(label_CamGain, hbox_CamGain) lay.addRow(label_AutoGain, self.pb_autogain) lay.addRow(label_Reset, hbox_aux) return lay def _statisticsLayout(self): # - Method label_Method = QLabel('CalcMethod:', self) label_Method.setStyleSheet("min-width:7em;") self.comboBox_Method = QComboBox(self) self.comboBox_Method.addItem('DimFei', 0) self.comboBox_Method.addItem('NDStats', 1) self.comboBox_Method.setCurrentIndex(0) self.comboBox_Method.setStyleSheet(""" QComboBox::item {height: 1em;} QComboBox{min-width:6em;}""") self.comboBox_Method.currentIndexChanged.connect( self._handleShowStatistics) # - Centroid label_Centroid = QLabel('Centroid [mm]: ', self) label_Centroid.setStyleSheet("min-width:7em;") label_i_Center = QLabel('(', self) self.PyDMLabel_CenterXDimFei = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='CenterXDimFei-Mon')) self.PyDMLabel_CenterXDimFei.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_CenterXNDStats = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='CenterXNDStats-Mon')) self.PyDMLabel_CenterXNDStats.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_CenterXNDStats.setVisible(False) label_m_Center = QLabel(',', self) self.PyDMLabel_CenterYDimFei = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='CenterYDimFei-Mon')) self.PyDMLabel_CenterYDimFei.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_CenterYNDStats = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='CenterYNDStats-Mon')) self.PyDMLabel_CenterYNDStats.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_CenterYNDStats.setVisible(False) label_f_Center = QLabel(')', self) # - Sigma label_Sigma = QLabel('Sigma [mm]: ', self) label_Sigma.setStyleSheet("min-width:7em;") label_i_Sigma = QLabel('(', self) self.PyDMLabel_SigmaXDimFei = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='SigmaXDimFei-Mon')) self.PyDMLabel_SigmaXDimFei.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_SigmaXNDStats = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='SigmaXNDStats-Mon')) self.PyDMLabel_SigmaXNDStats.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_SigmaXNDStats.setVisible(False) label_m_Sigma = QLabel(',', self) self.PyDMLabel_SigmaYDimFei = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='SigmaYDimFei-Mon')) self.PyDMLabel_SigmaYDimFei.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_SigmaYNDStats = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='SigmaYNDStats-Mon')) self.PyDMLabel_SigmaYNDStats.setStyleSheet( 'min-width:4em; max-width:4em;') self.PyDMLabel_SigmaYNDStats.setVisible(False) label_f_Sigma = QLabel(')', self) # - Theta label_Theta = QLabel('Theta [rad]: ') label_Theta.setStyleSheet("min-width:7em;") label_i_Theta = QLabel('(', self) self.PyDMLabel_ThetaDimFei = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute(propty='ThetaDimFei-Mon')) self.PyDMLabel_ThetaDimFei.setStyleSheet("max-width:12em;") self.PyDMLabel_ThetaNDStats = PyDMLabel( parent=self, init_channel=self.scrn_prefix.substitute( propty='ThetaNDStats-Mon')) self.PyDMLabel_ThetaNDStats.setStyleSheet("max-width:12em;") self.PyDMLabel_ThetaNDStats.setVisible(False) label_f_Theta = QLabel(')', self) lay = QGridLayout() lay.addWidget(label_Method, 1, 1, 1, 3) lay.addWidget(self.comboBox_Method, 1, 3, 1, 3) lay.addWidget(label_Centroid, 3, 1, alignment=Qt.AlignCenter) lay.addWidget(label_i_Center, 3, 2) lay.addWidget(self.PyDMLabel_CenterXDimFei, 3, 3) lay.addWidget(self.PyDMLabel_CenterXNDStats, 3, 3) lay.addWidget(label_m_Center, 3, 4) lay.addWidget(self.PyDMLabel_CenterYDimFei, 3, 5) lay.addWidget(self.PyDMLabel_CenterYNDStats, 3, 5) lay.addWidget(label_f_Center, 3, 6) lay.addWidget(label_Sigma, 5, 1, alignment=Qt.AlignCenter) lay.addWidget(label_i_Sigma, 5, 2) lay.addWidget(self.PyDMLabel_SigmaXDimFei, 5, 3) lay.addWidget(self.PyDMLabel_SigmaXNDStats, 5, 3) lay.addWidget(label_m_Sigma, 5, 4) lay.addWidget(self.PyDMLabel_SigmaYDimFei, 5, 5) lay.addWidget(self.PyDMLabel_SigmaYNDStats, 5, 5) lay.addWidget(label_f_Sigma, 5, 6) lay.addWidget(label_Theta, 7, 1, alignment=Qt.AlignCenter) lay.addWidget(label_i_Theta, 7, 2) lay.addWidget(self.PyDMLabel_ThetaDimFei, 7, 3, 1, 3) lay.addWidget(self.PyDMLabel_ThetaNDStats, 7, 3, 1, 3) lay.addWidget(label_f_Theta, 7, 6) return lay def _handleShowStatistics(self, visible): self.PyDMLabel_CenterXDimFei.setVisible(not visible) self.PyDMLabel_CenterXNDStats.setVisible(visible) self.PyDMLabel_CenterYDimFei.setVisible(not visible) self.PyDMLabel_CenterYNDStats.setVisible(visible) self.PyDMLabel_ThetaDimFei.setVisible(not visible) self.PyDMLabel_ThetaNDStats.setVisible(visible) self.PyDMLabel_SigmaXDimFei.setVisible(not visible) self.PyDMLabel_SigmaXNDStats.setVisible(visible) self.PyDMLabel_SigmaYDimFei.setVisible(not visible) self.PyDMLabel_SigmaYNDStats.setVisible(visible) def _saveCalibrationGrid(self): t = Thread(target=self._saveCalibrationGrid_thread, daemon=True) t.start() def _saveCalibrationGrid_thread(self): roi_h = float(self.ch_ImgROIHeight.value) roi_w = float(self.ch_ImgROIWidth.value) roi_offsetx = float(self.ch_ImgROIOffsetX.value) roi_offsety = float(self.ch_ImgROIOffsetY.value) cond = roi_h != float(self.image_view.image_maxheight) or \ roi_w != float(self.image_view.image_maxwidth) or \ roi_offsetx != 0 or roi_offsety != 0 if cond: # Disable camera acquisition and wait for disabling self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(0) state = self.SiriusLedState_CamEnbl.state while state == 1: time.sleep(0.1) state = self.SiriusLedState_CamEnbl.state # Change ROI to get entire image self.ch_ImgROIHeight.send_value_signal[float].emit( float(self.image_view.image_maxheight)) self.ch_ImgROIWidth.send_value_signal[float].emit( float(self.image_view.image_maxwidth)) self.ch_ImgROIOffsetX.send_value_signal[float].emit(0) self.ch_ImgROIOffsetY.send_value_signal[float].emit(0) # Enable led and wait for status self.PyDMStateButton_EnblLED.send_value_signal[int].emit(1) while not self.SiriusLedState_EnblLED.state: time.sleep(0.1) # Enable camera acquisition and wait for receiveing first frame self._receivedData = False self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(1) while not self._receivedData: time.sleep(0.1) # Save grid self.image_view.saveCalibrationGrid() if cond: # Disable camera acquisition and wait for disabling self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(0) state = self.SiriusLedState_CamEnbl.state while state == 1: time.sleep(0.1) state = self.SiriusLedState_CamEnbl.state # Change ROI to original size self.ch_ImgROIHeight.send_value_signal[float].emit(roi_h) self.ch_ImgROIWidth.send_value_signal[float].emit(roi_w) self.ch_ImgROIOffsetX.send_value_signal[float].emit(roi_offsetx) self.ch_ImgROIOffsetY.send_value_signal[float].emit(roi_offsety) # Enable camera acquisition self.PyDMStateButton_CamEnbl.send_value_signal[int].emit(1) # Enable showing saved grid time.sleep(0.1) self.checkBox_showgrid.setEnabled(True) self.save_files.emit() def _saveGridLocalFiles(self): home = os.path.expanduser('~') folder_month = datetime.now().strftime('%Y-%m') folder_day = datetime.now().strftime('%Y-%m-%d') path = os.path.join(home, 'mounts', 'screens-iocs', folder_month, folder_day) if not os.path.exists(path): os.makedirs(path) fn, _ = QFileDialog.getSaveFileName( self, 'Save Grid As...', path + '/' + self.device + datetime.now().strftime('_%Y-%m-%d_%Hh%Mmin'), '*.npy') if not fn: return False path_default = os.path.join(home, 'mounts', 'screens-iocs', 'default') if not os.path.exists(path_default): os.makedirs(path_default) fn_default = path_default + '/' + self.device grid = self.image_view.calibrationGrid width = self.image_view.imageWidth data = np.append(width, grid) np.save(fn, data) np.save(fn_default, data) def _loadCalibrationGrid(self, default=False): home = os.path.expanduser('~') if not default: folder_month = datetime.now().strftime('%Y-%m') path = os.path.join(home, 'mounts', 'screens-iocs', folder_month) fn, _ = QFileDialog.getOpenFileName(self, 'Load Grid...', path, '*.npy') if not fn: return if self.device not in fn: ans = QMessageBox.question( self, 'Warning', 'The name of the selected file does not contain the name' + ' of this screen. Are you sure you\'re loading this grid?', QMessageBox.Yes, QMessageBox.Cancel) if ans == QMessageBox.Cancel: return else: path = os.path.join(home, 'mounts', 'screens-iocs', 'default') fn = path + '/' + self.device + '.npy' try: data = np.load(fn) self.image_view.calibrationGrid = data except Exception as e: if not default: QMessageBox.critical( self, 'Error', 'Could not load calibration grid from file ' + fn + '. ' + '\nError message: ' + str(e), QMessageBox.Ok) return # Enable showing saved grid self.checkBox_showgrid.setEnabled(True) def _setReceivedDataFlag(self): self._receivedData = True def _setCalibrationGridFilterFactor(self): self.image_view.set_calibration_grid_filterfactor( self.spinbox_gridfilterfactor.value()) def _setCalibrationGridBorder2Remove(self): self.image_view.set_calibration_grid_border2remove( self.spinbox_removeborder.value()) @Slot() def _showFailToSaveGridMsg(self): QMessageBox.warning(self, 'Warning', 'Could not save calibration grid!', QMessageBox.Ok)
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()
def _setupUi(self): # Machine Shift self.wid_shift = QGroupBox('Machine Shift') machshift_pvname = SiriusPVName( 'AS-Glob:AP-MachShift:Mode-Sel').substitute(prefix=self._prefix) cbox_shift_mode = SiriusEnumComboBox(self, machshift_pvname) label_shift_mode = MachShiftLabel(self, self._prefix) label_shift_mode.label.setStyleSheet( 'QLabel{max-height: 2em; min-width: 7em;}') lay_shift = QGridLayout(self.wid_shift) lay_shift.setVerticalSpacing(5) lay_shift.setAlignment(Qt.AlignCenter) lay_shift.addWidget(cbox_shift_mode, 1, 0) lay_shift.addWidget(label_shift_mode, 2, 0) # Injection System self.wid_injsys = QGroupBox('Inj.System') wid_injsys = InjSysStbyControlWidget(self, self._prefix, is_summary=True) lay_injsys = QGridLayout(self.wid_injsys) lay_injsys.setAlignment(Qt.AlignCenter) lay_injsys.setContentsMargins(0, 0, 0, 0) lay_injsys.addWidget(wid_injsys) # Egun triggers self.wid_egun = QGroupBox('Egun Trig.') self.wid_egun.setStyleSheet('min-width: 5em;') egun_dev = SiriusPVName('LI-01:EG-TriggerPS').substitute( prefix=self._prefix) but_egun_trigger = PyDMStateButton( self, egun_dev.substitute(propty_name='enable')) led_egun_trigger = SiriusLedState( self, egun_dev.substitute(propty_name='enablereal')) lay_egun = QGridLayout(self.wid_egun) lay_egun.setVerticalSpacing(5) lay_egun.addWidget(but_egun_trigger, 1, 0) lay_egun.addWidget(led_egun_trigger, 2, 0) # injection control injctrl_dev = SiriusPVName('AS-Glob:AP-InjCtrl') injctrl_dev = injctrl_dev.substitute(prefix=self._prefix) self.wid_inject = QGroupBox('Injection') self.ch_injmode = SiriusConnectionSignal( injctrl_dev.substitute(propty='Mode-Sts')) self.ch_injmode.new_value_signal[int].connect( self._handle_injmode_settings_vis) # # Settings label_sett = QLabel('<h4>Sett.</h4>', self, alignment=Qt.AlignCenter) led_sett = InjDiagLed(self) self.wid_injsett = QWidget() lay_injsett = QGridLayout(self.wid_injsett) lay_injsett.setContentsMargins(0, 0, 0, 0) lay_injsett.setAlignment(Qt.AlignTop) lay_injsett.addWidget(label_sett, 0, 0) lay_injsett.addWidget(led_sett, 1, 0) # # Auto Stop self.label_injauto = QLabel('<h4>AutoStop</h4>', self, alignment=Qt.AlignCenter) self.but_injauto = PyDMStateButton( self, injctrl_dev.substitute(propty='AutoStop-Sel')) self.led_injauto = SiriusLedState( self, injctrl_dev.substitute(propty='AutoStop-Sts')) self.wid_injauto = QWidget() self.wid_injauto.setObjectName('wid') self.wid_injauto.setStyleSheet("#wid{min-width: 8em; max-width: 8em;}") lay_injauto = QGridLayout(self.wid_injauto) lay_injauto.setContentsMargins(0, 0, 0, 0) lay_injauto.setAlignment(Qt.AlignTop) lay_injauto.addWidget(self.label_injauto, 0, 0) lay_injauto.addWidget(self.but_injauto, 1, 0) lay_injauto.addWidget(self.led_injauto, 2, 0) # # Top-up status label_tusts = QLabel('<h4>Status</h4>', self, alignment=Qt.AlignCenter) label_tunow = ClockLabel(self) label_tunow.setStyleSheet('max-height:2em;') label_tunxt = SiriusLabel( self, injctrl_dev.substitute(propty='TopUpNextInj-Mon')) label_tunxt.displayFormat = SiriusLabel.DisplayFormat.Time label_tunxt.setAlignment(Qt.AlignCenter) label_tunxt.setStyleSheet('max-height:2em;') but_round = PyDMPushButton( self, '', qta.icon('mdi.tilde'), 1, False, injctrl_dev.substitute(propty='TopUpNextInjRound-Cmd')) but_round.setObjectName('but') but_round.setStyleSheet( '#but{min-width:18px; max-width:18px; icon-size:16px;}') self.wid_tusts = QWidget() self.wid_tusts.setObjectName('wid') self.wid_tusts.setStyleSheet("#wid{min-width: 8em; max-width: 8em;}") lay_tusts = QGridLayout(self.wid_tusts) lay_tusts.setContentsMargins(0, 0, 0, 0) lay_tusts.setAlignment(Qt.AlignTop) lay_tusts.addWidget(label_tusts, 0, 0, 1, 2) lay_tusts.addWidget(QLabel('Now:', self), 1, 0) lay_tusts.addWidget(label_tunow, 1, 1) lay_tusts.addWidget(QLabel('Next:', self), 2, 0) lay_tusts.addWidget(label_tunxt, 2, 1) lay_tusts.addWidget(but_round, 2, 2) self.wid_tusts.setVisible(False) # # Control label_inj = QLabel('<h4>Control</h4>', self, alignment=Qt.AlignCenter) self.but_tiinj = EVGInjectionButton(self, self._prefix) self.but_topup = PyDMStateButton( self, injctrl_dev.substitute(propty='TopUpState-Sel')) self.but_topup.setVisible(False) lay_inject_sel = QGridLayout() lay_inject_sel.setAlignment(Qt.AlignCenter) lay_inject_sel.addWidget(self.but_tiinj, 0, 0) lay_inject_sel.addWidget(self.but_topup, 0, 0) led_injsts = EVGInjectionLed(self, self._prefix) label_injcnt = PyDMLabel(self) label_injcnt.setToolTip( 'Count injection pulses when Egun Trigger is enabled.') label_injcnt.channel = SiriusPVName( 'AS-Glob:AP-CurrInfo:InjCount-Mon').substitute(prefix=self._prefix) label_injcnt.setStyleSheet('QLabel{max-width: 3.5em;}') lay_inject_sts = QHBoxLayout() lay_inject_sts.setContentsMargins(0, 0, 0, 0) lay_inject_sts.setAlignment(Qt.AlignTop) lay_inject_sts.addWidget(led_injsts) lay_inject_sts.addWidget(label_injcnt) self.wid_injctrl = QWidget() lay_injctrl = QGridLayout(self.wid_injctrl) lay_injctrl.setContentsMargins(0, 0, 0, 0) lay_injctrl.setAlignment(Qt.AlignTop) lay_injctrl.addWidget(label_inj, 0, 2, alignment=Qt.AlignCenter) lay_injctrl.addLayout(lay_inject_sel, 1, 2, alignment=Qt.AlignCenter) lay_injctrl.addLayout(lay_inject_sts, 2, 2, alignment=Qt.AlignCenter) # # Injection Auxiliary section self.wid_injlog = QGroupBox('Injection Log') label_injlog = PyDMLogLabel(self, injctrl_dev.substitute(propty='Log-Mon'), replace=[ 'Remaining time', ]) lay_injlog = QGridLayout(self.wid_injlog) lay_injlog.addWidget(label_injlog, 0, 0) self.wid_injlog.setVisible(False) self.wid_mon = MonitorSummaryWidget(self, self._prefix) self.wid_mon.setVisible(False) # # Target Current self._ld_currtgt = QLabel('<h4>Target Curr.</h4>', self, alignment=Qt.AlignCenter) self._sb_currtgt = SiriusSpinbox( self, injctrl_dev.substitute(propty='TargetCurrent-SP')) self._sb_currtgt.showStepExponent = False self._lb_currtgt = PyDMLabel( self, injctrl_dev.substitute(propty='TargetCurrent-RB')) self._lb_currtgt.showUnits = True self._wid_tcurr = QWidget() lay_tcurr = QGridLayout(self._wid_tcurr) lay_tcurr.setContentsMargins(0, 0, 0, 0) lay_tcurr.setAlignment(Qt.AlignTop) lay_tcurr.addWidget(self._ld_currtgt, 0, 0) lay_tcurr.addWidget(self._sb_currtgt, 1, 0) lay_tcurr.addWidget(self._lb_currtgt, 2, 0) # # Bucket List self._bucket_list = BucketList(self, prefix=self._prefix, min_size=15) self.wid_fill = QWidget() lay_fill = QGridLayout(self.wid_fill) lay_fill.setContentsMargins(0, 0, 0, 0) lay_fill.setHorizontalSpacing(9) lay_fill.addWidget(self._wid_tcurr, 0, 0) lay_fill.addWidget(self._bucket_list, 0, 1) self.wid_fill.setVisible(False) pbt_aux = QPushButton('v', self) pbt_aux.setToolTip('Show Injection Auxiliary section.') pbt_aux.clicked.connect(self._toggle_show_injaux) pbt_aux.setStyleSheet('QPushButton{max-width: 0.8em;}') pbt_bl = QPushButton('>', self) pbt_bl.setToolTip('Show bucket list and target current controls.') pbt_bl.clicked.connect(self._toggle_show_bucketlist) pbt_bl.setStyleSheet('QPushButton{max-width: 0.8em;}') lay_inj = QGridLayout(self.wid_inject) lay_inj.setAlignment(Qt.AlignTop) lay_inj.setVerticalSpacing(5) lay_inj.setHorizontalSpacing(12) lay_inj.addWidget(self.wid_injsett, 0, 0, 2, 1) lay_inj.addWidget(self.wid_injauto, 0, 1, 2, 1) lay_inj.addWidget(self.wid_tusts, 0, 1, 2, 1) lay_inj.addWidget(self.wid_injctrl, 0, 2, 2, 1) lay_inj.addWidget(pbt_bl, 0, 3, alignment=Qt.AlignTop) lay_inj.addWidget(pbt_aux, 1, 3, alignment=Qt.AlignBottom) lay_inj.addWidget(self.wid_fill, 0, 4, 2, 1) # Current curr_pvname = SiriusPVName( 'SI-Glob:AP-CurrInfo:Current-Mon').substitute(prefix=self._prefix) self.label_curr = PyDMLabel(self, curr_pvname) self.label_curr.showUnits = True self.label_curr.setStyleSheet(""" QLabel{ font-size: 18pt; qproperty-alignment: AlignCenter; min-width: 6em; max-width: 6em; }""") self.wid_curr = QGroupBox('Current') lay_curr = QHBoxLayout(self.wid_curr) lay_curr.addWidget(self.label_curr) # RF Kill Beam self.wid_rfkill = QGroupBox('RF Kill Beam') self.wid_rfkill.setObjectName('RFKillBeam') rfkill_bt = RFKillBeamButton(self, self._prefix) rfkill_lay = QGridLayout(self.wid_rfkill) rfkill_lay.addWidget(rfkill_bt) # menu buttons self.wid_pbt = QPushButton('v', self) self.wid_pbt.clicked.connect(self._toggle_show_menubutton) self.wid_pbt.setStyleSheet('QPushButton{max-width: 0.8em;}') self._menubutton = get_object(ismenubar=False, parent=self) self._menubutton.layout().setContentsMargins(0, 0, 0, 0) self._menubutton.layout().setSpacing(4) self._menubutton.setVisible(False) hlay1 = QHBoxLayout() hlay1.setContentsMargins(0, 0, 0, 0) hlay1.addWidget(self.wid_shift) hlay1.addWidget(self.wid_injsys) hlay1.addWidget(self.wid_egun) hlay1.addWidget(self.wid_inject) hlay1.addWidget(self.wid_curr) hlay1.addWidget(self.wid_rfkill) hlay2 = QHBoxLayout() hlay2.setContentsMargins(0, 0, 0, 0) hlay2.addWidget(self.wid_injlog) hlay2.addWidget(self.wid_mon) cwid = QWidget(self) lay = QGridLayout(cwid) lay.addLayout(hlay1, 0, 0) lay.addLayout(hlay2, 1, 0) lay.addWidget(self._menubutton, 2, 0, 1, 2) lay.addWidget(self.wid_pbt, 0, 1, 2, 1, alignment=Qt.AlignRight | Qt.AlignBottom) self.setCentralWidget(cwid)
class APUControlWindow(SiriusMainWindow): """APU Control Window.""" def __init__(self, parent=None, prefix=_vaca_prefix, device=''): """Init.""" super().__init__(parent) self._prefix = prefix self._device = _PVName(device) self._beamline = IDSearch.conv_idname_2_beamline(self._device) self.dev_pref = self._device.substitute(prefix=prefix) self.setWindowTitle(device + ' Control Window - ' + self._beamline) self.setObjectName('IDApp') self.setWindowIcon(get_id_icon()) self._setupUi() def _setupUi(self): self._label_title = QLabel('<h3>' + self._device + ' Control - ' + self._beamline + '</h3 >', self, alignment=Qt.AlignCenter) self._label_title.setStyleSheet('max-height:1.29em;') self.wid_mainControls = self._mainControlsWidget() self.wid_ctrlMode = self._ctrlModeWidget() self.wid_beamLinesCtrl = self._beamLinesCtrlWidget() self.wid_auxCommands = self._auxCommandsWidget() self.wid_status = self._statusWidget() cw = QWidget() self.setCentralWidget(cw) lay = QGridLayout(cw) lay.addWidget(self._label_title, 0, 0, 1, 3) lay.addWidget(self.wid_mainControls, 1, 0, 2, 1) lay.addWidget(self.wid_ctrlMode, 1, 1) lay.addWidget(self.wid_beamLinesCtrl, 2, 1) lay.addWidget(self.wid_auxCommands, 3, 0) lay.addWidget(self.wid_status, 3, 1) lay.setRowStretch(0, 1) lay.setRowStretch(1, 1) lay.setRowStretch(2, 2) lay.setRowStretch(3, 3) def _mainControlsWidget(self): self._ld_phs = QLabel('Phase [mm]', self) self._sb_phs = PyDMSpinbox(self, self.dev_pref.substitute(propty='Phase-SP')) self._sb_phs.showStepExponent = False self._lb_phs = PyDMLabel(self, self.dev_pref.substitute(propty='Phase-Mon')) self._ld_kx = QLabel('Kx', self) self._sb_kx = PyDMSpinbox(self, self.dev_pref.substitute(propty='Kx-SP')) self._sb_kx.showStepExponent = False self._lb_kx = PyDMLabel(self, self.dev_pref.substitute(propty='Kx-Mon')) self._ld_phsspd = QLabel('Phase Speed\n[mm/s]', self) self._sb_phsspd = PyDMSpinbox( self, self.dev_pref.substitute(propty='PhaseSpeed-SP')) self._sb_phsspd.showStepExponent = False self._lb_phsspd = PyDMLabel( self, self.dev_pref.substitute(propty='PhaseSpeed-Mon')) self._ld_ismov = QLabel('Motion', self) self._pb_start = PyDMPushButton(self, label='', icon=qta.icon('fa5s.play')) self._pb_start.setToolTip( 'Start automatic motion towards previously entered setpoint.') self._pb_start.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_start.pressValue = 3 # Start self._pb_start.setObjectName('Start') self._pb_start.setStyleSheet( '#Start{min-width:30px; max-width:30px; icon-size:25px;}') self._pb_stop = PyDMPushButton(self, label='', icon=qta.icon('fa5s.stop')) self._pb_stop.setToolTip('Stop all motion, lock all brakes.') self._pb_stop.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_stop.pressValue = 1 # Stop self._pb_stop.setObjectName('Stop') self._pb_stop.setStyleSheet( '#Stop{min-width:30px; max-width:30px; icon-size:25px;}') self._led_ismov = SiriusLedState(self, self.dev_pref + ':Moving-Mon') self._led_motenbl = SiriusLedState( self, self.dev_pref.substitute(propty='MotorsEnbld-Mon')) hbox_motion = QHBoxLayout() hbox_motion.setSpacing(15) hbox_motion.addWidget(self._pb_start) hbox_motion.addWidget(self._pb_stop) hbox_motion.addWidget(self._led_ismov) hbox_motion.addWidget(self._led_motenbl) gbox_main = QGroupBox('Main Controls', self) lay_main = QGridLayout(gbox_main) lay_main.addWidget(self._ld_phs, 0, 0) lay_main.addWidget(self._sb_phs, 0, 1) lay_main.addWidget(self._lb_phs, 0, 2) lay_main.addWidget(self._ld_kx, 1, 0) lay_main.addWidget(self._sb_kx, 1, 1) lay_main.addWidget(self._lb_kx, 1, 2) lay_main.addWidget(self._ld_phsspd, 2, 0) lay_main.addWidget(self._sb_phsspd, 2, 1) lay_main.addWidget(self._lb_phsspd, 2, 2) lay_main.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Fixed), 3, 0) lay_main.addWidget(self._ld_ismov, 4, 0) lay_main.addLayout(hbox_motion, 4, 1, 1, 2) return gbox_main def _statusWidget(self): self._ld_alarm = QLabel('Alarms', self, alignment=Qt.AlignCenter) self._led_alarm = SiriusLedAlert( self, self.dev_pref.substitute(propty='Alarm-Mon')) self._pb_alarmdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self) self._pb_alarmdetail.setObjectName('dtl') self._pb_alarmdetail.setStyleSheet( "#dtl{min-width:25px; max-width:25px; icon-size:20px;}") connect_window(self._pb_alarmdetail, APUAlarmDetails, self, prefix=self._prefix, device=self._device) self._ld_intlk = QLabel('Interlocks', self, alignment=Qt.AlignCenter) self._led_intlkresume = PyDMLedMultiChannel( self, { self.dev_pref.substitute(propty='IntlkInStop-Mon'): 0, self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon'): 0, self.dev_pref.substitute(propty='IntlkOutPwrEnbld-Mon'): 1 }) self._pb_intlkdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self) self._pb_intlkdetail.setObjectName('dtl') self._pb_intlkdetail.setStyleSheet( "#dtl{min-width:25px; max-width:25px; icon-size:20px;}") connect_window(self._pb_intlkdetail, APUInterlockDetails, self, prefix=self._prefix, device=self._device) self._ld_hwsys = QLabel('Hardware\n&LowLevel', self, alignment=Qt.AlignCenter) self._led_hwsysresume = PyDMLedMultiChannel( self, { self.dev_pref.substitute(propty='StateHw-Mon'): { 'value': [0x4C, 0x3C], 'comp': 'in' }, self.dev_pref.substitute(propty='State-Mon'): { 'value': [1, 4], 'comp': 'in' }, self.dev_pref.substitute(propty='IsOperational-Mon'): 1 }) self._led_hwsysresume.offColor = PyDMLed.Yellow self._led_hwsysresume.onColor = PyDMLed.LightGreen self._pb_hwsysdetail = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self) self._pb_hwsysdetail.setObjectName('dtl') self._pb_hwsysdetail.setStyleSheet( "#dtl{min-width:25px; max-width:25px; icon-size:20px;}") connect_window(self._pb_hwsysdetail, APUHardLLDetails, self, prefix=self._prefix, device=self._device) self._ld_reset = QLabel('Reset', self, alignment=Qt.AlignCenter) self._pb_reset = PyDMPushButton(self, label='', icon=qta.icon('fa5s.sync')) self._pb_reset.setToolTip('Reset active alarms.') self._pb_reset.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_reset.pressValue = 2 # Reset self._pb_reset.setObjectName('Reset') self._pb_reset.setStyleSheet( '#Reset{min-width:30px; max-width:30px; icon-size:25px;}') gbox_alrmintlk = QGroupBox('Status') lay_alrmintlk = QGridLayout(gbox_alrmintlk) lay_alrmintlk.addWidget(self._pb_alarmdetail, 0, 0) lay_alrmintlk.addWidget(self._ld_alarm, 0, 1) lay_alrmintlk.addWidget(self._led_alarm, 0, 2) lay_alrmintlk.addWidget(self._pb_intlkdetail, 1, 0) lay_alrmintlk.addWidget(self._ld_intlk, 1, 1) lay_alrmintlk.addWidget(self._led_intlkresume, 1, 2) lay_alrmintlk.addWidget(self._pb_hwsysdetail, 2, 0) lay_alrmintlk.addWidget(self._ld_hwsys, 2, 1) lay_alrmintlk.addWidget(self._led_hwsysresume, 2, 2) lay_alrmintlk.addWidget(self._ld_reset, 3, 1) lay_alrmintlk.addWidget(self._pb_reset, 3, 2) return gbox_alrmintlk def _ctrlModeWidget(self): self._led_ctrlmode = PyDMLed( self, self.dev_pref.substitute(propty='IsRemote-Mon')) self._led_ctrlmode.offColor = PyDMLed.Red self._led_ctrlmode.onColor = PyDMLed.LightGreen self._lb_ctrlmode = PyDMLabel( self, self.dev_pref.substitute(propty='Interface-Mon')) gbox_ctrlmode = QGroupBox('Control Mode') lay_ctrlmode = QHBoxLayout(gbox_ctrlmode) lay_ctrlmode.setAlignment(Qt.AlignCenter) lay_ctrlmode.addWidget(self._led_ctrlmode) lay_ctrlmode.addWidget(self._lb_ctrlmode) return gbox_ctrlmode def _beamLinesCtrlWidget(self): self._ld_blinesenbl = QLabel('Enable', self) self._sb_blinesenbl = PyDMStateButton( self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sel')) self._led_blinesenbl = SiriusLedState( self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sts')) self._ld_blinesmon = QLabel('Status', self) self._led_blinesmon = SiriusLedState( self, self.dev_pref.substitute(propty='BeamLineCtrl-Mon')) gbox_blines = QGroupBox('Beam Lines Control', self) lay_blines = QGridLayout(gbox_blines) lay_blines.addWidget(self._ld_blinesenbl, 0, 0) lay_blines.addWidget(self._sb_blinesenbl, 0, 1) lay_blines.addWidget(self._led_blinesenbl, 0, 2) lay_blines.addWidget(self._ld_blinesmon, 1, 0) lay_blines.addWidget(self._led_blinesmon, 1, 1, 1, 2) return gbox_blines def _auxCommandsWidget(self): self._ld_speedlim = QLabel('Max Phase Speed\n[mm/s]', self) self._sb_speedlim = PyDMSpinbox( self, self.dev_pref.substitute(propty='MaxPhaseSpeed-SP')) self._sb_speedlim.showStepExponent = False self._sb_speedlim.setStyleSheet('max-width:4.5em;') self._lb_speedlim = PyDMLabel( self, self.dev_pref.substitute(propty='MaxPhaseSpeed-RB')) self._ld_homeaxis = QLabel('Do homing', self) self._pb_home = PyDMPushButton(self, label='', icon=qta.icon('mdi.keyboard-return')) self._pb_home.setToolTip('Execute homing for selected axis.') self._pb_home.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_home.pressValue = 10 # Home self._pb_home.setObjectName('Home') self._pb_home.setStyleSheet( '#Home{min-width:30px; max-width:30px; icon-size:25px;}') self._ld_standby = QLabel('Enable Standby Mode', self) self._pb_standby = PyDMPushButton( self, label='', icon=qta.icon('mdi.alpha-a-box-outline')) self._pb_standby.setToolTip( 'Enable standby mode for automatic motion.') self._pb_standby.channel = \ self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_standby.pressValue = 5 # Standby self._pb_standby.setObjectName('Standby') self._pb_standby.setStyleSheet( '#Standby{min-width:30px; max-width:30px; icon-size:25px;}') self._ld_lastcomm = QLabel('Last Command', self) self._lb_lastcomm = PyDMLabel( self, self.dev_pref.substitute(propty='LastDevCtrlCmd-Mon')) gbox_auxcmd = QGroupBox('Auxiliary Commands', self) lay_auxcmd = QGridLayout(gbox_auxcmd) lay_auxcmd.addWidget(self._ld_speedlim, 0, 0) lay_auxcmd.addWidget(self._sb_speedlim, 0, 1) lay_auxcmd.addWidget(self._lb_speedlim, 0, 2) lay_auxcmd.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Fixed), 1, 0) lay_auxcmd.addWidget(self._ld_homeaxis, 2, 0) lay_auxcmd.addWidget(self._pb_home, 2, 1, 1, 2, alignment=Qt.AlignCenter) lay_auxcmd.addWidget(self._ld_standby, 3, 0) lay_auxcmd.addWidget(self._pb_standby, 3, 1, 1, 2, alignment=Qt.AlignCenter) lay_auxcmd.addWidget(self._ld_lastcomm, 4, 0) lay_auxcmd.addWidget(self._lb_lastcomm, 4, 1, 1, 2) return gbox_auxcmd def contextMenuEvent(self, event): point = event.pos() if self._label_corrsH.underMouse(): menu = self.corrsH.contextMenuEvent(event, return_menu=True) menu.popup(self.mapToGlobal(point)) if self._label_corrsV.underMouse(): menu = self.corrsV.contextMenuEvent(event, return_menu=True) menu.popup(self.mapToGlobal(point))
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
def _get_acq_commom_params_grpbx(self): grp_bx = QGroupBox('Common Parameters', self) fbl = QFormLayout(grp_bx) lbl = QLabel('Non-linear Corr.', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_butled(grp_bx, 'PolyCalibration') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('Channel Rate', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_sel(grp_bx, 'TrigAcqChan') fbl.addRow(lbl, wid) lbl = QLabel('Trigger Type', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_sel(grp_bx, 'TrigAcqTrigger') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('Repeat', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair_butled(grp_bx, 'TrigAcqRepeat') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) if self.isring: lbl = QLabel('Nr of Shots', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'TrigNrShots') fbl.addRow(lbl, wid) self._set_detailed([lbl, wid]) lbl = QLabel('SamplesPre', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'TrigNrSamplesPre') fbl.addRow(lbl, wid) lbl = QLabel('SamplesPost', grp_bx, alignment=Qt.AlignCenter) wid = self.create_pair(grp_bx, 'TrigNrSamplesPost') fbl.addRow(lbl, wid) lbl = QLabel('Acquisition:', grp_bx, alignment=Qt.AlignCenter) strt = PyDMPushButton( grp_bx, label='', init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'), pressValue=self._csorb.TrigAcqCtrl.Start) strt.setToolTip('Start Acquisition') strt.setIcon(qta.icon('fa5s.play')) strt.setObjectName('strt') strt.setStyleSheet( '#strt{min-width:25px; max-width:25px; icon-size:20px;}') stop = PyDMPushButton( grp_bx, label='', init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'), pressValue=self._csorb.TrigAcqCtrl.Stop) stop.setToolTip('Stop Acquisition') stop.setIcon(qta.icon('fa5s.stop')) stop.setObjectName('stop') stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') abrt = PyDMPushButton( grp_bx, label='', init_channel=self.devpref.substitute(propty='TrigAcqCtrl-Sel'), pressValue=self._csorb.TrigAcqCtrl.Abort) abrt.setToolTip('Abort Acquisition') abrt.setIcon(qta.icon('fa5s.ban')) abrt.setObjectName('abrt') abrt.setStyleSheet( '#abrt{min-width:25px; max-width:25px; icon-size:20px;}') pdmlbl = PyDMLabel(grp_bx, self.devpref.substitute(propty='TrigAcqCtrl-Sts')) pdmlbl.setObjectName('pdmlbl') pdmlbl.setStyleSheet('#pdmlbl{min-width:6em; max-width:6em;}') pdmlbl.setAlignment(Qt.AlignCenter) hbl = QHBoxLayout() fbl.addRow(hbl) hbl.addStretch() hbl.addWidget(lbl) hbl.addWidget(strt) hbl.addWidget(stop) hbl.addWidget(abrt) hbl.addWidget(pdmlbl) conf = PyDMPushButton( grp_bx, pressValue=1, init_channel=self.devpref.substitute(propty='TrigAcqConfig-Cmd')) conf.setToolTip('Resend Configurations') conf.setIcon(qta.icon('fa5s.sync')) conf.setObjectName('conf') conf.setStyleSheet( '#conf{min-width:25px; max-width:25px; icon-size:20px;}') sts = QPushButton('', grp_bx) sts.setIcon(qta.icon('fa5s.list-ul')) sts.setToolTip('Open Detailed Status View') sts.setObjectName('sts') sts.setStyleSheet( '#sts{min-width:25px; max-width:25px; icon-size:20px;}') Window = create_window_from_widget(StatusWidget, title='Orbit Status') connect_window(sts, Window, grp_bx, device=self.device, prefix=self.prefix, acc=self.acc, is_orb=True) pdm_led = SiriusLedAlert( grp_bx, self.devpref.substitute(propty='OrbStatus-Mon')) lbl = QLabel('Status:', grp_bx) hbl = QHBoxLayout() hbl.setSpacing(9) hbl.addStretch() hbl.addWidget(lbl) hbl.addWidget(pdm_led) hbl.addWidget(sts) hbl.addWidget(conf) fbl.addRow(hbl) return grp_bx
class OpticsCorrWindow(SiriusMainWindow): """Class to include some intelligence in the .ui files.""" def __init__(self, acc, opticsparam, parent=None, prefix=_VACA_PREFIX): """Initialize some widgets.""" super(OpticsCorrWindow, self).__init__(parent) self.prefix = prefix self.acc = acc.upper() self.param = opticsparam self.ioc_prefix = _PVName( self.acc+'-Glob:AP-'+self.param.title()+'Corr') self.ioc_prefix = self.ioc_prefix.substitute(prefix=self.prefix) self.title = self.acc + ' ' + self.param.title() + ' Correction' if self.param == 'tune': self.param_pv = 'DeltaTune{0}-{1}' self.intstrength = 'KL' self.intstrength_calcdesc = 'DeltaKL-Mon' self.intstrength_calcpv = 'DeltaKL{}-Mon' self.fams = list(_Const.SI_QFAMS_TUNECORR) if self.acc == 'SI' \ else list(_Const.BO_QFAMS_TUNECORR) elif self.param == 'chrom': self.param_pv = 'Chrom{0}-{1}' self.intstrength = 'SL' self.intstrength_calcdesc = 'CalcSL-Mon' self.intstrength_calcpv = 'SL{}-Mon' self.fams = list(_Const.SI_SFAMS_CHROMCORR) if self.acc == 'SI' \ else list(_Const.BO_SFAMS_CHROMCORR) self.setWindowTitle(self.title) self.setObjectName(self.acc+'App') self._setupUi() self.setFocus(True) self.setFocusPolicy(Qt.StrongFocus) def _setupUi(self): label = QLabel('<h3>'+self.title+'</h3>', self) label.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));""") self.gb_status = QGroupBox('Status', self) self.gb_status.setLayout(self._setupStatusLayout()) self.wid_optics = QWidget() lay_optics = QGridLayout(self.wid_optics) lay_optics.setContentsMargins(0, 0, 0, 0) self.gb_optprm = QGroupBox( 'ΔTune' if self.param == 'tune' else 'Chromaticity', self) self.gb_optprm.setLayout(self._setupOpticsParamLayout()) if self.param == 'tune': self.pb_updref = PyDMPushButton( self, label='Update Reference', pressValue=1, init_channel=self.ioc_prefix.substitute(propty='SetNewRefKL-Cmd')) self.pb_updref.setStyleSheet('min-height:2.4em; max-height:2.4em;') lay_optics.addWidget(self.pb_updref, 0, 0, 1, 2) lay_optics.addWidget(self.gb_optprm, 1, 0) if self.acc == 'SI': self.gb_digmon = QGroupBox('Tune Monitor', self) self.gb_digmon.setLayout(self._setupDigMonLayout()) lay_optics.addWidget(self.gb_digmon, 1, 1) lay_optics.setColumnStretch(0, 3) lay_optics.setColumnStretch(1, 1) else: lay_optics.addWidget(self.gb_optprm, 0, 0) self.gb_fams = QGroupBox('Families', self) self.gb_fams.setLayout(self._setupFamiliesLayout()) self.gb_fams.setSizePolicy(QSzPly.Preferred, QSzPly.Expanding) self.gb_iocctrl = QGroupBox('IOC Control', self) self.gb_iocctrl.setLayout(self._setupIOCControlLayout()) cwt = QWidget() self.setCentralWidget(cwt) if self.acc == 'SI': vlay1 = QVBoxLayout() vlay1.setAlignment(Qt.AlignTop) vlay1.addWidget(self.wid_optics) vlay1.addWidget(self.gb_fams) lay = QGridLayout(cwt) lay.addWidget(label, 0, 0, 1, 2) lay.addLayout(vlay1, 1, 0, alignment=Qt.AlignTop) lay.addWidget(self.gb_iocctrl, 1, 1) lay.addWidget(self.gb_status, 2, 0, 1, 2) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 1) lay.setRowStretch(0, 1) lay.setRowStretch(1, 15) lay.setRowStretch(2, 5) else: lay = QVBoxLayout(cwt) lay.addWidget(label) lay.addWidget(self.wid_optics) lay.addWidget(self.gb_fams) lay.addWidget(self.gb_iocctrl) lay.addWidget(self.gb_status) self.setStyleSheet(""" PyDMLabel{ qproperty-alignment: AlignCenter; }""") def _setupStatusLayout(self): self.log_label = PyDMLogLabel( self, self.ioc_prefix.substitute(propty='Log-Mon')) lay = QVBoxLayout() lay.addWidget(self.log_label) return lay def _setupOpticsParamLayout(self): self.lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter) self.lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter) self.lb_sp = QLabel('<h4>SP</h4>', self, alignment=Qt.AlignCenter) self.lb_rb = QLabel('<h4>RB</h4>', self, alignment=Qt.AlignCenter) self.lb_mon = QLabel( '<h4>Estimative</h4>', self, alignment=Qt.AlignCenter) self.sb_paramx = PyDMSpinbox(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'SP'))) self.sb_paramx.showStepExponent = False self.sb_paramy = PyDMSpinbox(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'SP'))) self.sb_paramy.showStepExponent = False self.lb_paramx = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'RB'))) self.lb_paramy = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'RB'))) self.lb_prmmonx = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'Mon'))) self.lb_prmmony = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'Mon'))) self.bt_apply = PyDMPushButton( self, label='Apply', pressValue=1, init_channel=self.ioc_prefix.substitute( propty='ApplyDelta-Cmd')) lay = QGridLayout() lay.addWidget(self.lb_sp, 0, 1) lay.addWidget(self.lb_rb, 0, 2) lay.addWidget(self.lb_x, 1, 0) lay.addWidget(self.sb_paramx, 1, 1) lay.addWidget(self.lb_paramx, 1, 2) lay.addWidget(self.lb_y, 2, 0) lay.addWidget(self.sb_paramy, 2, 1) lay.addWidget(self.lb_paramy, 2, 2) lay.addWidget(self.lb_mon, 0, 3) lay.addWidget(self.lb_prmmonx, 1, 3) lay.addWidget(self.lb_prmmony, 2, 3) lay.addWidget(self.bt_apply, 3, 1) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 5) lay.setColumnStretch(2, 5) lay.setColumnStretch(3, 5) if self.acc == 'SI' and self.param == 'chrom': self._icon_absval = qta.icon( 'mdi.alpha-a', 'mdi.alpha-b', 'mdi.alpha-s', options=[ dict(scale_factor=1.5, offset=(-0.4, 0.0)), dict(scale_factor=1.5, offset=(0.0, 0.0)), dict(scale_factor=1.5, offset=(+0.4, 0.0))]) self._icon_delta = qta.icon('mdi.delta') self._is_setting = 'absolut' self.pb_change_sp = QPushButton(self._icon_absval, '', self) self.pb_change_sp.clicked.connect(self._change_chrom_sp) self.sb_paramx_delta = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='DeltaChromX-SP')) self.sb_paramx_delta.showStepExponent = False self.sb_paramx_delta.setVisible(False) self.sb_paramy_delta = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='DeltaChromY-SP')) self.sb_paramy_delta.showStepExponent = False self.sb_paramy_delta.setVisible(False) self.lb_paramx_delta = PyDMLabel( self, self.ioc_prefix.substitute(propty='DeltaChromX-RB')) self.lb_paramx_delta.setVisible(False) self.lb_paramy_delta = PyDMLabel( self, self.ioc_prefix.substitute(propty='DeltaChromY-RB')) self.lb_paramy_delta.setVisible(False) self.lb_mon.setText('Implem.\nEstimative') self.lb_mon.setStyleSheet('font-weight: bold;') self.lb_calcmon = QLabel( 'Calcd.\nEstimative', self, alignment=Qt.AlignCenter) self.lb_calcmon.setStyleSheet('font-weight: bold;') self.lb_prmcalcmonx = PyDMLabel( self, self.ioc_prefix.substitute(propty='CalcChromX-Mon')) self.lb_prmcalcmony = PyDMLabel( self, self.ioc_prefix.substitute(propty='CalcChromY-Mon')) lay.addWidget(self.pb_change_sp, 0, 0) lay.addWidget(self.sb_paramx_delta, 1, 1) lay.addWidget(self.sb_paramy_delta, 2, 1) lay.addWidget(self.lb_paramx_delta, 1, 2) lay.addWidget(self.lb_paramy_delta, 2, 2) lay.addWidget(self.lb_calcmon, 0, 4) lay.addWidget(self.lb_prmcalcmonx, 1, 4) lay.addWidget(self.lb_prmcalcmony, 2, 4) return lay def _setupDigMonLayout(self): lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter) lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter) self.lb_tunex = PyDMLabel(self, 'SI-Glob:DI-Tune-H:TuneFrac-Mon') self.lb_tuney = PyDMLabel(self, 'SI-Glob:DI-Tune-V:TuneFrac-Mon') lay = QGridLayout() lay.addWidget(lb_x, 0, 0) lay.addWidget(self.lb_tunex, 0, 1) lay.addWidget(lb_y, 1, 0) lay.addWidget(self.lb_tuney, 1, 1) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 5) return lay def _setupFamiliesLayout(self): lay = QGridLayout() lb_family = QLabel('<h4>Family</h4>', self, alignment=Qt.AlignCenter) lb_family.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_family, 0, 1) lb_rbdesc = QLabel('<h4>'+self.intstrength+'-RB</h4>', self, alignment=Qt.AlignCenter) lb_rbdesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_rbdesc, 0, 2) if self.param == 'tune': lb_refdesc = QLabel('<h4>RefKL-Mon</h4>', self, alignment=Qt.AlignCenter) lb_refdesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_refdesc, 0, 3) lb_lastddesc = QLabel('<h4>'+self.intstrength_calcdesc+'</h4>', self, alignment=Qt.AlignCenter) lb_lastddesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_lastddesc, 0, 4) row = 1 for fam in self.fams: dev_name = _PVName(self.acc+'-Fam:PS-'+fam) pref_name = dev_name.substitute(prefix=self.prefix) 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;}""") _hlautil.connect_window( pbt, _PSDetailWindow, parent=self, psname=dev_name) lay.addWidget(pbt, row, 0) lb_name = QLabel(fam, self, alignment=Qt.AlignCenter) lay.addWidget(lb_name, row, 1) lb_rb = PyDMLabel(self, pref_name.substitute( propty=self.intstrength+'-RB')) lay.addWidget(lb_rb, row, 2) if self.param == 'tune': lb_ref = PyDMLabel(self, self.ioc_prefix.substitute( propty='RefKL'+fam+'-Mon')) lay.addWidget(lb_ref, row, 3) lb_calc = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.intstrength_calcpv.format(fam))) lay.addWidget(lb_calc, row, 4) row += 1 return lay def _setupIOCControlLayout(self): lay = QGridLayout() lb_sts = QLabel('<h4>Status</h4>', self) self.led_sts = _StatusLed(self, self.ioc_prefix.substitute( propty='Status-Mon')) lay.addWidget(lb_sts, 0, 0) lay.addWidget(self.led_sts, 0, 1, alignment=Qt.AlignLeft) lb_conf = QLabel('<h4>Configuration</h4>') self.bt_dtls = QPushButton(qta.icon('fa5s.list-ul'), '', self) _hlautil.connect_window( self.bt_dtls, _CorrParamsDetailWindow, parent=self, acc=self.acc, opticsparam=self.param, prefix=self.prefix, fams=self.fams) lay.addWidget(lb_conf, 2, 0, 1, 2) lay.addWidget(self.bt_dtls, 2, 2, alignment=Qt.AlignRight) lb_cname = QLabel('Name', self) self.le_cname = _ConfigLineEdit( self, self.ioc_prefix.substitute( propty='ConfigName-SP')) self.lb_cname = PyDMLabel(self, self.ioc_prefix.substitute( propty='ConfigName-RB')) lay.addWidget(lb_cname, 3, 0) lay.addWidget(self.le_cname, 3, 1, 1, 2) lay.addWidget(self.lb_cname, 4, 1, 1, 2) row = 5 if self.acc == 'SI': lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 5, 0) row = 6 if self.param == 'chrom': lb_meas_chrom = QLabel('<h4>Chrom. Measurement</h4>') lay.addWidget(lb_meas_chrom, 6, 0, 1, 3) lb_meas_chrom_dfRF = QLabel('ΔFreq RF [Hz]', self) self.sb_meas_chrom_dfRF = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromDeltaFreqRF-SP')) self.sb_meas_chrom_dfRF.showStepExponent = False self.lb_meas_chrom_dfRF = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromDeltaFreqRF-RB')) lay.addWidget(lb_meas_chrom_dfRF, 7, 0) lay.addWidget(self.sb_meas_chrom_dfRF, 7, 1) lay.addWidget(self.lb_meas_chrom_dfRF, 7, 2) lb_meas_chrom_wait = QLabel('Wait Tune [s]', self) self.sb_meas_chrom_wait = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromWaitTune-SP')) self.sb_meas_chrom_wait.showStepExponent = False self.lb_meas_chrom_wait = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromWaitTune-RB')) lay.addWidget(lb_meas_chrom_wait, 8, 0) lay.addWidget(self.sb_meas_chrom_wait, 8, 1) lay.addWidget(self.lb_meas_chrom_wait, 8, 2) lb_meas_chrom_nrsteps = QLabel('Nr Steps', self) self.sb_meas_chrom_nrsteps = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromNrSteps-SP')) self.sb_meas_chrom_nrsteps.showStepExponent = False self.lb_meas_chrom_nrsteps = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromNrSteps-RB')) lay.addWidget(lb_meas_chrom_nrsteps, 9, 0) lay.addWidget(self.sb_meas_chrom_nrsteps, 9, 1) lay.addWidget(self.lb_meas_chrom_nrsteps, 9, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 10, 0) lb_meas_chrom_x = QLabel('Meas. Chrom X', self) self.lb_meas_chrom_x = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromX-Mon')) lay.addWidget(lb_meas_chrom_x, 11, 0) lay.addWidget(self.lb_meas_chrom_x, 11, 1) lb_meas_chrom_y = QLabel('Meas. Chrom Y', self) self.lb_meas_chrom_y = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromY-Mon')) lay.addWidget(lb_meas_chrom_y, 12, 0) lay.addWidget(self.lb_meas_chrom_y, 12, 1) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 13, 0) self.lb_meas_chrom_sts = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromStatus-Mon')) self.bt_meas_chrom_start = PyDMPushButton( self, icon=qta.icon('fa5s.play'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Start) self.bt_meas_chrom_start.setObjectName('start') self.bt_meas_chrom_start.setStyleSheet( '#start{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_chrom_stop = PyDMPushButton( self, icon=qta.icon('fa5s.stop'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Stop) self.bt_meas_chrom_stop.setObjectName('stop') self.bt_meas_chrom_stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_chrom_rst = PyDMPushButton( self, icon=qta.icon('fa5s.sync'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Reset) self.bt_meas_chrom_rst.setObjectName('rst') self.bt_meas_chrom_rst.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') hbox_cmd = QHBoxLayout() hbox_cmd.addWidget(self.bt_meas_chrom_start) hbox_cmd.addWidget(self.bt_meas_chrom_stop) hbox_cmd.addWidget(self.bt_meas_chrom_rst) lay.addWidget(self.lb_meas_chrom_sts, 14, 0, 1, 2) lay.addLayout(hbox_cmd, 14, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 15, 0) row = 15 # configuration measurement lb_meas_conf = QLabel('<h4>Config. Measurement</h4>') lay.addWidget(lb_meas_conf, row+1, 0, 1, 3) mag_type = 'Q' if self.param == 'tune' else 'S' unit = '[1/m]' if self.param == 'tune' else '[1/m2]' lb_meas_conf_dfamF = QLabel( 'Fam. Δ'+self.intstrength+' '+mag_type+'F '+unit, self) self.sb_meas_conf_dfamF = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'F-SP')) self.sb_meas_conf_dfamF.showStepExponent = False self.lb_meas_conf_dfamF = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'F-RB')) lay.addWidget(lb_meas_conf_dfamF, row+2, 0) lay.addWidget(self.sb_meas_conf_dfamF, row+2, 1) lay.addWidget(self.lb_meas_conf_dfamF, row+2, 2) lb_meas_conf_dfamD = QLabel( 'Fam. Δ'+self.intstrength+' '+mag_type+'D '+unit, self) self.sb_meas_conf_dfamD = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'D-SP')) self.sb_meas_conf_dfamD.showStepExponent = False self.lb_meas_conf_dfamD = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'D-RB')) lay.addWidget(lb_meas_conf_dfamD, row+3, 0) lay.addWidget(self.sb_meas_conf_dfamD, row+3, 1) lay.addWidget(self.lb_meas_conf_dfamD, row+3, 2) lb_meas_conf_wait = QLabel('Wait [s]', self) self.sb_meas_conf_wait = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='MeasConfigWait-SP')) self.sb_meas_conf_wait.showStepExponent = False self.lb_meas_conf_wait = PyDMLabel( self, self.ioc_prefix.substitute(propty='MeasConfigWait-RB')) lay.addWidget(lb_meas_conf_wait, row+4, 0) lay.addWidget(self.sb_meas_conf_wait, row+4, 1) lay.addWidget(self.lb_meas_conf_wait, row+4, 2) lb_meas_conf_cname = QLabel('Name to save', self) self.le_meas_conf_name = PyDMLineEdit( self, self.ioc_prefix.substitute(propty='MeasConfigName-SP')) self.lb_meas_conf_name = PyDMLabel( self, self.ioc_prefix.substitute(propty='MeasConfigName-RB')) lay.addWidget(lb_meas_conf_cname, row+5, 0) lay.addWidget(self.le_meas_conf_name, row+5, 1, 1, 2) lay.addWidget(self.lb_meas_conf_name, row+6, 1, 1, 2) lb_meas_conf_save = QLabel('Force Save', self) self.bt_meas_conf_save = PyDMPushButton( self, icon=qta.icon('mdi.content-save'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfigSave-Cmd'), pressValue=1) self.bt_meas_conf_save.setObjectName('save') self.bt_meas_conf_save.setStyleSheet( '#save{min-width:25px; max-width:25px; icon-size:20px;}') lay.addWidget(lb_meas_conf_save, row+7, 0) lay.addWidget( self.bt_meas_conf_save, row+7, 1, alignment=Qt.AlignLeft) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+8, 0) self.lb_meas_conf_sts = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigStatus-Mon')) self.bt_meas_conf_start = PyDMPushButton( self, icon=qta.icon('fa5s.play'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Start) self.bt_meas_conf_start.setObjectName('start') self.bt_meas_conf_start.setStyleSheet( '#start{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_conf_stop = PyDMPushButton( self, icon=qta.icon('fa5s.stop'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Stop) self.bt_meas_conf_stop.setObjectName('stop') self.bt_meas_conf_stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_conf_rst = PyDMPushButton( self, icon=qta.icon('fa5s.sync'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Reset) self.bt_meas_conf_rst.setObjectName('rst') self.bt_meas_conf_rst.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') hbox_cmd = QHBoxLayout() hbox_cmd.addWidget(self.bt_meas_conf_start) hbox_cmd.addWidget(self.bt_meas_conf_stop) hbox_cmd.addWidget(self.bt_meas_conf_rst) lay.addWidget(self.lb_meas_conf_sts, row+9, 0, 1, 2) lay.addLayout(hbox_cmd, row+9, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+10, 0) # correction settings lb_corr = QLabel('<h4>Settings</h4>') lay.addWidget(lb_corr, row+11, 0, 1, 3) lb_meth = QLabel('Method', self) self.cb_method = PyDMEnumComboBox( self, self.ioc_prefix.substitute(propty='CorrMeth-Sel')) self.lb_method = PyDMLabel( self, self.ioc_prefix.substitute(propty='CorrMeth-Sts')) lay.addWidget(lb_meth, row+12, 0) lay.addWidget(self.cb_method, row+12, 1) lay.addWidget(self.lb_method, row+12, 2) lb_grp = QLabel('Grouping', self) self.cb_group = PyDMEnumComboBox( self, self.ioc_prefix.substitute(propty='CorrGroup-Sel')) self.lb_group = PyDMLabel( self, self.ioc_prefix.substitute(propty='CorrGroup-Sts')) lay.addWidget(lb_grp, row+13, 0) lay.addWidget(self.cb_group, row+13, 1) lay.addWidget(self.lb_group, row+13, 2) if self.param == 'tune': lb_sync = QLabel('Sync', self) self.bt_sync = PyDMStateButton( self, self.ioc_prefix.substitute(propty='SyncCorr-Sel')) self.bt_sync.shape = 1 self.lb_sync = PyDMLabel( self, self.ioc_prefix.substitute(propty='SyncCorr-Sts')) lay.addWidget(lb_sync, row+14, 0) lay.addWidget(self.bt_sync, row+14, 1) lay.addWidget(self.lb_sync, row+14, 2) row = row + 15 lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Expanding), row, 0) return lay def _change_chrom_sp(self): cond = self._is_setting == 'absolut' self._is_setting = 'delta' if cond else 'absolut' icon = self._icon_delta if cond else self._icon_absval textX = '<h4>Δ-SP</h4>' if cond else '<h4>SP</h4>' textY = '<h4>Δ-RB</h4>' if cond else '<h4>RB</h4>' self.sb_paramx.setVisible(not cond) self.lb_paramx.setVisible(not cond) self.sb_paramy.setVisible(not cond) self.lb_paramy.setVisible(not cond) self.sb_paramx_delta.setVisible(cond) self.lb_paramx_delta.setVisible(cond) self.sb_paramy_delta.setVisible(cond) self.lb_paramy_delta.setVisible(cond) self.pb_change_sp.setIcon(icon) self.lb_sp.setText(textX) self.lb_rb.setText(textY)
def _get_config_widget(self, parent): gb_pos = QGroupBox('Image Processing ', parent) meth_sp = PyDMEnumComboBox( gb_pos, init_channel=self._dev+':CalcMethod-Sel') meth_lb = SiriusLabel(gb_pos, init_channel=self._dev+':CalcMethod-Sts') meth_ld = QLabel('Method', gb_pos) nrpt_ld = QLabel('Num. Pts.', gb_pos) nrpt_sp = SiriusSpinbox( gb_pos, init_channel=self._dev+':NrAverages-SP') nrpt_sp.showStepExponent = False rdb = PyDMLabel(gb_pos, init_channel=self._dev+':NrAverages-RB') rdb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) slsh = QLabel('/', gb_pos, alignment=Qt.AlignCenter) slsh.setStyleSheet('min-width:0.7em; max-width:0.7em;') cnt = PyDMLabel(gb_pos, init_channel=self._dev+':BufferSize-Mon') cnt.setAlignment(Qt.AlignRight | Qt.AlignVCenter) cnt.setToolTip('Current Buffer Size') pbt = PyDMPushButton( gb_pos, init_channel=self._dev+':ResetBuffer-Cmd', pressValue=1) pbt.setToolTip('Reset Buffer') pbt.setIcon(qta.icon('mdi.delete-empty')) pbt.setObjectName('rst') pbt.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') nrpt_wd = QWidget(gb_pos) hbl = QHBoxLayout(nrpt_wd) hbl.addWidget(pbt) hbl.addStretch() hbl.addWidget(cnt) hbl.addWidget(slsh) hbl.addWidget(rdb) rsx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeX-SP') rsx_sp.showStepExponent = False rsx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeX-RB') rsx_ld = QLabel('ROI Size X', gb_pos) rsy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeY-SP') rsy_sp.showStepExponent = False rsy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeY-RB') rsy_ld = QLabel('ROI Size Y', gb_pos) ra_bt = PyDMStateButton( gb_pos, init_channel=self._dev+':ROIAutoCenter-Sel') ra_lb = SiriusLabel( gb_pos, init_channel=self._dev+':ROIAutoCenter-Sts') ra_ld = QLabel('Auto Center:', gb_pos) rcx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterX-SP') rcx_sp.showStepExponent = False rcx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterX-RB') rcx_ld = QLabel('ROI Center X', gb_pos) rcy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterY-SP') rcy_sp.showStepExponent = False rcy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterY-RB') rcy_ld = QLabel('ROI Center Y', gb_pos) sts_bt = QPushButton(qta.icon('fa5s.ellipsis-h'), '', gb_pos) sts_bt.setToolTip('Open Detailed Configs') sts_bt.setObjectName('sts') sts_bt.setStyleSheet( '#sts{min-width:25px; max-width:25px; icon-size:20px;}') Window = create_window_from_widget( _DetailedWidget, title='Image Processing Detailed Configs') connect_window( sts_bt, Window, gb_pos, device=self._dev, convertion_set=self._conv_set) hlay = QHBoxLayout() hlay.addWidget(sts_bt, alignment=Qt.AlignRight) lay = QGridLayout(gb_pos) if self._ori == 'V': lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(meth_sp, 0, 1) lay.addWidget(meth_lb, 1, 1) lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft) lay.addWidget(nrpt_sp, 2, 1) lay.addWidget(nrpt_wd, 3, 0, 1, 2) lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rsx_sp, 4+0, 1) lay.addWidget(rsx_lb, 4+1, 1) lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rsy_sp, 6+0, 1) lay.addWidget(rsy_lb, 6+1, 1) lay.addWidget(sts_bt, 0, 0+4, alignment=Qt.AlignRight) lay.addWidget(ra_ld, 2+0, 0+3, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(ra_bt, 2+0, 1+3) lay.addWidget(ra_lb, 2+1, 1+3, alignment=Qt.AlignLeft) lay.addWidget(rcx_ld, 4+0, 0+3, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rcx_sp, 4+0, 1+3) lay.addWidget(rcx_lb, 4+1, 1+3) lay.addWidget(rcy_ld, 6+0, 0+3, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rcy_sp, 6+0, 1+3) lay.addWidget(rcy_lb, 6+1, 1+3) else: lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(meth_sp, 0, 1) lay.addWidget(meth_lb, 1, 1) lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft) lay.addWidget(nrpt_sp, 2, 1) lay.addWidget(nrpt_wd, 3, 0, 1, 2) lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rsx_sp, 4+0, 1) lay.addWidget(rsx_lb, 4+1, 1) lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rsy_sp, 6+0, 1) lay.addWidget(rsy_lb, 6+1, 1) lay.addWidget(ra_ld, 8+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(ra_bt, 8+0, 1) lay.addWidget(ra_lb, 8+1, 1, alignment=Qt.AlignLeft) lay.addWidget(rcx_ld, 10+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rcx_sp, 10+0, 1) lay.addWidget(rcx_lb, 10+1, 1) lay.addWidget(rcy_ld, 12+0, 0, 2, 1, alignment=Qt.AlignLeft) lay.addWidget(rcy_sp, 12+0, 1) lay.addWidget(rcy_lb, 12+1, 1) lay.addWidget(sts_bt, 14, 0, alignment=Qt.AlignLeft) lay.setRowStretch(15, 5) return gb_pos
class TuneDetails(SiriusMainWindow): """Tune Details.""" def __init__(self, parent=None, prefix='', section='', orientation='H', background=None): """Init.""" super().__init__(parent) self.prefix = prefix self.section = section.upper() self.orientation = orientation self.device = SiriusPVName('AC-Glob:DI-Tune-O') self.device = self.device.substitute(sec=self.section, idx=self.orientation, prefix=self.prefix) if self.section == 'BO': self.trigger = SiriusPVName('BO-Glob:TI-TuneProc') self.background = background self.setWindowTitle(self.device + ' Detailed Settings') self.setObjectName(self.section + 'App') self._setupUi() self.setFocusPolicy(Qt.StrongFocus) def _setupUi(self): cw = QWidget(self) self.setCentralWidget(cw) # title self.title_label = QLabel( '<h3>Tune ' + self.orientation + ' Detailed Settings<h3>', self) self.title_label.setObjectName('title') pal = self.title_label.palette() pal.setColor(QPalette.Background, self.background) self.title_label.setAutoFillBackground(True) self.title_label.setPalette(pal) # measurement self.meas_gbox = QGroupBox('Measurement', self) self.meas_gbox.setLayout(self._measLayout()) # config self.config_gbox = QGroupBox('Configuration', self) self.config_gbox.setLayout(self._configLayout()) if self.section == 'BO': # trigger self.trg_gbox = QGroupBox('Trigger', self) self.trg_gbox.setLayout(QHBoxLayout()) self.trg_gbox.layout().addWidget( HLTriggerSimple(self.trg_gbox, device='BO-Glob:TI-TuneProc', prefix=self.prefix, duration=True, nrpulses=True)) # spectrogram view self.spec_gbox = QGroupBox('Spectrogram View', self) self.spec_gbox.setLayout(self._specViewLayout()) # roi self.roi_gbox = QGroupBox('ROI', self) self.roi_gbox.setLayout(self._roiLayout()) vbox = QVBoxLayout() vbox.addWidget(self.trg_gbox) vbox.addWidget(self.spec_gbox) vbox.addWidget(self.roi_gbox) vbox.addWidget(self.config_gbox) lay = QGridLayout(cw) lay.addWidget(self.title_label, 0, 0, 1, 2) lay.addWidget(self.meas_gbox, 1, 0) lay.addLayout(vbox, 1, 1) else: lay = QVBoxLayout(cw) lay.addWidget(self.title_label) lay.addWidget(self.meas_gbox) lay.addWidget(self.config_gbox) self.setStyleSheet(""" QLed{ min-width:1.29em; max-width:1.29em; } #title { min-height:1.29em; max-height:1.29em; qproperty-alignment: "AlignVCenter | AlignHCenter"; } PyDMLabel, PyDMSpinbox, PyDMEnumComboBox, PyDMStateButton{ min-width:6em; max-width:6em; }""") def _measLayout(self): # Acquisition lbl_acq = QLabel('Acquisition', self) self.bt_acq = PyDMStateButton( self, self.device.substitute(propty='SpecAnaGetSpec-Sel')) self.bt_acq.shape = 1 self.led_acq = SiriusLedState( self, self.device.substitute(propty='SpecAnaGetSpec-Sts')) hbox_acq = QHBoxLayout() hbox_acq.addWidget(self.bt_acq) hbox_acq.addWidget(self.led_acq) # Excitation lbl_drive = QLabel('Excitation', self) self.bt_drive = PyDMStateButton( self, self.device.substitute(propty='Enbl-Sel')) self.bt_drive.shape = 1 value = 0b111 if self.section == 'BO' else 1 self.led_drive = PyDMLedMultiChannel( parent=self, channels2values={self.device.substitute(propty='Enbl-Sts'): value}) self.led_drive.setOffColor(PyDMLed.DarkGreen) hbox_drive = QHBoxLayout() hbox_drive.addWidget(self.bt_drive) hbox_drive.addWidget(self.led_drive) # Excitation Status Detailed gbox_enblsts = QGridLayout() lbl_enblsts = QLabel('Excitation\nEnable Status\nDetailed', self, alignment=Qt.AlignVCenter | Qt.AlignRight) if self.section == 'BO': # # Carrier Generator self.led_carrier = SiriusLedState( self, self.device.substitute(propty='EnblCarrierGen-Sts')) gbox_enblsts.addWidget(self.led_carrier, 0, 0) gbox_enblsts.addWidget(QLabel('Carrier Generator'), 0, 1) # # Noise Generator self.led_noise = SiriusLedState( self, self.device.substitute(propty='EnblNoiseGen-Sts')) gbox_enblsts.addWidget(self.led_noise, 1, 0) gbox_enblsts.addWidget(QLabel('Noise Generator'), 1, 1) else: # # Noise Generator self.led_trkgen = SiriusLedState( self, self.device.substitute(propty='SpecAnaTrkGen-Sts')) gbox_enblsts.addWidget(self.led_trkgen, 1, 0) gbox_enblsts.addWidget(QLabel('Tracking Generator'), 1, 1) # # Amplifier self.led_amp = SiriusLedState( self, self.device.substitute(propty='EnblAmp-Sts')) gbox_enblsts.addWidget(self.led_amp, 2, 0) gbox_enblsts.addWidget(QLabel('Amplifier'), 2, 1) if self.section == 'BO': # Frame Count lbl_acqcnt = QLabel('Frame Count', self) dev = self.device.substitute(dev='TuneProc') self.lb_acqcnt = PyDMLabel(self, dev.substitute(propty='FrameCount-Mon')) self.lb_acqcnt.setAlignment(Qt.AlignCenter) self.led_acqcnt = PyDMLedMultiChannel(parent=self) self.trigNrPulseChannel = SiriusConnectionSignal( self.trigger.substitute(prefix=self.prefix, propty='NrPulses-RB')) self.trigNrPulseChannel.new_value_signal[int].connect( self._updateNrAcq) hbox_acqcnt = QHBoxLayout() hbox_acqcnt.addWidget(self.lb_acqcnt) hbox_acqcnt.addWidget(self.led_acqcnt) # Nr. Samples p/ spec lbl_nrsmp = QLabel('Nr. Samples p/ Spec.', self) self.lb_nrsmp = PyDMLabel(parent=self, init_channel=self.device.substitute( dev='TuneProc', propty_name='SwePts', propty_suffix='RB')) if self.section == 'SI': # Acquisition Time lbl_acqtime = QLabel('Acq. Time', self) self.cb_acqtime = PyDMEnumComboBox( parent=self, init_channel=self.device.substitute(dev='TuneProc', propty_name='Trace', propty_suffix='Mon', field='SCAN')) # Sweep time lbl_swetime = QLabel('Sweep Time [ms]', self) self.lb_swetime = PyDMLabel(parent=self, init_channel=self.device.substitute( dev='TuneProc', propty_name='SweTime', propty_suffix='Mon')) # Span lbl_span = QLabel('Span [kHz]', self) self.le_span = PyDMLineEdit(self, self.device.substitute(propty='Span-SP')) self.le_span.precisionFromPV = True self.lb_span = PyDMLabel(self, self.device.substitute(propty='Span-RB')) hbox_span = QHBoxLayout() hbox_span.addWidget(self.le_span) hbox_span.addWidget(self.lb_span) # RBW lbl_rbw = QLabel('RBW', self) if self.section == 'BO': self.cb_rbw = PyDMEnumComboBox( self, self.device.substitute(propty='SpecAnaRBW-Sel')) else: items = [ '1 Hz', '2 Hz', '3 Hz', '5 Hz', '10 Hz', '20 Hz', '30 Hz', '50 Hz', '100 Hz', '200 Hz', '300 Hz', '500 Hz', '1 kHz', '2 kHz', '3 kHz', '5 kHz', '6.25 kHz', '10 kHz', '20 kHz', '30 kHz', '50 kHz', '100 kHz', '200 kHz', '300 kHz', '500 kHz', '1 MHz', '2 MHz', '3 MHz', '5 MHz', '10 MHz' ] self.cb_rbw = SiriusStringComboBox( self, self.device.substitute(propty='SpecAnaRBW-Sel'), items=items) self.lb_rbw = PyDMLabel( self, self.device.substitute(propty='SpecAnaRBW-Sts')) hbox_rbw = QHBoxLayout() hbox_rbw.addWidget(self.cb_rbw) hbox_rbw.addWidget(self.lb_rbw) # Harmonic lbl_h = QLabel('Harmonic (n)', self) self.sb_h = PyDMSpinbox(self, self.device.substitute(propty='RevN-SP')) self.sb_h.showStepExponent = False self.sb_h.precisionFromPV = True self.lb_h = PyDMLabel(self, self.device.substitute(propty='RevN-RB')) hbox_h = QHBoxLayout() hbox_h.addWidget(self.sb_h) hbox_h.addWidget(self.lb_h) # Harmonic Frequency lbl_Fh = QLabel('Harm. Freq. [kHz]', self) self.lb_Fh = PyDMLabel(parent=self) self.lb_Fh.setToolTip('Frf/(h*n)') self.lb_Fh.channel = self.device.substitute(propty='FreqRevN-Mon') # Frequency Offset lbl_foff = QLabel('Frequency Offset [kHz]', self) self.sb_foff = PyDMSpinbox(self, self.device.substitute(propty='FreqOff-SP')) self.sb_foff.showStepExponent = False self.sb_foff.precisionFromPV = True self.lb_foff = PyDMLabel(self, self.device.substitute(propty='FreqOff-RB')) hbox_foff = QHBoxLayout() hbox_foff.addWidget(self.sb_foff) hbox_foff.addWidget(self.lb_foff) # Center Frequency lbl_Fc = QLabel('Center Frequency [MHz]', self) self.le_Fc = PyDMLineEdit( self, self.device.substitute(propty='CenterFreq-SP')) self.le_Fc.precisionFromPV = True self.lb_Fc = PyDMLabel(self, self.device.substitute(propty='CenterFreq-RB')) hbox_Fc = QHBoxLayout() hbox_Fc.addWidget(self.le_Fc) hbox_Fc.addWidget(self.lb_Fc) # Lock Center Freq. lbl_autoFc = QLabel('Lock Center Frequency ', self) self.bt_autoFc = PyDMStateButton( self, self.device.substitute(propty='CenterFreqAuto-Sel')) self.bt_autoFc.shape = 1 self.led_autoFc = SiriusLedState( self, self.device.substitute(propty='CenterFreqAuto-Sts')) hbox_autoFc = QHBoxLayout() hbox_autoFc.addWidget(self.bt_autoFc) hbox_autoFc.addWidget(self.led_autoFc) # Amplifier Gain lbl_drivegain = QLabel('Amplifier Gain [dB]', self) self.sb_drivegain = PyDMSpinbox( self, self.device.substitute(propty='AmpGain-SP')) self.sb_drivegain.showStepExponent = False self.sb_drivegain.precisionFromPV = True self.lb_drivegain = PyDMLabel( self, self.device.substitute(propty='AmpGain-RB')) hbox_drivegain = QHBoxLayout() hbox_drivegain.addWidget(self.sb_drivegain) hbox_drivegain.addWidget(self.lb_drivegain) if self.section == 'BO': # Auto Configure Excitation lbl_driveauto = QLabel('Auto Config. Excit.', self) self.bt_driveauto = PyDMStateButton( self, self.device.substitute(propty='DriveAuto-Sel')) self.bt_driveauto.shape = 1 self.led_driveauto = SiriusLedState( self, self.device.substitute(propty='DriveAuto-Sts')) hbox_driveauto = QHBoxLayout() hbox_driveauto.addWidget(self.bt_driveauto) hbox_driveauto.addWidget(self.led_driveauto) # Noise Amplitude lbl_noiseamp = QLabel('Noise Amplitude [V]', self) self.sb_noiseamp = PyDMSpinbox( self, self.device.substitute(propty='NoiseAmpl-SP')) self.sb_noiseamp.showStepExponent = False self.sb_noiseamp.precisionFromPV = True self.lb_noiseamp = PyDMLabel( self, self.device.substitute(propty='NoiseAmpl-RB')) hbox_noiseamp = QHBoxLayout() hbox_noiseamp.addWidget(self.sb_noiseamp) hbox_noiseamp.addWidget(self.lb_noiseamp) else: # Noise Amplitude lbl_trkgenlvl = QLabel('Trk. Gen. Power [dBm]', self) self.sb_trkgenlvl = PyDMLineEdit( self, self.device.substitute(propty='SpecAnaTrkGenLvl-SP')) self.lb_trkgenlvl = PyDMLabel( self, self.device.substitute(propty='SpecAnaTrkGenLvl-RB')) hbox_trkgenlvl = QHBoxLayout() hbox_trkgenlvl.addWidget(self.sb_trkgenlvl) hbox_trkgenlvl.addWidget(self.lb_trkgenlvl) # Spectrum Acquisition lbl_getspec = QLabel('Spectrum Acq.', self) self.cb_getspec = PyDMStateButton( parent=self, init_channel=self.device.substitute(dev='TuneProc', propty_name='GetSpectrum', propty_suffix='Sel')) self.cb_getspec.shape = 1 self.lb_getspec = PyDMLed(parent=self, init_channel=self.device.substitute( dev='TuneProc', propty_name='GetSpectrum', propty_suffix='Sts')) hbox_getspec = QHBoxLayout() hbox_getspec.addWidget(self.cb_getspec) hbox_getspec.addWidget(self.lb_getspec) lay = QFormLayout() lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) lay.addRow(lbl_acq, hbox_acq) lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_drive, hbox_drive) lay.addRow(lbl_enblsts, gbox_enblsts) if self.section == 'BO': lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_acqcnt, hbox_acqcnt) lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_nrsmp, self.lb_nrsmp) if self.section == 'SI': lay.addRow(lbl_acqtime, self.cb_acqtime) lay.addRow(lbl_swetime, self.lb_swetime) lay.addRow(lbl_span, hbox_span) lay.addRow(lbl_rbw, hbox_rbw) lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_h, hbox_h) lay.addRow(lbl_Fh, self.lb_Fh) lay.addRow(lbl_foff, hbox_foff) lay.addRow(lbl_Fc, hbox_Fc) lay.addRow(lbl_autoFc, hbox_autoFc) lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_drivegain, hbox_drivegain) if self.section == 'BO': lay.addRow(lbl_driveauto, hbox_driveauto) lay.addRow(lbl_noiseamp, hbox_noiseamp) else: lay.addRow(lbl_trkgenlvl, hbox_trkgenlvl) lay.addItem(QSpacerItem(1, 6, QSzPlcy.Ignored, QSzPlcy.Fixed)) lay.addRow(lbl_getspec, hbox_getspec) return lay def _configLayout(self): self.bt_rst = PyDMPushButton( parent=self, init_channel=self.device.substitute(propty='Rst-Cmd'), pressValue=1, icon=qta.icon('fa5s.sync')) self.bt_rst.setObjectName('bt_rst') self.bt_rst.setStyleSheet( '#bt_rst{min-width:25px; max-width:25px; icon-size:20px;}') lay = QFormLayout() lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) lay.addRow('Restore Default', self.bt_rst) return lay def _specViewLayout(self): dev = self.device.substitute(dev='TuneProc') # Mode lbl_mode = QLabel('Mode', self) self.cb_mode = PyDMEnumComboBox(self, dev.substitute(propty='SpecMode-Sel')) self.lb_mode = PyDMLabel(self, dev.substitute(propty='SpecMode-Sts')) hbox_mode = QHBoxLayout() hbox_mode.addWidget(self.cb_mode) hbox_mode.addWidget(self.lb_mode) # Time window lbl_timewdw = QLabel('Time Window [ms]', self) self.le_timewdw = PyDMLineEdit(self, dev.substitute(propty='SpecTime-SP')) self.le_timewdw.precisionFromPV = True self.lb_timewdw = PyDMLabel(self, dev.substitute(propty='SpecTime-RB')) hbox_timewdw = QHBoxLayout() hbox_timewdw.addWidget(self.le_timewdw) hbox_timewdw.addWidget(self.lb_timewdw) lay = QFormLayout() lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) lay.addRow(lbl_mode, hbox_mode) lay.addRow(lbl_timewdw, hbox_timewdw) return lay def _roiLayout(self): # StartX lbl_roistartx = QLabel('Start X [MHz]', self) self.le_roistartx = PyDMLineEdit( self, self.device.substitute(propty='ROIOffsetX-SP')) self.le_roistartx.precisionFromPV = True self.lb_roistartx = PyDMLabel( self, self.device.substitute(propty='ROIOffsetX-RB')) hbox_roistartx = QHBoxLayout() hbox_roistartx.addWidget(self.le_roistartx) hbox_roistartx.addWidget(self.lb_roistartx) # Width lbl_roiwidth = QLabel('Width [MHz]', self) self.le_roiwidth = PyDMLineEdit( self, self.device.substitute(propty='ROIWidth-SP')) self.le_roiwidth.precisionFromPV = True self.lb_roiwidth = PyDMLabel( self, self.device.substitute(propty='ROIWidth-RB')) hbox_roiwidth = QHBoxLayout() hbox_roiwidth.addWidget(self.le_roiwidth) hbox_roiwidth.addWidget(self.lb_roiwidth) # StartY lbl_roistarty = QLabel('Start Y [ms]', self) self.le_roistarty = PyDMLineEdit( self, self.device.substitute(propty='ROIOffsetY-SP')) self.le_roistarty.precisionFromPV = True self.lb_roistarty = PyDMLabel( self, self.device.substitute(propty='ROIOffsetY-RB')) hbox_roistarty = QHBoxLayout() hbox_roistarty.addWidget(self.le_roistarty) hbox_roistarty.addWidget(self.lb_roistarty) # Height lbl_roiheight = QLabel('Height [ms]', self) self.le_roiheight = PyDMLineEdit( self, self.device.substitute(propty='ROIHeight-SP')) self.le_roiheight.precisionFromPV = True self.lb_roiheight = PyDMLabel( self, self.device.substitute(propty='ROIHeight-RB')) hbox_roiheight = QHBoxLayout() hbox_roiheight.addWidget(self.le_roiheight) hbox_roiheight.addWidget(self.lb_roiheight) # Auto adjust lbl_roiauto = QLabel('Auto Positioning', self) self.bt_roiauto = PyDMStateButton( self, self.device.substitute(propty='ROIAuto-Sel')) self.bt_roiauto.shape = 1 self.led_roiauto = SiriusLedState( self, self.device.substitute(propty='ROIAuto-Sts')) hbox_roiauto = QHBoxLayout() hbox_roiauto.addWidget(self.bt_roiauto) hbox_roiauto.addWidget(self.led_roiauto) lay = QFormLayout() lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) lay.addRow(lbl_roistartx, hbox_roistartx) lay.addRow(lbl_roiwidth, hbox_roiwidth) lay.addRow(lbl_roistarty, hbox_roistarty) lay.addRow(lbl_roiheight, hbox_roiheight) lay.addRow(lbl_roiauto, hbox_roiauto) return lay def _updateNrAcq(self, new_value): dev = self.device.substitute(dev='TuneProc') self.led_acqcnt.set_channels2values( {dev.substitute(propty='FrameCount-Mon'): new_value})
def get_orbit_widget(self, parent): """.""" orb_wid = QWidget(parent) orb_wid.setObjectName('grp') orb_wid.setStyleSheet('#grp{min-height: 11em; max-height: 15em;}') orb_wid.setLayout(QGridLayout()) conf = PyDMPushButton( orb_wid, pressValue=1, init_channel=self.devpref.substitute(propty='TrigAcqConfig-Cmd')) conf.setToolTip('Refresh Configurations') conf.setIcon(qta.icon('fa5s.sync')) conf.setObjectName('conf') conf.setStyleSheet( '#conf{min-width:25px; max-width:25px; icon-size:20px;}') sts = QPushButton('', orb_wid) sts.setIcon(qta.icon('fa5s.list-ul')) sts.setToolTip('Open Detailed Status View') sts.setObjectName('sts') sts.setStyleSheet( '#sts{min-width:25px; max-width:25px; icon-size:20px;}') icon = qta.icon( 'fa5s.hammer', color=_util.get_appropriate_color(self.acc)) window = create_window_from_widget( StatusWidget, title='Orbit Status', icon=icon) _util.connect_window( sts, window, orb_wid, device=self.device, prefix=self.prefix, acc=self.acc, is_orb=True) pdm_led = SiriusLedAlert( orb_wid, self.devpref.substitute(propty='OrbStatus-Mon')) lbl = QLabel('Status:', orb_wid) hbl = QHBoxLayout() hbl.setSpacing(9) hbl.addStretch() hbl.addWidget(lbl) hbl.addWidget(pdm_led) hbl.addWidget(sts) hbl.addWidget(conf) orb_wid.layout().addItem(hbl, 0, 0, 1, 2) lbl = QLabel('SOFB Mode', orb_wid) wid = self.create_pair_sel(orb_wid, 'SOFBMode') orb_wid.layout().addWidget(lbl, 1, 0, alignment=Qt.AlignVCenter) orb_wid.layout().addWidget(wid, 1, 1) lbl = QLabel('RefOrb:', orb_wid) combo = RefControl( self, self.device, self.ctrls, prefix=self.prefix, acc=self.acc) lbl2 = QLabel('', orb_wid) combo.configname.connect(lbl2.setText) vbl_ref = QVBoxLayout() vbl_ref.addWidget(combo) vbl_ref.addWidget(lbl2) orb_wid.layout().addWidget(lbl, 3, 0, alignment=Qt.AlignVCenter) orb_wid.layout().addLayout(vbl_ref, 3, 1) lbl = QLabel('Num. Pts.', orb_wid) stp = SiriusSpinbox( orb_wid, self.devpref.substitute(propty='SmoothNrPts-SP')) stp.showStepExponent = False rdb = PyDMLabel( orb_wid, self.devpref.substitute(propty='SmoothNrPts-RB')) rdb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) slsh = QLabel('/', orb_wid, alignment=Qt.AlignCenter) slsh.setStyleSheet('min-width:0.7em; max-width:0.7em;') cnt = PyDMLabel( orb_wid, self.devpref.substitute(propty='BufferCount-Mon')) cnt.setAlignment(Qt.AlignRight | Qt.AlignVCenter) cnt.setToolTip('Current Buffer Size') rst = PyDMPushButton( orb_wid, pressValue=1, init_channel=self.devpref.substitute(propty='SmoothReset-Cmd')) rst.setToolTip('Reset Buffer') rst.setIcon(qta.icon('mdi.delete-empty')) rst.setObjectName('rst') rst.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') hbl = QHBoxLayout() hbl.addWidget(stp) hbl.addWidget(cnt) hbl.addWidget(slsh) hbl.addWidget(rdb) hbl.addWidget(rst) orb_wid.layout().addWidget(lbl, 4, 0, alignment=Qt.AlignVCenter) orb_wid.layout().addItem(hbl, 4, 1) orb_wid.layout().setColumnStretch(1, 2) return orb_wid
class APUSummaryWidget(APUSummaryBase): """APU Summary Widget.""" def __init__(self, parent=None, prefix=_vaca_prefix, device=''): """Init.""" super().__init__(parent) self._prefix = prefix self._device = _PVName(device) self._beamline = IDSearch.conv_idname_2_beamline(self._device) self.dev_pref = self._device.substitute(prefix=prefix) self._setupUi() def _setupUi(self): self._lb_bl = QLabel('<h4>' + self._beamline + '</h4>', self, alignment=Qt.AlignCenter) self._pb_dev = QPushButton(self._device, self) connect_newprocess( self._pb_dev, ['sirius-hla-si-id-control.py', '-dev', self._device]) self._sb_phs = PyDMSpinbox(self, self.dev_pref.substitute(propty='Phase-SP')) self._sb_phs.showStepExponent = False self._lb_phs = PyDMLabel(self, self.dev_pref.substitute(propty='Phase-Mon')) self._sb_kx = PyDMSpinbox(self, self.dev_pref.substitute(propty='Kx-SP')) self._sb_kx.showStepExponent = False self._lb_kx = PyDMLabel(self, self.dev_pref.substitute(propty='Kx-Mon')) self._sb_phsspd = PyDMSpinbox( self, self.dev_pref.substitute(propty='PhaseSpeed-SP')) self._sb_phsspd.showStepExponent = False self._lb_phsspd = PyDMLabel( self, self.dev_pref.substitute(propty='PhaseSpeed-Mon')) self._pb_start = PyDMPushButton(self, label='', icon=qta.icon('fa5s.play')) self._pb_start.setToolTip( 'Start automatic motion towards previously entered setpoint.') self._pb_start.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_start.pressValue = 3 # Start self._pb_start.setObjectName('Start') self._pb_start.setStyleSheet( '#Start{min-width:30px; max-width:30px; icon-size:25px;}') self._pb_stop = PyDMPushButton(self, label='', icon=qta.icon('fa5s.stop')) self._pb_stop.setToolTip('Stop all motion, lock all brakes.') self._pb_stop.channel = self.dev_pref.substitute(propty='DevCtrl-Cmd') self._pb_stop.pressValue = 1 # Stop self._pb_stop.setObjectName('Stop') self._pb_stop.setStyleSheet( '#Stop{min-width:30px; max-width:30px; icon-size:25px;}') self._led_ismov = SiriusLedState( self, self.dev_pref.substitute(propty='Moving-Mon')) self._led_status = PyDMLedMultiChannel( self, { self.dev_pref.substitute(propty='Alarm-Mon'): 0, self.dev_pref.substitute(propty='IntlkInStop-Mon'): 0, self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon'): 0, self.dev_pref.substitute(propty='IntlkOutPwrEnbld-Mon'): 1, self.dev_pref.substitute(propty='IsOperational-Mon'): 1 }) self._sb_blenbl = PyDMStateButton( self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sel')) self._led_blenbl = SiriusLedState( self, self.dev_pref.substitute(propty='BeamLineCtrlEnbl-Sts')) self._led_blmon = SiriusLedState( self, self.dev_pref.substitute(propty='BeamLineCtrl-Mon')) self.widgets = { 'Beamline': ([ self._lb_bl, ], 'v'), 'Device': ([ self._pb_dev, ], 'v'), 'Alarms': ([ self._led_status, ], 'v'), 'Phase': ([self._sb_phs, self._lb_phs], 'v'), 'Kx': ([self._sb_kx, self._lb_kx], 'v'), 'Phase Speed': ([self._sb_phsspd, self._lb_phsspd], 'v'), 'Start': ([ self._pb_start, ], 'v'), 'Stop': ([ self._pb_stop, ], 'v'), 'Moving': ([ self._led_ismov, ], 'v'), 'BeamLine Enable': ([self._sb_blenbl, self._led_blenbl], 'h'), 'Beamline Control': ([ self._led_blmon, ], 'v'), } layout = QHBoxLayout(self) for name, size in self.widgets_widths: objname = name.replace(' ', '') group = self.widgets[name] items, ori = group widget = QWidget(self) lay = QVBoxLayout() if ori == 'v' else QHBoxLayout() lay.setContentsMargins(0, 0, 0, 0) lay.setAlignment(Qt.AlignCenter) lay.setSpacing(0) widget.setLayout(lay) for item in items: lay.addWidget(item) widget.setObjectName(objname) widget.setStyleSheet( '#' + objname + '{{min-width:{0}em; max-width:{0}em;}}'.format(str(size))) layout.addWidget(widget) def enable_beamline_control(self): """Enable beamline control.""" if self._sb_blenbl.isEnabled(): if not self._sb_blenbl.value: self._sb_blenbl.send_value() def disable_beamline_control(self): """Disable beamline control.""" if self._sb_blenbl.isEnabled(): if self._sb_blenbl.value: self._sb_blenbl.send_value()
class DCCTSettingsDetails(QWidget): """DCCT Settings Details Widget.""" def __init__(self, parent=None, prefix='', device=''): """Initialize object.""" super().__init__(parent) self.prefix = prefix self.device = _PVName(device) if 'BO' in device: self.setObjectName('BOApp') else: self.setObjectName('SIApp') self.dcct_prefix = device.substitute(prefix=self.prefix) self._db = get_dcct_database() self._setupUi() def _setupUi(self): self.gbox_reliablemeas = self._setupReliableMeasWidget() self.gbox_generalsettings = self._setupGeneralSettingsWidget() self.gbox_trigger = self._setupTriggerWidget() self.gbox_config = self._setupConfigurationWidget() self.gbox_normalmode = self._setupMeasSettingsWidget('Normal') self.gbox_fastmode = self._setupMeasSettingsWidget('Fast') lay_mode = QGridLayout() lay_mode.addWidget(self.gbox_normalmode, 0, 0) lay_mode.addWidget(self.gbox_fastmode, 0, 0) self.mode_channel = SiriusConnectionSignal( self.dcct_prefix.substitute(propty='MeasMode-Sel')) self.mode_channel.new_value_signal.connect(self._showMeasModeSettings) lay = QGridLayout() lay.addWidget( QLabel('<h3>' + self.device + ' Settings Details</h3>', self, alignment=Qt.AlignCenter), 0, 0, 1, 2) lay.addWidget(self.gbox_reliablemeas, 1, 0) lay.addWidget(self.gbox_generalsettings, 2, 0) lay.addWidget(self.gbox_config, 3, 0) lay.addWidget(self.gbox_trigger, 3, 1) lay.addLayout(lay_mode, 1, 1, 2, 1) lay.setVerticalSpacing(15) lay.setHorizontalSpacing(15) lay.setRowStretch(0, 1) lay.setRowStretch(1, 3) lay.setRowStretch(2, 7) lay.setRowStretch(3, 2) self.setLayout(lay) self.setStyleSheet(""" PyDMSpinbox, PyDMLabel{ min-width:6em; max-width:6em; qproperty-alignment: AlignCenter;} PyDMLedMultiChannel, PyDMStateButton, PyDMEnumComboBox{ min-width:6em; max-width:6em;}""") def _setupReliableMeasWidget(self): gbox_reliablemeas = QGroupBox('Measure Reliability Status', self) gbox_reliablemeas.setStyleSheet(""" .QLabel{min-height:1.29em; max-height:1.29em;} """) lay_reliablemeas = QGridLayout(gbox_reliablemeas) relmeas_count = self._db['ReliableMeasLabels-Cte']['count'] self.relmeas_labels = list() for idx in range(relmeas_count): led = SiriusLedAlert(parent=self, init_channel=self.dcct_prefix.substitute( propty='ReliableMeas-Mon'), bit=idx) lay_reliablemeas.addWidget(led, idx, 0) lbl = QLabel('', self) self.relmeas_labels.append(lbl) lay_reliablemeas.addWidget(lbl, idx, 1) lay_reliablemeas.setColumnStretch(0, 1) lay_reliablemeas.setColumnStretch(1, 10) self.reliablemeas_channel = _PV( self.dcct_prefix.substitute(propty='ReliableMeasLabels-Cte'), callback=self._updateReliableMeasLabels) return gbox_reliablemeas def _setupGeneralSettingsWidget(self): gbox_generalsettings = QGroupBox('General Measurement Settings', self) l_enbl = QLabel('Enable:', self) self.pydmstatebutton_Enbl = PyDMStateButton( self, self.dcct_prefix.substitute(propty='Enbl-Sel')) self.pydmstatebutton_Enbl.shape = 1 self.led_Enbl = SiriusLedState( self, self.dcct_prefix.substitute(propty='Enbl-Sts')) hlay_enbl = QHBoxLayout() hlay_enbl.addWidget(self.pydmstatebutton_Enbl) hlay_enbl.addWidget(self.led_Enbl) l_meastrig = QLabel('Trigger Source: ', self) self.pydmenumcombobox_MeasTrg = PyDMEnumComboBox( self, self.dcct_prefix.substitute(propty='MeasTrg-Sel')) self.pydmlabel_MeasTrg = PyDMLabel( self, self.dcct_prefix.substitute(propty='MeasTrg-Sts')) hlay_meastrig = QHBoxLayout() hlay_meastrig.addWidget(self.pydmenumcombobox_MeasTrg) hlay_meastrig.addWidget(self.pydmlabel_MeasTrg) l_trigmiss = QLabel('Trigger Is Missing?', self) self.led_TrgMiss = SiriusLedAlert( self, self.dcct_prefix.substitute(propty='TrgIsMissing-Mon')) hlay_trigmiss = QHBoxLayout() hlay_trigmiss.addWidget(self.led_TrgMiss) hlay_trigmiss.setAlignment(Qt.AlignLeft) l_range = QLabel('Range: ', self) self.pydmenumcombobox_Range = PyDMEnumComboBox( self, self.dcct_prefix.substitute(propty='Range-Sel')) self.pydmlabel_Range = PyDMLabel( self, self.dcct_prefix.substitute(propty='Range-Sts')) hlay_range = QHBoxLayout() hlay_range.addWidget(self.pydmenumcombobox_Range) hlay_range.addWidget(self.pydmlabel_Range) l_lowlimenbl = QLabel('Low Beam Current Detection: ', self) self.pydmstatebutton_LowLimEnbl = PyDMStateButton( self, self.dcct_prefix.substitute(propty='LowLimEnbl-Sel')) self.pydmstatebutton_LowLimEnbl.shape = 1 self.pydmlabel_LowLimEnbl = PyDMLabel( self, self.dcct_prefix.substitute(propty='LowLimEnbl-Sts')) hlay_lowlimenbl = QHBoxLayout() hlay_lowlimenbl.addWidget(self.pydmstatebutton_LowLimEnbl) hlay_lowlimenbl.addWidget(self.pydmlabel_LowLimEnbl) l_currthold = QLabel('Current Threshold [mA]: ', self) self.pydmspinbox_CurrThold = PyDMSpinbox( self, self.dcct_prefix.substitute(propty='CurrThold-SP')) self.pydmspinbox_CurrThold.showStepExponent = False self.pydmlabel_CurrThold = PyDMLabel( self, self.dcct_prefix.substitute(propty='CurrThold-RB')) hlay_currthold = QHBoxLayout() hlay_currthold.addWidget(self.pydmspinbox_CurrThold) hlay_currthold.addWidget(self.pydmlabel_CurrThold) l_hfreject = QLabel('High Frequency Rejection: ', self) self.pydmstatebutton_HFReject = PyDMStateButton( self, self.dcct_prefix.substitute(propty='HFReject-Sel')) self.pydmstatebutton_HFReject.shape = 1 self.pydmlabel_HFReject = PyDMLabel( self, self.dcct_prefix.substitute(propty='HFReject-Sts')) hlay_hfreject = QHBoxLayout() hlay_hfreject.addWidget(self.pydmstatebutton_HFReject) hlay_hfreject.addWidget(self.pydmlabel_HFReject) l_measmode = QLabel('Mode: ', self) self.pydmenumcombobox_MeasMode = PyDMEnumComboBox( self, self.dcct_prefix.substitute(propty='MeasMode-Sel')) self.pydmlabel_MeasMode = PyDMLabel( self, self.dcct_prefix.substitute(propty='MeasMode-Sts')) hlay_measmode = QHBoxLayout() hlay_measmode.addWidget(self.pydmenumcombobox_MeasMode) hlay_measmode.addWidget(self.pydmlabel_MeasMode) flay_generalsettings = QFormLayout() flay_generalsettings.setLabelAlignment(Qt.AlignRight) flay_generalsettings.setFormAlignment(Qt.AlignCenter) flay_generalsettings.addRow(l_enbl, hlay_enbl) flay_generalsettings.addRow(l_meastrig, hlay_meastrig) flay_generalsettings.addRow(l_trigmiss, hlay_trigmiss) flay_generalsettings.addRow(l_range, hlay_range) flay_generalsettings.addItem( QSpacerItem(1, 10, QSzPly.Ignored, QSzPly.Preferred)) flay_generalsettings.addRow(l_lowlimenbl, hlay_lowlimenbl) flay_generalsettings.addRow(l_currthold, hlay_currthold) flay_generalsettings.addRow(l_hfreject, hlay_hfreject) flay_generalsettings.addItem( QSpacerItem(1, 10, QSzPly.Ignored, QSzPly.Preferred)) flay_generalsettings.addRow(l_measmode, hlay_measmode) gbox_generalsettings.setLayout(flay_generalsettings) return gbox_generalsettings def _setupMeasSettingsWidget(self, mode): if mode == 'Normal': prefix = self.dcct_prefix visible = True elif mode == 'Fast': prefix = self.dcct_prefix.substitute(propty_name=mode) visible = False gbox_modesettings = QGroupBox(mode + ' Measurement Mode Settings', self) l_smpcnt = QLabel('Sample Count: ', self) spinbox_SampleCnt = PyDMSpinbox( self, prefix.substitute(propty=prefix.propty_name + 'SampleCnt-SP')) spinbox_SampleCnt.showStepExponent = False label_SampleCnt = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'SampleCnt-RB')) hlay_smpcnt = QHBoxLayout() hlay_smpcnt.addWidget(spinbox_SampleCnt) hlay_smpcnt.addWidget(label_SampleCnt) l_measperiod = QLabel('Period [s]: ', self) spinbox_MeasPeriod = PyDMSpinbox( self, prefix.substitute(propty=prefix.propty_name + 'MeasPeriod-SP')) spinbox_MeasPeriod.showStepExponent = False label_MeasPeriod = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'MeasPeriod-RB')) hlay_measperiod = QHBoxLayout() hlay_measperiod.addWidget(spinbox_MeasPeriod) hlay_measperiod.addWidget(label_MeasPeriod) l_measupdateperiod = QLabel('Measured Period [s]: ', self) label_MeasUpdatePeriod = PyDMLabel( self, self.dcct_prefix.substitute(propty='MeasUpdatePeriod-Mon')) l_imped = QLabel('Impedance: ', self) enumcombobox_Imped = PyDMEnumComboBox( self, prefix.substitute(propty=prefix.propty_name + 'Imped-Sel')) label_Imped = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'Imped-Sts')) hlay_imped = QHBoxLayout() hlay_imped.addWidget(enumcombobox_Imped) hlay_imped.addWidget(label_Imped) l_offset = QLabel('Relative Offset Enable: ', self) statebutton_RelEnbl = PyDMStateButton( self, prefix.substitute(propty=prefix.propty_name + 'RelEnbl-Sel')) statebutton_RelEnbl.shape = 1 statebutton_RelEnbl.setStyleSheet('min-width:6em; max-width:6em;') label_RelEnbl = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'RelEnbl-Sts')) hlay_offset = QHBoxLayout() hlay_offset.addWidget(statebutton_RelEnbl) hlay_offset.addWidget(label_RelEnbl) l_rellvl = QLabel('Relative Offset Level [V]: ', self) spinbox_RelLvl = PyDMSpinbox( self, prefix.substitute(propty=prefix.propty_name + 'RelLvl-SP')) spinbox_RelLvl.showStepExponent = False label_RelLvl = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'RelLvl-RB')) label_RelLvl.precisionFromPV = False label_RelLvl.precision = 9 pushbutton_RelAcq = PyDMPushButton( parent=self, label='Acquire Offset', pressValue=1, init_channel=prefix.substitute(propty=prefix.propty_name + 'RelAcq-Cmd')) pushbutton_RelAcq.setAutoDefault(False) pushbutton_RelAcq.setDefault(False) hlay_rellvl = QHBoxLayout() hlay_rellvl.addWidget(spinbox_RelLvl) hlay_rellvl.addWidget(label_RelLvl) hlay_rellvl.addWidget(pushbutton_RelAcq) flay_modesettings = QFormLayout() flay_modesettings.setLabelAlignment(Qt.AlignRight) flay_modesettings.setFormAlignment(Qt.AlignHCenter) flay_modesettings.addRow(l_smpcnt, hlay_smpcnt) flay_modesettings.addRow(l_measperiod, hlay_measperiod) flay_modesettings.addRow(l_measupdateperiod, label_MeasUpdatePeriod) flay_modesettings.addRow(l_imped, hlay_imped) flay_modesettings.addRow(l_offset, hlay_offset) flay_modesettings.addRow(l_rellvl, hlay_rellvl) if mode == 'Normal': l_linesync = QLabel('Line Synchronization: ', self) statebutton_LineSync = PyDMStateButton( self, prefix.substitute(propty=prefix.propty_name + 'LineSync-Sel')) statebutton_LineSync.shape = 1 statebutton_LineSync.setStyleSheet('min-width:6em; max-width:6em;') label_LineSync = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'LineSync-Sts')) hlay_linesync = QHBoxLayout() hlay_linesync.addWidget(statebutton_LineSync) hlay_linesync.addWidget(label_LineSync) label_avg = QLabel('<h4>Average Filter</h4>', self) l_avgenbl = QLabel('Enable: ', self) statebutton_AvgFilterEnbl = PyDMStateButton( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterEnbl-Sel')) statebutton_AvgFilterEnbl.shape = 1 label_AvgFilterEnbl = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterEnbl-Sts')) hlay_avgenbl = QHBoxLayout() hlay_avgenbl.addWidget(statebutton_AvgFilterEnbl) hlay_avgenbl.addWidget(label_AvgFilterEnbl) l_avgcnt = QLabel('Samples: ', self) spinbox_AvgFilterCount = PyDMSpinbox( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterCnt-SP')) spinbox_AvgFilterCount.showStepExponent = False label_AvgFilterCount = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterCnt-RB')) hlay_avgcnt = QHBoxLayout() hlay_avgcnt.addWidget(spinbox_AvgFilterCount) hlay_avgcnt.addWidget(label_AvgFilterCount) l_avgtyp = QLabel('Type: ', self) enumcombobox_AvgFilterTyp = PyDMEnumComboBox( self, self.dcct_prefix.substitute(propty='AvgFilterTyp-Sel')) label_AvgFilterTyp = PyDMLabel( self, self.dcct_prefix.substitute(propty='AvgFilterTyp-Sts')) hlay_avgtyp = QHBoxLayout() hlay_avgtyp.addWidget(enumcombobox_AvgFilterTyp) hlay_avgtyp.addWidget(label_AvgFilterTyp) l_avgwin = QLabel('Noise window size [%]: ', self) spinbox_AvgFilterWind = PyDMSpinbox( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterWind-SP')) spinbox_AvgFilterWind.showStepExponent = False label_AvgFilterWind = PyDMLabel( self, prefix.substitute(propty=prefix.propty_name + 'AvgFilterWind-RB')) hlay_avgwin = QHBoxLayout() hlay_avgwin.addWidget(spinbox_AvgFilterWind) hlay_avgwin.addWidget(label_AvgFilterWind) flay_modesettings.addRow(l_linesync, hlay_linesync) flay_modesettings.addRow(QLabel('')) flay_modesettings.addRow(label_avg) flay_modesettings.addRow(l_avgenbl, hlay_avgenbl) flay_modesettings.addRow(l_avgcnt, hlay_avgcnt) flay_modesettings.addRow(l_avgtyp, hlay_avgtyp) flay_modesettings.addRow(l_avgwin, hlay_avgwin) gbox_modesettings.setLayout(flay_modesettings) gbox_modesettings.setVisible(visible) gbox_modesettings.setStyleSheet(""" PyDMSpinbox, PyDMLabel{ min-width:6em; max-width:6em; qproperty-alignment: AlignCenter;} PyDMLedMultiChannel, PyDMStateButton, PyDMEnumComboBox{ min-width:6em; max-width:6em;}""") return gbox_modesettings def _setupConfigurationWidget(self): statebutton_Test = PyDMStateButton( self, self.dcct_prefix.substitute(propty='Test-Sel')) statebutton_Test.shape = 1 statebutton_Test.setStyleSheet('min-width:6em; max-width:6em;') label_Test = PyDMLabel(self, self.dcct_prefix.substitute(propty='Test-Sts')) hlay_test = QHBoxLayout() hlay_test.addWidget(statebutton_Test) hlay_test.addWidget(label_Test) self.bt_dl = PyDMPushButton( parent=self, pressValue=1, icon=qta.icon('fa5s.sync'), init_channel=self.dcct_prefix.substitute(propty='Download-Cmd')) self.bt_dl.setObjectName('bt_dl') self.bt_dl.setStyleSheet( '#bt_dl{min-width:25px; max-width:25px; icon-size:20px;}') gbox_test = QGroupBox('Configurations') lay = QFormLayout(gbox_test) lay.setLabelAlignment(Qt.AlignRight) lay.setFormAlignment(Qt.AlignCenter) lay.addRow('Enable test current: ', hlay_test) lay.addRow('Download Configurations: ', self.bt_dl) return gbox_test def _setupTriggerWidget(self): gbox_trigger = QGroupBox('Trigger', self) hbl = QHBoxLayout(gbox_trigger) hbl.addWidget( HLTriggerSimple(gbox_trigger, device=self.device.substitute(dis='TI'), prefix=self.prefix)) return gbox_trigger def _updateReliableMeasLabels(self, pvname, value, **kwargs): if value: for idx, lbl in enumerate(self.relmeas_labels): lbl.setText(value[idx]) def _showMeasModeSettings(self, value): if value == _DCCTc.MeasModeSel.Normal: self.gbox_normalmode.setVisible(True) self.gbox_fastmode.setVisible(False) elif value == _DCCTc.MeasModeSel.Fast: self.gbox_normalmode.setVisible(False) self.gbox_fastmode.setVisible(True)
def get_measurement_widget(self, parent): """.""" meas_wid = QWidget(parent) meas_lay = QVBoxLayout(meas_wid) strt = PyDMPushButton( meas_wid, init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"), pressValue=ConstTLines.MeasRespMatCmd.Start) strt.setEnabled(True) strt.setToolTip('Start Measurement') strt.setIcon(qta.icon('fa5s.play')) strt.setObjectName('strt') strt.setStyleSheet( '#strt{min-width:25px; max-width:25px; icon-size:20px;}') stop = PyDMPushButton( meas_wid, init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"), pressValue=ConstTLines.MeasRespMatCmd.Stop) stop.setEnabled(True) stop.setToolTip('Stop Measurement') stop.setIcon(qta.icon('fa5s.stop')) stop.setObjectName('stop') stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') rst = PyDMPushButton( meas_wid, init_channel=self.devpref.substitute(propty="MeasRespMat-Cmd"), pressValue=ConstTLines.MeasRespMatCmd.Reset) rst.setEnabled(True) rst.setToolTip('Reset Measurement Status') rst.setIcon(qta.icon('fa5s.sync')) rst.setObjectName('conf') rst.setStyleSheet( '#conf{min-width:25px; max-width:25px; icon-size:20px;}') lbl = PyDMLabel( meas_wid, self.devpref.substitute(propty='MeasRespMat-Mon')) lbl.setAlignment(Qt.AlignCenter) hbl = QHBoxLayout() hbl.setSpacing(8) meas_lay.addItem(hbl) hbl.addWidget(strt) hbl.addWidget(stop) hbl.addWidget(rst) hbl.addStretch() hbl.addWidget(lbl) fml = QFormLayout() meas_lay.addSpacing(20) meas_lay.addItem(fml) lbl = QLabel('CH [urad]', meas_wid) wid = self.create_pair(meas_wid, 'MeasRespMatKickCH') fml.addRow(lbl, wid) lbl = QLabel('CV [urad]', meas_wid) wid = self.create_pair(meas_wid, 'MeasRespMatKickCV') fml.addRow(lbl, wid) if self.acc in {'SI', 'BO'}: lbl = QLabel('RF [Hz]', meas_wid) wid = self.create_pair(meas_wid, 'MeasRespMatKickRF') fml.addRow(lbl, wid) lbl = QLabel('Wait [s]', meas_wid) lbl.setToolTip('Time to wait between kicks') wid = self.create_pair(meas_wid, 'MeasRespMatWait') fml.addRow(lbl, wid) return meas_wid
class InjBOControlWindow(BaseWindow): """Booster Injection Control HLA.""" def __init__(self, parent=None, prefix=_VACA_PREFIX): super().__init__(parent, prefix) self.setWindowTitle('Booster Injection Control Window') self.setObjectName('BOApp') self.SVG_FILE = 'TB-BO.svg' self._scrns = ('BO-01D:DI-Scrn-1', 'BO-01D:DI-Scrn-2', 'BO-02U:DI-Scrn') self._setupUi() self.lattice_wid.setStyleSheet( 'min-width:60em; min-height:14em; max-height:14em;') def _setupMenu(self): PosAng = QAction("PosAng CH-Sept", self) util.connect_newprocess(PosAng, 'sirius-hla-tb-ap-posang.py', parent=self) self.menu.addAction(PosAng) def _setupDiagWidget(self): return def _setupScrnsCorrsWidget(self): # screens lay_screens = QVBoxLayout() lay_screens.setContentsMargins(0, 0, 0, 0) header_screens = self._create_headerline( (('', 0), ('Screen', 6.5), ('Cam', 3.5), ('Type-Sel', 5), ('Type-Sts', 5), ('', 0))) header_screens.setObjectName('header_screens') header_screens.setStyleSheet( '#header_screens {border-bottom: 2px solid gray;}') header_screens.layout().setContentsMargins(0, 9, 0, 9) header_screens.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Maximum) lay_screens.addWidget(header_screens) for idx, scrn_prefix in enumerate(self._scrns): scrn_prefix = SiriusPVName(scrn_prefix) w = self._create_scrn_summwidget(scrn_prefix, idx) w.layout().setContentsMargins(9, 9, 9, 9) lay_screens.addWidget(w) # correctors w_corr = QWidget() w_corr.setObjectName('w_corr') w_corr.setStyleSheet('#w_corr {border-left: 2px solid gray;}') lay_corr = QGridLayout(w_corr) lay_corr.setContentsMargins(0, 0, 0, 0) lay_corr.setVerticalSpacing(25) lay_corr.setHorizontalSpacing(15) lay_corr.setAlignment(Qt.AlignTop) header_corrs = self._create_headerline( (('', 0), ('', 1.29), ('', 5), ('Kick-SP', 5), ('Kick-Mon', 5), ('', 0), ('', 1.29), ('', 5), ('Kick-SP', 5), ('Kick-Mon', 5), ('', 0))) header_corrs.setObjectName('header_corrs') header_corrs.setStyleSheet( '#header_corrs {border-bottom: 2px solid gray;}') header_corrs.layout().setContentsMargins(0, 9, 0, 9) header_corrs.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Maximum) lay_corr.addWidget(header_corrs, 0, 0, 1, 2) for corr, row, col in (('TB-04:PS-CH-1', 1, 0), ('TB-04:PS-CH-2', 2, 0), ('TB-04:PS-CV-1', 1, 1), ('TB-04:PS-CV-2', 2, 1), ('TB-04:PU-InjSept', 3, 0), ('BO-01D:PU-InjKckr', 3, 1)): corr = SiriusPVName(corr) w = self._create_corr_summwidget(corr) w.layout().setContentsMargins(9, 9, 9, 9) lay_corr.addWidget(w, row, col) # posang posang_prefix = SiriusPVName('TB-Glob:AP-PosAng').substitute( prefix=self.prefix) w_posang = QWidget() w_posang.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Maximum) w_posang.setObjectName('w_posang') w_posang.setStyleSheet('#w_posang {border-top: 2px solid gray;}') lay_posang = QGridLayout(w_posang) lay_posang.setVerticalSpacing(9) lay_posang.setHorizontalSpacing(15) header_posang = self._create_headerline( (('', 0), ('', 1.29), ('Position and Angle Correction', 30), ('', 0))) header_posang.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Maximum) lay_posang.addWidget(header_posang, 0, 0, 1, 2) self.pb_update_ref = PyDMPushButton( label='Update Reference', parent=self, init_channel=posang_prefix.substitute(propty='SetNewRefKick-Cmd'), pressValue=1) self.pb_update_ref.setStyleSheet('min-height: 2em;') lay_posang.addWidget(self.pb_update_ref, 1, 0, 1, 2) for col, title, axis in ((0, 'Horizontal', 'X'), (1, 'Vertical', 'Y')): lb_pos = QLabel('<h4>Δ' + axis.lower() + '</h4>', self, alignment=Qt.AlignRight) lb_pos.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Maximum) pos_sp = PyDMSpinbox( self, posang_prefix.substitute(propty='DeltaPos' + axis + '-SP')) pos_sp.setObjectName('pos_sp_' + axis.lower()) pos_sp.showStepExponent = False pos_rb = PyDMLabel( self, posang_prefix.substitute(propty='DeltaPos' + axis + '-RB')) pos_rb.setObjectName('pos_rb_' + axis.lower()) lb_ang = QLabel('<h4>Δ' + axis.lower() + '\'</h4>', self, alignment=Qt.AlignRight) lb_ang.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Maximum) ang_sp = PyDMSpinbox( self, posang_prefix.substitute(propty='DeltaAng' + axis + '-SP')) ang_sp.setObjectName('ang_sp_' + axis.lower()) ang_sp.showStepExponent = False ang_rb = PyDMLabel( self, posang_prefix.substitute(propty='DeltaAng' + axis + '-RB')) ang_rb.setObjectName('ang_rb_' + axis.lower()) gbox_posang = QGroupBox(title, self) axlay = QGridLayout(gbox_posang) axlay.addWidget(lb_pos, 0, 0) axlay.addWidget(pos_sp, 0, 1) axlay.addWidget(pos_rb, 0, 2) axlay.addWidget(lb_ang, 1, 0) axlay.addWidget(ang_sp, 1, 1) axlay.addWidget(ang_rb, 1, 2) lay_posang.addWidget(gbox_posang, 2, col) self.pb_posang_settings = QPushButton('Settings', self) util.connect_window(self.pb_posang_settings, CorrParamsDetailWindow, parent=self, tl='TB', prefix=self.prefix) lay_posang.addWidget(self.pb_posang_settings, 3, 0, 1, 2, alignment=Qt.AlignRight) lay_posangref = QGridLayout() lay_posangref.setHorizontalSpacing(9) lay_posangref.setVerticalSpacing(9) lay_posangref.addWidget( QLabel('<h4>Reference Kicks</h4>', self, alignment=Qt.AlignCenter), 0, 0, 1, 7) for corr in ('CH1', 'CH2', 'CV1', 'CV2'): lb_corr = PyDMLabel(self, posang_prefix.substitute(propty=corr + '-Cte')) lb_corr.setStyleSheet('font-weight:bold;') lb_refkick = PyDMLabel( self, posang_prefix.substitute(propty='RefKick' + corr + '-Mon')) lb_refkick.showUnits = True col = 1 if 'CH' in corr else 4 row = 0 if '1' in corr else 1 lay_posangref.addWidget(lb_corr, row + 1, col) lay_posangref.addWidget(lb_refkick, row + 1, col + 1) lay_posangref.setColumnStretch(0, 1) lay_posangref.setColumnStretch(1, 3) lay_posangref.setColumnStretch(2, 3) lay_posangref.setColumnStretch(3, 1) lay_posangref.setColumnStretch(4, 3) lay_posangref.setColumnStretch(5, 3) lay_posangref.setColumnStretch(6, 1) lay_posang.addLayout(lay_posangref, 4, 0, 1, 2) lay_corr.addWidget(w_posang, 4, 0, 1, 2) lay_corr.setRowStretch(0, 1) lay_corr.setRowStretch(1, 2) lay_corr.setRowStretch(2, 2) lay_corr.setRowStretch(3, 2) lay_corr.setRowStretch(4, 10) lay = QHBoxLayout() lay.setContentsMargins(0, 0, 0, 0) lay.setSpacing(0) lay.addLayout(lay_screens) lay.addWidget(w_corr) self.corr_wid.setLayout(lay)
class PUDetailWidget(QWidget): """Detailed widget for controlling a pulsed magnet.""" def __init__(self, devname, parent=None): """Receive a parent and a pulsed mangnet name.""" super().__init__(parent) self._devname = _PVName(devname) self._section = self._devname.sec self._prefix = _VACA_PREFIX self._pdev = self._devname.substitute(prefix=self._prefix) self.setObjectName(self._section + 'App') self.setWindowIcon( qta.icon('mdi.current-ac', color=util.get_appropriate_color(self._section))) self._create_pvs() self._setup_ui() self.setStyleSheet(""" #pulses_box, #pwrstate_box { max-width: 8em; } """) self.setFocusPolicy(Qt.StrongFocus) def _create_pvs(self): """Create variables with pvs that'll be used.""" self._voltage_sp_pv = self._pdev.substitute(propty='Voltage-SP') self._voltage_rb_pv = self._pdev.substitute(propty='Voltage-RB') self._voltage_mon_pv = self._pdev.substitute(propty='Voltage-Mon') self._kick_sp_pv = self._pdev.substitute(propty='Kick-SP') self._kick_rb_pv = self._pdev.substitute(propty='Kick-RB') self._kick_mon_pv = self._pdev.substitute(propty='Kick-Mon') self._pwrstate_sel_pv = self._pdev.substitute(propty='PwrState-Sel') self._pwrstate_sts_pv = self._pdev.substitute(propty='PwrState-Sts') self._enablepulses_sel_pv = self._pdev.substitute(propty='Pulse-Sel') self._enablepulses_sts_pv = self._pdev.substitute(propty='Pulse-Sts') self._reset_cmd_pv = self._pdev.substitute(propty='Reset-Cmd') self._intlk1_mon_pv = self._pdev.substitute(propty='Intlk1-Mon') self._intlk2_mon_pv = self._pdev.substitute(propty='Intlk2-Mon') self._intlk3_mon_pv = self._pdev.substitute(propty='Intlk3-Mon') self._intlk4_mon_pv = self._pdev.substitute(propty='Intlk4-Mon') self._intlk5_mon_pv = self._pdev.substitute(propty='Intlk5-Mon') self._intlk6_mon_pv = self._pdev.substitute(propty='Intlk6-Mon') self._intlk7_mon_pv = self._pdev.substitute(propty='Intlk7-Mon') self._intlk1_lbcte_pv = self._pdev.substitute(propty='Intlk1Label-Cte') self._intlk2_lbcte_pv = self._pdev.substitute(propty='Intlk2Label-Cte') self._intlk3_lbcte_pv = self._pdev.substitute(propty='Intlk3Label-Cte') self._intlk4_lbcte_pv = self._pdev.substitute(propty='Intlk4Label-Cte') self._intlk5_lbcte_pv = self._pdev.substitute(propty='Intlk5Label-Cte') self._intlk6_lbcte_pv = self._pdev.substitute(propty='Intlk6Label-Cte') self._intlk7_lbcte_pv = self._pdev.substitute(propty='Intlk7Label-Cte') if 'Sept' not in self._devname: self._intlk8_mon_pv = self._pdev.substitute(propty='Intlk8-Mon') self._intlk8_lbcte_pv = \ self._pdev.substitute(propty='Intlk8Label-Cte') self._ctrlmode_pv = self._pdev.substitute(propty='CtrlMode-Mon') self._trigname = self._devname.substitute(dis='TI') def _setup_ui(self): self.header_label = QLabel("<h1>" + self._devname + "</h1>") self.header_label.setObjectName("header_label") interlock_box = QGroupBox(parent=self, title="Interlock") interlock_box.setObjectName("interlock_box") interlock_box.setLayout(self._interlock_layout()) pwrstate_box = QGroupBox(parent=self, title="Power") pwrstate_box.setObjectName("pwrstate_box") pwrstate_box.setLayout(self._pwrstate_layout()) pulses_box = QGroupBox(parent=self, title="Pulses") pulses_box.setObjectName("pulses_box") pulses_box.setLayout(self._pulses_layout()) voltage_box = QGroupBox(parent=self, title="Voltage") voltage_box.setObjectName("voltage_box") voltage_box.setLayout(self._voltage_layout()) kick_box = QGroupBox(parent=self, title="Kick") kick_box.setObjectName("kick_box") kick_box.setLayout(self._kick_layout()) timing_box = QGroupBox(parent=self, title='Trigger') timing_box.setObjectName('timing_box') hbl = QHBoxLayout(timing_box) hbl.addWidget(HLTriggerSimple(timing_box, self._trigname, self._prefix)) self.layout = QGridLayout(self) self.layout.addWidget(self.header_label, 0, 0, 1, 3) self.layout.addWidget(interlock_box, 1, 0, 3, 1) vbl1 = QVBoxLayout() vbl1.addWidget(pwrstate_box) vbl1.addWidget(pulses_box) self.layout.addLayout(vbl1, 1, 1, 2, 1) vbl2 = QVBoxLayout() vbl2.addWidget(voltage_box) vbl2.addWidget(kick_box) self.layout.addLayout(vbl2, 1, 2, 2, 1) self.layout.addWidget(timing_box, 3, 1, 1, 3) self.layout.addLayout(self._ctrlmode_layout(), 4, 1, 1, 3) def _interlock_layout(self): interlock_layout = QGridLayout() intlk_cnt = 8 if 'Sept' not in self._devname else 7 for i in range(intlk_cnt): label = PyDMLabel( self, getattr(self, '_intlk' + str(i + 1) + '_lbcte_pv')) led = PyDMLed(self, getattr(self, '_intlk' + str(i + 1) + '_mon_pv')) led.onColor = led.LightGreen led.offColor = led.Red interlock_layout.addWidget(led, i, 0) interlock_layout.addWidget(label, i, 1) self.reset_bt = PyDMPushButton(parent=self, init_channel=self._reset_cmd_pv, 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;}') interlock_layout.addWidget(self.reset_bt, i + 1, 0, 1, 2, alignment=Qt.AlignHCenter) return interlock_layout def _pwrstate_layout(self): pwrstate_layout = QHBoxLayout() self.state_button = PyDMStateButton(parent=self, init_channel=self._pwrstate_sel_pv) self.state_led = SiriusLedState(self, self._pwrstate_sts_pv) pwrstate_layout.addWidget(self.state_button) pwrstate_layout.addWidget(self.state_led) return pwrstate_layout def _pulses_layout(self): pulses_layout = QHBoxLayout() self.pulses_state_button = PyDMStateButton( parent=self, init_channel=self._enablepulses_sel_pv) self.pulses_state_led = SiriusLedState( parent=self, init_channel=self._enablepulses_sts_pv) pulses_layout.addWidget(self.pulses_state_button) pulses_layout.addWidget(self.pulses_state_led) return pulses_layout def _voltage_layout(self): voltage_layout = QVBoxLayout() self.voltage_sp_widget = PyDMSpinboxScrollbar(self, self._voltage_sp_pv) self.voltage_rb_label = PyDMLabel(self, self._voltage_rb_pv) self.voltage_rb_label.showUnits = True self.voltage_rb_label.precisionFromPV = True self.voltage_mon_label = PyDMLabel(self, self._voltage_mon_pv) self.voltage_mon_label.showUnits = True self.voltage_mon_label.precisionFromPV = True voltage_layout = QFormLayout() voltage_layout.setLabelAlignment(Qt.AlignRight) voltage_layout.setFormAlignment(Qt.AlignHCenter) voltage_layout.addRow('SP:', self.voltage_sp_widget) voltage_layout.addRow('RB:', self.voltage_rb_label) voltage_layout.addRow('Mon:', self.voltage_mon_label) return voltage_layout def _kick_layout(self): self.kick_sp_widget = PyDMSpinboxScrollbar(self, self._kick_sp_pv) self.kick_rb_label = PyDMLabel(self, self._kick_rb_pv) self.kick_rb_label.showUnits = True self.kick_rb_label.precisionFromPV = True self.kick_mon_label = PyDMLabel(self, self._kick_mon_pv) self.kick_mon_label.showUnits = True self.kick_mon_label.precisionFromPV = True kick_layout = QFormLayout() kick_layout.setLabelAlignment(Qt.AlignRight) kick_layout.setFormAlignment(Qt.AlignHCenter) kick_layout.addRow('SP:', self.kick_sp_widget) kick_layout.addRow('RB:', self.kick_rb_label) kick_layout.addRow('Mon:', self.kick_mon_label) return kick_layout def _ctrlmode_layout(self): ctrlmode_layout = QHBoxLayout() self.ctrlmode_led = SiriusLedAlert(parent=self, init_channel=self._ctrlmode_pv) self.ctrlmode_label = PyDMLabel(parent=self, init_channel=self._ctrlmode_pv) ctrlmode_layout.addStretch() ctrlmode_layout.addWidget(self.ctrlmode_led) ctrlmode_layout.addWidget(self.ctrlmode_label) return ctrlmode_layout
class BaslerCamSettings(QTabWidget): def __init__(self, parent=None, device='', prefix=''): super().__init__(parent) self.prefix = prefix self.device = SiriusPVName(device).substitute(prefix=prefix) self.cam_prefix = self.device.substitute(prefix=prefix) self.setObjectName(self.device.sec + 'App') self._setupUi() def _setupUi(self): self.addTab(self._infoWidget(), 'Gen. Info') self.addTab(self._statusWidget(), 'Status') self.addTab(self._acquisitionWidget(), 'Acquisition') self.addTab(self._imgIntesityAndBGWidget(), 'Intensity and BG') self.addTab(self._ROIWidget(), 'ROI') self.setCurrentIndex(2) self.setStyleSheet('#' + self.device.sec + 'App{min-width: 31em; max-width: 31em;}') def _infoWidget(self): label_DevID = QLabel('Device ID:', self) hbox_DevID = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='DeviceID', propty_type='cte') hbox_DevID.setAlignment(Qt.AlignLeft) label_DevVers = QLabel('Device Version:', self) hbox_DevVers = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='DeviceVersion', propty_type='cte') hbox_DevVers.setAlignment(Qt.AlignLeft) label_DevModelName = QLabel('Device Model Name:', self) hbox_DevModelName = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='DeviceModelName', propty_type='cte') hbox_DevModelName.setAlignment(Qt.AlignLeft) label_DevVendorName = QLabel('Device Vendor Name:', self) hbox_DevVendorName = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='DeviceVendorName', propty_type='cte') hbox_DevVendorName.setAlignment(Qt.AlignLeft) label_DevFirmVers = QLabel('Firmware Version:', self) hbox_DevFirmVers = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='DeviceFirmwareVersion', propty_type='cte') hbox_DevFirmVers.setAlignment(Qt.AlignLeft) label_SensorHeight = QLabel('Sensor Height [pixels]:', self) hbox_SensorHeight = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='SensorHeight', propty_type='cte') hbox_SensorHeight.setAlignment(Qt.AlignLeft) label_SensorWidth = QLabel('Sensor Width [pixels]:', self) hbox_SensorWidth = create_propty_layout(parent=self, prefix=self.cam_prefix, width=15, propty='SensorWidth', propty_type='cte') hbox_SensorWidth.setAlignment(Qt.AlignLeft) wid = QWidget() flay = QFormLayout(wid) flay.setLabelAlignment(Qt.AlignRight) flay.setFormAlignment(Qt.AlignHCenter) flay.addRow(label_DevID, hbox_DevID) flay.addRow(label_DevVers, hbox_DevVers) flay.addRow(label_DevModelName, hbox_DevModelName) flay.addRow(label_DevVendorName, hbox_DevVendorName) flay.addRow(label_DevFirmVers, hbox_DevFirmVers) flay.addRow(label_SensorHeight, hbox_SensorHeight) flay.addRow(label_SensorWidth, hbox_SensorWidth) return wid def _statusWidget(self): label_Conn = QLabel('Connection:', self) hbox_Conn = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Connection', propty_type='mon') label_Temp = QLabel('Temperature State:', self) self.lb_Temp = PyDMLabel(self, self.cam_prefix.substitute(propty='Temp-Mon')) self.lb_Temp.setStyleSheet('min-width:7.1em; max-width:7.1em;') self.lb_Temp.setAlignment(Qt.AlignCenter) self.led_TempState = SiriusLedAlert( self, self.cam_prefix.substitute(propty='TempState-Mon')) self.led_TempState.setStyleSheet('min-width:1.29em; max-width:1.29em;') self.lb_TempState = PyDMLabel( self, self.cam_prefix.substitute(propty='TempState-Mon')) self.lb_TempState.setStyleSheet('min-width:2.5em; max-width:2.5em;') hbox_Temp = QHBoxLayout() hbox_Temp.addWidget(self.lb_Temp) hbox_Temp.addWidget(self.led_TempState) hbox_Temp.addWidget(self.lb_TempState) label_LastErr = QLabel('Last Error:', self) hbox_LastErr = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='LastErr', propty_type='mon', cmd={ 'label': 'Clear Last Error', 'pressValue': 1, 'name': 'ClearLastErr' }) label_Reset = QLabel('Reset Camera:', self) self.pb_dtl = PyDMPushButton( label='', icon=qta.icon('fa5s.sync'), parent=self, pressValue=1, init_channel=self.cam_prefix.substitute(propty='Rst-Cmd')) self.pb_dtl.setObjectName('reset') self.pb_dtl.setStyleSheet( "#reset{min-width:25px; max-width:25px; icon-size:20px;}") wid = QWidget() flay = QFormLayout(wid) flay.setLabelAlignment(Qt.AlignRight) flay.setFormAlignment(Qt.AlignHCenter) flay.addRow(label_Conn, hbox_Conn) flay.addRow(label_Temp, hbox_Temp) flay.addRow(label_LastErr, hbox_LastErr) flay.addRow(label_Reset, self.pb_dtl) return wid def _acquisitionWidget(self): label_CamEnbl = QLabel('Acquire Enable Status:', self) hbox_CamEnbl = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Enbl', propty_type='enbldisabl') label_FrameCnt = QLabel('Frame Count:', self) hbox_FrameCnt = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='FrameCnt', propty_type='mon') label_AcqMode = QLabel('Acquire Mode:', self) hbox_AcqMode = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AcqMode', propty_type='enum') label_AcqPeriod = QLabel('Acquire Period [s]:', self) hbox_AcqPeriod = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AcqPeriod', propty_type='sprb') label_AcqPeriodLowLim = QLabel('Acquire Period Low Limit [s]:', self) hbox_AcqPeriodLowLim = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AcqPeriodLowLim', propty_type='sprb') label_ExpMode = QLabel('Exposure Mode:', self) hbox_ExpMode = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='ExposureMode', propty_type='enum') label_ExpTime = QLabel('Exposure Time [us]:', self) hbox_ExpTime = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='ExposureTime', propty_type='sprb') label_Gain = QLabel('Gain [dB]:', self) hbox_Gain = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Gain', propty_type='sprb', cmd={ 'label': '', 'pressValue': 1, 'width': '25', 'height': '25', 'icon': qta.icon('mdi.auto-fix'), 'icon-size': '20', 'toolTip': 'Auto Gain', 'name': 'AutoGain' }) label_TransformType = QLabel('Transform Type:', self) hbox_TransformType = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='TransformType', propty_type='enum') label_BlackLevel = QLabel('Black Level [gray va]:', self) hbox_BlackLevel = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='BlackLevel', propty_type='sprb') label_DebouncerPeriod = QLabel('Debouncer Period [us]:', self) hbox_DebouncerPeriod = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='DebouncerPeriod', propty_type='sprb') self.pb_advanced = QPushButton('Advanced', self) my_window = create_window_from_widget( BaslerCamAcqAdvSettings, is_main=False, title='Basler Camera Advanced Acquisition Settings') util.connect_window(self.pb_advanced, my_window, parent=self, device=self.device, prefix=self.prefix) hbox_adv = QHBoxLayout() hbox_adv.addWidget(self.pb_advanced, alignment=Qt.AlignRight) wid = QWidget() flay = QFormLayout(wid) flay.setLabelAlignment(Qt.AlignRight) flay.setFormAlignment(Qt.AlignHCenter) flay.addRow(label_CamEnbl, hbox_CamEnbl) flay.addRow(label_FrameCnt, hbox_FrameCnt) flay.addRow(label_AcqMode, hbox_AcqMode) flay.addRow(label_AcqPeriod, hbox_AcqPeriod) flay.addRow(label_AcqPeriodLowLim, hbox_AcqPeriodLowLim) flay.addRow(label_ExpMode, hbox_ExpMode) flay.addRow(label_ExpTime, hbox_ExpTime) flay.addRow(label_Gain, hbox_Gain) flay.addRow(label_BlackLevel, hbox_BlackLevel) flay.addRow(label_DebouncerPeriod, hbox_DebouncerPeriod) flay.addRow(label_TransformType, hbox_TransformType) flay.addRow(hbox_adv) return wid def _imgIntesityAndBGWidget(self): label_EnblAdjust = QLabel('Enable Scale and Offset Adjust:', self) hbox_EnblAdjust = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='EnblOffsetScale', propty_type='enbldisabl') label_AutoAdjust = QLabel('Automatic Intensity Adjust:', self) hbox_AutoAdjust = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AutoOffsetScale', cmd={ 'label': 'Auto Adjust', 'pressValue': 1, 'name': 'AutoOffsetScale' }) label_PixelScale = QLabel('Pixel Scale:', self) hbox_PixelScale = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='PixelScale', propty_type='sprb', use_linedit=True) label_PixelOffset = QLabel('Pixel Offset:', self) hbox_PixelOffset = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='PixelOffset', propty_type='sprb', use_linedit=True) label_EnblLowClip = QLabel('Enable Low Cliping:', self) hbox_EnblLowClip = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='EnblLowClip', propty_type='enbldisabl') label_LowClip = QLabel('Minimum Intensity for Low Cliping:', self) hbox_LowClip = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='LowClip', propty_type='sprb', use_linedit=True) label_EnblHighClip = QLabel('Enable High Cliping:', self) hbox_EnblHighClip = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='EnblHighClip', propty_type='enbldisabl') label_HighClip = QLabel('Maximum Intensity for High Cliping:', self) hbox_HighClip = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='HighClip', propty_type='sprb', use_linedit=True) label_EnblBG = QLabel('Enable BG Subtraction:', self) hbox_EnblBG = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='EnblBGSubtraction', propty_type='enbldisabl') label_SaveBG = QLabel('Save BG:', self) hbox_SaveBG = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='SaveBG', cmd={ 'label': 'Save', 'pressValue': 1, 'name': 'SaveBG' }) label_ValidBG = QLabel('Is valid BG?', self) hbox_ValidBG = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='ValidBG', propty_type='mon') wid = QWidget() flay = QFormLayout(wid) flay.setLabelAlignment(Qt.AlignRight) flay.setFormAlignment(Qt.AlignHCenter) flay.addRow(label_EnblAdjust, hbox_EnblAdjust) flay.addRow(label_AutoAdjust, hbox_AutoAdjust) flay.addRow(label_PixelScale, hbox_PixelScale) flay.addRow(label_PixelOffset, hbox_PixelOffset) flay.addRow(label_EnblLowClip, hbox_EnblLowClip) flay.addRow(label_LowClip, hbox_LowClip) flay.addRow(label_EnblHighClip, hbox_EnblHighClip) flay.addRow(label_HighClip, hbox_HighClip) flay.addRow(label_EnblBG, hbox_EnblBG) flay.addRow(label_SaveBG, hbox_SaveBG) flay.addRow(label_ValidBG, hbox_ValidBG) return wid def _ROIWidget(self): label_MaxWidth = QLabel('Maximum Width [pixels]:', self) self.PyDMLabel_MaxWidth = PyDMLabel( self, self.cam_prefix.substitute(propty='SensorWidth-Cte')) self.PyDMLabel_MaxWidth.setStyleSheet( """max-width:7.10em; max-height:1.29em;""") label_MaxHeight = QLabel('Maximum Height [pixels]:', self) self.PyDMLabel_MaxHeight = PyDMLabel( self, self.cam_prefix.substitute(propty='SensorHeight-Cte')) self.PyDMLabel_MaxHeight.setStyleSheet( """max-width:7.10em; max-height:1.29em;""") label_ROIWidth = QLabel('Width [pixels]:', self) hbox_ROIWidth = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIWidth', propty_type='sprb') label_ROIHeight = QLabel('Heigth [pixels]:', self) hbox_ROIHeight = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIHeight', propty_type='sprb') label_ROIOffsetX = QLabel('Offset X [pixels]:', self) hbox_ROIOffsetX = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIOffsetX', propty_type='sprb') label_ROIOffsetY = QLabel('Offset Y [pixels]:', self) hbox_ROIOffsetY = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIOffsetY', propty_type='sprb') label_AutoCenterX = QLabel('Auto Center X:', self) hbox_AutoCenterX = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIAutoCenterX', propty_type='offon') label_AutoCenterY = QLabel('Auto Center Y:', self) hbox_AutoCenterY = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AOIAutoCenterY', propty_type='offon') wid = QWidget() flay = QFormLayout(wid) flay.setLabelAlignment(Qt.AlignRight) flay.setFormAlignment(Qt.AlignHCenter) flay.addRow(label_MaxWidth, self.PyDMLabel_MaxWidth) flay.addRow(label_MaxHeight, self.PyDMLabel_MaxHeight) flay.addRow(label_ROIWidth, hbox_ROIWidth) flay.addRow(label_ROIHeight, hbox_ROIHeight) flay.addRow(label_ROIOffsetX, hbox_ROIOffsetX) flay.addRow(label_ROIOffsetY, hbox_ROIOffsetY) flay.addRow(label_AutoCenterX, hbox_AutoCenterX) flay.addRow(label_AutoCenterY, hbox_AutoCenterY) return wid
class CurrLTWindow(SiriusMainWindow): """Current and Lifetime Window.""" def __init__(self, parent=None, prefix=_VACA_PREFIX): """Initialize some widgets.""" super(CurrLTWindow, self).__init__(parent) self.prefix = prefix self.device = _PVName('SI-Glob:AP-CurrInfo') self.devname = self.device.substitute(prefix=self.prefix) self.setObjectName('SIApp') self.setWindowTitle('SI Current Info: Current and Lifetime') self._setupUi() self.setFocus(True) self.setFocusPolicy(Qt.StrongFocus) def _setupUi(self): self.label_title = QLabel('SI Current and Lifetime') self.label_title.setStyleSheet(""" font-size:1.2em; font-weight:bold; 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));""") self.label_title.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.settings = QWidget() vlay_sett = QVBoxLayout(self.settings) vlay_sett.setContentsMargins(0, 0, 0, 0) vlay_sett.addWidget(self._setupCurrentSettingsWidget()) vlay_sett.addWidget(self._setupLifetimeSettigsWidget()) vlay_sett.addWidget(self._setupGraphSettingsWidget()) self.pb_showsett = QPushButton('<', self) self.pb_showsett.setObjectName('showsett') self.pb_showsett.setToolTip('Hide settings') self.pb_showsett.setStyleSheet( '#showsett{min-width:0.7em;max-width:0.7em;}') self.pb_showsett.released.connect(self._handle_settings_vis) self.pb_showeff = QPushButton('v', self) self.pb_showeff.setObjectName('showeff') self.pb_showeff.setToolTip('Show efficiency graph') self.pb_showeff.setStyleSheet( '#showeff{min-width:0.7em;max-width:0.7em;}') self.pb_showeff.released.connect(self._handle_efficiency_vis) hbox_visi = QHBoxLayout() hbox_visi.addStretch() hbox_visi.addWidget(self.pb_showsett) hbox_visi.addWidget(self.pb_showeff) self.eff_graph = EffMonitor(self, self.prefix, self.device.sec) self.eff_graph.setVisible(False) cw = QWidget() self.setCentralWidget(cw) lay = QGridLayout(cw) lay.addWidget(self.label_title, 0, 0, 1, 2) lay.addLayout(self._setupGraphPanelLayout(), 1, 0) lay.addWidget(self.settings, 1, 1) lay.addLayout(hbox_visi, 2, 0, 1, 2, alignment=Qt.AlignRight) lay.addWidget(self.eff_graph, 3, 0, 1, 2) lay.setColumnStretch(0, 6) lay.setColumnStretch(1, 1) def _setupGraphPanelLayout(self): # Main Panel # # Labels self._ld_current = QLabel('Current', self, alignment=Qt.AlignCenter) self._ld_current.setStyleSheet("font-weight:bold; max-height1.5em;") self._lb_current = PyDMLabel( self, self.devname.substitute(propty='Current-Mon')) self._lb_current.setStyleSheet("font-size:40px;") self._lb_current.precision = 0 self._lb_current.showUnits = True self._ld_lifetime = QLabel('Lifetime', self) self._ld_lifetime.setStyleSheet("font-weight:bold; max-height1.5em;") self._ld_lifetime.setAlignment(Qt.AlignCenter) self._lb_lifetime = QLabel('0:00:00', self) self._lb_lifetime.channel = self.devname.substitute( propty='Lifetime-Mon') self._lb_lifetime.setStyleSheet("font-size:40px;") self.lifetime_dcct_pv = SiriusConnectionSignal( self.devname.substitute(propty='Lifetime-Mon')) self.lifetime_dcct_pv.new_value_signal[float].connect( self._format_lifetime_label) self.lifetime_bpm_pv = SiriusConnectionSignal( self.devname.substitute(propty='LifetimeBPM-Mon')) self.lifetime_bpm_pv.new_value_signal[float].connect( self._format_lifetime_label) # # Graph self.graph = SiriusTimePlot(self, background='w') self.graph.plotItem.getAxis('left').setLabel('Current [mA]', color='blue') self.graph.plotItem.getAxis('right').setLabel('Lifetime [h]', color='red') self.graph.showLegend = False self.graph.showXGrid = True self.graph.showYGrid = True self.graph.autoRangeY = True self.graph.setObjectName('graph') self.graph.setStyleSheet('#graph{min-width:40em;min-height:32em;}') self.graph.bufferSize = 60 * 60 * 10 self.graph.timeSpan = 30 * 60 t_end = Time.now() t_init = t_end - 30 * 60 t_end_iso = t_end.get_iso8601() t_init_iso = t_init.get_iso8601() pvname = self.devname.substitute(propty='Current-Mon') self.graph.addYChannel(y_channel=pvname, axis='left', name='Current', color='blue', lineWidth=1) self._curve_current = self.graph.curveAtIndex(0) self.graph.fill_curve_with_archdata(self._curve_current, pvname, t_init=t_init_iso, t_end=t_end_iso) pvname = _PVName('SI-01M1:DI-BPM:Sum-Mon').substitute( prefix=self.prefix) self.graph.addYChannel(y_channel=pvname, axis='left', name='Current', color='blue', lineWidth=1) self._curve_bpmsum = self.graph.curveAtIndex(1) self.graph.fill_curve_with_archdata(self._curve_bpmsum, pvname, t_init=t_init_iso, t_end=t_end_iso) self.graph.addYChannel(y_channel='FAKE:Lifetime', axis='right', name='Lifetime', color='red', lineWidth=1) self._curve_lifetimedcct = self.graph.curveAtIndex(2) self.graph.fill_curve_with_archdata( self._curve_lifetimedcct, self.devname.substitute(propty='Lifetime-Mon'), t_init=t_init_iso, t_end=t_end_iso, factor=3600) self.graph.addYChannel(y_channel='FAKE:LifetimeBPM', axis='right', name='Lifetime', color='red', lineWidth=1) self._curve_lifetimebpm = self.graph.curveAtIndex(3) self.graph.fill_curve_with_archdata( self._curve_lifetimebpm, self.devname.substitute(propty='LifetimeBPM-Mon'), t_init=t_init_iso, t_end=t_end_iso, factor=3600) self.lifetime_dcct_pv.new_value_signal[float].connect( self._update_graph) self.lifetime_bpm_pv.new_value_signal[float].connect( self._update_graph) self._flag_need_dcctx = True self._flag_need_dccty = True self._flag_need_bpmx = True self._flag_need_bpmy = True self.dcct_wavx = _np.array([]) self.dcct_wavy = _np.array([]) self.bpm_wavx = _np.array([]) self.bpm_wavy = _np.array([]) self.dcct_buff_y_pv = SiriusConnectionSignal( self.devname.substitute(propty='BufferValue-Mon')) self.dcct_buff_x_pv = SiriusConnectionSignal( self.devname.substitute(propty='BufferTimestamp-Mon')) self.bpm_buff_y_pv = SiriusConnectionSignal( self.devname.substitute(propty='BufferValueBPM-Mon')) self.bpm_buff_x_pv = SiriusConnectionSignal( self.devname.substitute(propty='BufferTimestampBPM-Mon')) self.dcct_buff_y_pv.new_value_signal[_np.ndarray].connect( self._update_waveforms) self.dcct_buff_x_pv.new_value_signal[_np.ndarray].connect( self._update_waveforms) self.bpm_buff_y_pv.new_value_signal[_np.ndarray].connect( self._update_waveforms) self.bpm_buff_x_pv.new_value_signal[_np.ndarray].connect( self._update_waveforms) self.graph.addYChannel(y_channel='FAKE:DCCTBuffer', axis='left', name='DCCTBuffer', color='blue', lineStyle=Qt.NoPen, symbolSize=10, symbol='o') self._curve_dcct_buff = self.graph.curveAtIndex(4) self.graph.addYChannel(y_channel='FAKE:BPMBuffer', axis='left', name='BPMBuffer', color='blue', lineStyle=Qt.NoPen, symbolSize=10, symbol='o') self._curve_bpm_buff = self.graph.curveAtIndex(5) self._curve_bpmsum.setVisible(False) self._curve_lifetimebpm.setVisible(False) self._curve_bpm_buff.setVisible(False) lay = QGridLayout() lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 0) lay.addWidget(self._ld_current, 0, 1) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 2) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 3) lay.addWidget(self._ld_lifetime, 0, 4) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 5) lay.addWidget(self._lb_current, 1, 1) lay.addWidget(self._lb_lifetime, 1, 4) lay.addWidget(self.graph, 2, 0, 1, 6) return lay def _setupCurrentSettingsWidget(self): self._ld_storedebeam = QLabel('Stored EBeam?', self) self._ld_storedebeam.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._led_storedebeam = SiriusLedState( self, self.devname.substitute(propty='StoredEBeam-Mon')) self._ld_dcctfault = QLabel('DCCT Fault Check:', self) self._ld_dcctfault.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._bt_dcctfault = PyDMStateButton( self, self.devname.substitute(propty='DCCTFltCheck-Sel')) self._bt_dcctfault.shape = PyDMStateButton.Rounded self._led_dcctfault = SiriusLedState( self, self.devname.substitute(propty='DCCTFltCheck-Sts')) self._ld_seldcct = QLabel('Select DCCT:', self) self._ld_seldcct.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._cb_seldcct = PyDMEnumComboBox( self, self.devname.substitute(propty='DCCT-Sel')) self._lb_seldcct = PyDMLabel( self, self.devname.substitute(propty='DCCT-Sts')) self._lb_seldcct.setAlignment(Qt.AlignCenter) self._lb_seldcct.precision = 0 self._led_dcct13c4 = SiriusLedAlert( self, _PVName('SI-13C4:DI-DCCT:ReliableMeas-Mon').substitute( prefix=self.prefix)) self._lb_dcct13c4 = QLabel('DCCT 13C4', self) self._lb_dcct13c4.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._pb_13c4_detail = QPushButton(self) self._pb_13c4_detail.setObjectName('DCCT13C4_dtl') self._pb_13c4_detail.setStyleSheet( "#DCCT13C4_dtl{min-width:25px; max-width:25px; icon-size:20px;}") self._pb_13c4_detail.setIcon(qta.icon('fa5s.ellipsis-h')) connect_window(self._pb_13c4_detail, DCCTMain, self, prefix=self.prefix, device='SI-13C4:DI-DCCT') hlay_dcct13c4 = QHBoxLayout() hlay_dcct13c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) hlay_dcct13c4.addWidget(self._led_dcct13c4) hlay_dcct13c4.addWidget(self._lb_dcct13c4) hlay_dcct13c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) hlay_dcct13c4.addWidget(self._pb_13c4_detail) hlay_dcct13c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) self._led_dcct14c4 = SiriusLedAlert( self, _PVName('SI-14C4:DI-DCCT:ReliableMeas-Mon').substitute( prefix=self.prefix)) self._lb_dcct14c4 = QLabel('DCCT 14C4', self) self._lb_dcct14c4.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._pb_14c4_detail = QPushButton(self) self._pb_14c4_detail.setObjectName('DCCT14C4_dtl') self._pb_14c4_detail.setStyleSheet( "#DCCT14C4_dtl{min-width:25px; max-width:25px; icon-size:20px;}") self._pb_14c4_detail.setIcon(qta.icon('fa5s.ellipsis-h')) connect_window(self._pb_14c4_detail, DCCTMain, self, prefix=self.prefix, device='SI-14C4:DI-DCCT') hlay_dcct14c4 = QHBoxLayout() hlay_dcct14c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) hlay_dcct14c4.addWidget(self._led_dcct14c4) hlay_dcct14c4.addWidget(self._lb_dcct14c4) hlay_dcct14c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) hlay_dcct14c4.addWidget(self._pb_14c4_detail) hlay_dcct14c4.addItem( QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum)) gbox = QGroupBox('Current Settings and Status', self) lay = QGridLayout(gbox) lay.addWidget(self._ld_storedebeam, 0, 0) lay.addWidget(self._led_storedebeam, 0, 1) lay.addWidget(self._ld_dcctfault, 1, 0) lay.addWidget(self._bt_dcctfault, 1, 1) lay.addWidget(self._led_dcctfault, 1, 2) lay.addWidget(self._ld_seldcct, 2, 0) lay.addWidget(self._cb_seldcct, 2, 1) lay.addWidget(self._lb_seldcct, 2, 2) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 3, 0) lay.addLayout(hlay_dcct13c4, 4, 0, 1, 3) lay.addLayout(hlay_dcct14c4, 5, 0, 1, 3) lay.setColumnStretch(0, 2) lay.setColumnStretch(1, 1) lay.setColumnStretch(2, 1) return gbox def _setupLifetimeSettigsWidget(self): self._ld_calcmode = QLabel('Calc Mode:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._cb_calcmode = PyDMEnumComboBox( self, self.devname.substitute(propty='LtFitMode-Sel')) self._lb_calcmode = SiriusLabel( self, self.devname.substitute(propty='LtFitMode-Sts')) self._lb_calcmode.setAlignment(Qt.AlignCenter) self._ld_curroffset = QLabel('Current\nOffset [mA]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._sb_curroffset = SiriusSpinbox( self, self.devname.substitute(propty='CurrOffset-SP')) self._sb_curroffset.showStepExponent = False self._lb_curroffset = PyDMLabel( self, self.devname.substitute(propty='CurrOffset-RB')) self._lb_curroffset.setAlignment(Qt.AlignCenter) self._ld_buffer = QLabel('<h4>Buffer</h4>', self, alignment=Qt.AlignCenter) self._pb_plussett = QPushButton('+', self) self._pb_plussett.setStyleSheet('max-height:0.9em; max-width:0.9em;') self._pb_plussett.released.connect(self._handle_intvl_sett_visibility) self._ld_maxintvl = QLabel('Max. Sampling\nInterval [s]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._ld_maxintvl.setToolTip( "Timestamp settings use 2 parameters to define the\n" "timestamp interval.\n\n" "If 'Max. Sampling Interval' == -1:\n" " use 'Last Time' and 'First Time' parameters.\n" "Else:\n" " use 'Max. Sampling Interval' and last timestamp set.\n\n" "Default: use 'Max. Sampling Interval' and 'Last Time'.") hlay_maxintvl = QHBoxLayout() hlay_maxintvl.addWidget(self._pb_plussett) hlay_maxintvl.addWidget(self._ld_maxintvl) self._sb_maxintvl = PyDMSpinbox( self, self.devname.substitute(propty='MaxSplIntvl-SP')) self._sb_maxintvl.precisionFromPV = True self._sb_maxintvl.showStepExponent = False self._lb_maxintvl = PyDMLabel( self, self.devname.substitute(propty='MaxSplIntvl-RB')) self._lb_maxintvl.setAlignment(Qt.AlignCenter) self._lb_maxintvl.precisionFromPV = True self._ld_firstsmpl = QLabel('First Time [s]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._ld_firstsmpl.setVisible(False) self._le_firstsmpl = PyDMLineEdit( self, self.devname.substitute(propty='FrstSplTime-SP')) self._le_firstsmpl.setVisible(False) self._lb_firstsmpl_dcct = PyDMLabel( self, self.devname.substitute(propty='FrstSplTime-RB')) self._lb_firstsmpl_dcct.setVisible(False) self._lb_firstsmpl_bpm = PyDMLabel( self, self.devname.substitute(propty='FrstSplTimeBPM-RB')) self._lb_firstsmpl_bpm.setVisible(False) self._pb_firstnow = QPushButton(qta.icon('mdi.clock-end'), '', self) self._pb_firstnow.setObjectName('firstnow') self._pb_firstnow.setStyleSheet( '#firstnow{min-width:25px; max-width:25px; icon-size:20px;}') self._pb_firstnow.setToolTip('Click to set current timestamp') self._pb_firstnow.released.connect(self._update_first_time) self._pb_firstnow.setVisible(False) hbox_sp_first = QHBoxLayout() hbox_sp_first.addWidget(self._le_firstsmpl) hbox_sp_first.addWidget(self._pb_firstnow) self._ld_lastsmpl = QLabel('Last Time [s]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._ld_lastsmpl.setToolTip( "If 'Last Time' == -1, use current timestamp.") self._ld_lastsmpl.setVisible(False) self._le_lastsmpl = PyDMLineEdit( self, self.devname.substitute(propty='LastSplTime-SP')) self._le_lastsmpl.setVisible(False) self._lb_lastsmpl_dcct = PyDMLabel( self, self.devname.substitute(propty='LastSplTime-RB')) self._lb_lastsmpl_dcct.setVisible(False) self._lb_lastsmpl_bpm = PyDMLabel( self, self.devname.substitute(propty='LastSplTimeBPM-RB')) self._lb_lastsmpl_bpm.setVisible(False) self._pb_lastnow = QPushButton(qta.icon('mdi.clock-end'), '', self) self._pb_lastnow.setObjectName('lastnow') self._pb_lastnow.setStyleSheet( '#lastnow{min-width:25px; max-width:25px; icon-size:20px;}') self._pb_lastnow.setToolTip('Click to set current timestamp') self._pb_lastnow.released.connect(self._update_last_time) self._pb_lastnow.setVisible(False) hbox_sp_last = QHBoxLayout() hbox_sp_last.addWidget(self._le_lastsmpl) hbox_sp_last.addWidget(self._pb_lastnow) self._ld_smplintvl = QLabel('Samples\nInterval [s]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._lb_smplintvl_dcct = PyDMLabel( self, self.devname.substitute(propty='SplIntvl-Mon')) self._lb_smplintvl_bpm = PyDMLabel( self, self.devname.substitute(propty='SplIntvlBPM-Mon')) self._lb_smplintvl_bpm.setVisible(False) self._ld_intvlbtwspl = QLabel('Interval Between\nSamples [s]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._sb_intvlbtwspl = PyDMSpinbox( self, self.devname.substitute(propty='MinIntvlBtwSpl-SP')) self._sb_intvlbtwspl.precisionFromPV = True self._sb_intvlbtwspl.showStepExponent = False self._lb_intvlbtwspl = PyDMLabel( self, self.devname.substitute(propty='MinIntvlBtwSpl-RB')) self._lb_intvlbtwspl.setAlignment(Qt.AlignCenter) self._lb_intvlbtwspl.precisionFromPV = True self._ld_bufautoreset = QLabel('Auto Reset:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._cb_bufautoreset = PyDMEnumComboBox( self, self.devname.substitute(propty='BuffAutoRst-Sel')) self._lb_bufautoreset = PyDMLabel( self, self.devname.substitute(propty='BuffAutoRst-Sts')) self._ld_bufdcurr = QLabel('Auto Reset Delta\nCurrent [mA]:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._sb_bufdcurr = PyDMSpinbox( self, self.devname.substitute(propty='BuffAutoRstDCurr-SP')) self._sb_bufdcurr.showStepExponent = False self._lb_bufdcurr = PyDMLabel( self, self.devname.substitute(propty='BuffAutoRstDCurr-RB')) self._ld_bufsize = QLabel('Size:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._lb_bufsize_dcct = PyDMLabel( self, self.devname.substitute(propty='BuffSize-Mon')) self._lb_bufsize_dcct.setAlignment(Qt.AlignCenter) self._lb_bufsize_bpm = PyDMLabel( self, self.devname.substitute(propty='BuffSizeBPM-Mon')) self._lb_bufsize_bpm.setAlignment(Qt.AlignCenter) self._lb_bufsize_bpm.setVisible(False) self._pb_bufreset = PyDMPushButton( self, label='', icon=qta.icon('mdi.delete-empty'), pressValue=1, init_channel=self.devname.substitute(propty='BuffRst-Cmd')) self._pb_bufreset.setObjectName('reset') self._pb_bufreset.setStyleSheet( "#reset{min-width:25px; max-width:25px; icon-size:20px;}") self._ld_sep = QLabel('/', self) self._lb_bufsizetot_dcct = PyDMLabel( self, self.devname.substitute(propty='BuffSizeTot-Mon')) self._lb_bufsizetot_dcct.setStyleSheet("min-width:5em; max-width:5em;") self._lb_bufsizetot_dcct.setAlignment(Qt.AlignCenter) self._lb_bufsizetot_dcct.precision = 0 self._lb_bufsizetot_bpm = PyDMLabel( self, self.devname.substitute(propty='BuffSizeTotBPM-Mon')) self._lb_bufsizetot_bpm.setStyleSheet("min-width:5em; max-width:5em;") self._lb_bufsizetot_bpm.setAlignment(Qt.AlignCenter) self._lb_bufsizetot_bpm.precision = 0 self._lb_bufsizetot_bpm.setVisible(False) glay_bufsize = QGridLayout() glay_bufsize.addWidget(self._lb_bufsize_dcct, 0, 0) glay_bufsize.addWidget(self._lb_bufsize_bpm, 0, 0) glay_bufsize.addWidget(self._pb_bufreset, 0, 1) glay_bufsize.addWidget(self._ld_sep, 0, 2) glay_bufsize.addWidget(self._lb_bufsizetot_dcct, 0, 3) glay_bufsize.addWidget(self._lb_bufsizetot_bpm, 0, 3) glay_bufsize.setColumnStretch(0, 5) glay_bufsize.setColumnStretch(1, 2) glay_bufsize.setColumnStretch(2, 1) glay_bufsize.setColumnStretch(3, 5) gbox = QGroupBox('Lifetime Settings', self) lay = QGridLayout(gbox) lay.addWidget(self._ld_calcmode, 0, 0) lay.addWidget(self._cb_calcmode, 0, 1) lay.addWidget(self._lb_calcmode, 0, 2) lay.addWidget(self._ld_curroffset, 1, 0) lay.addWidget(self._sb_curroffset, 1, 1) lay.addWidget(self._lb_curroffset, 1, 2) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 2, 1) lay.addWidget(self._ld_buffer, 3, 0, 1, 3) lay.addLayout(hlay_maxintvl, 4, 0) lay.addWidget(self._sb_maxintvl, 4, 1) lay.addWidget(self._lb_maxintvl, 4, 2) lay.addWidget(self._ld_firstsmpl, 5, 0) lay.addLayout(hbox_sp_first, 5, 1, 1, 2) lay.addWidget(self._lb_firstsmpl_dcct, 6, 1, 1, 2) lay.addWidget(self._lb_firstsmpl_bpm, 6, 1, 1, 2) lay.addWidget(self._ld_lastsmpl, 7, 0) lay.addLayout(hbox_sp_last, 7, 1, 1, 2) lay.addWidget(self._lb_lastsmpl_dcct, 8, 1, 1, 2) lay.addWidget(self._lb_lastsmpl_bpm, 8, 1, 1, 2) lay.addWidget(self._ld_smplintvl, 9, 0) lay.addWidget(self._lb_smplintvl_dcct, 9, 1) lay.addWidget(self._lb_smplintvl_bpm, 9, 1) lay.addWidget(self._ld_intvlbtwspl, 10, 0) lay.addWidget(self._sb_intvlbtwspl, 10, 1) lay.addWidget(self._lb_intvlbtwspl, 10, 2) lay.addItem(QSpacerItem(20, 5, QSzPlcy.Minimum, QSzPlcy.Fixed), 11, 1) lay.addWidget(self._ld_bufautoreset, 12, 0) lay.addWidget(self._cb_bufautoreset, 12, 1) lay.addWidget(self._lb_bufautoreset, 12, 2) lay.addWidget(self._ld_bufdcurr, 13, 0) lay.addWidget(self._sb_bufdcurr, 13, 1) lay.addWidget(self._lb_bufdcurr, 13, 2) lay.addItem(QSpacerItem(20, 5, QSzPlcy.Minimum, QSzPlcy.Fixed), 14, 1) lay.addWidget(self._ld_bufsize, 15, 0) lay.addLayout(glay_bufsize, 15, 1, 1, 2) return gbox def _setupGraphSettingsWidget(self): self._ld_ltfrom = QLabel('Show lifetime from:', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._cb_ltfrom = QComboBox() self._cb_ltfrom.addItem('DCCT') self._cb_ltfrom.addItem('BPM') self._cb_ltfrom.currentTextChanged.connect( self._handle_lifetime_type_sel) self._ld_showsmpl = QLabel('Show samples: ', self, alignment=Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self._cb_showsmpl = QCheckBox(self) self._cb_showsmpl.setChecked(True) self._cb_showsmpl.stateChanged.connect(self._handle_samples_visibility) gbox = QGroupBox('Graphs Settings', self) lay = QGridLayout(gbox) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 0) lay.addWidget(self._ld_ltfrom, 0, 1) lay.addWidget(self._cb_ltfrom, 0, 2) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Expanding, QSzPlcy.Minimum), 0, 3) lay.addItem(QSpacerItem(1, 1, QSzPlcy.Minimum, QSzPlcy.Expanding), 1, 1, 1, 2) lay.addWidget(self._ld_showsmpl, 2, 1) lay.addWidget(self._cb_showsmpl, 2, 2) return gbox # ---------- auxiliar methods ---------- def _format_lifetime_label(self, value): """Format lifetime label.""" if self._lb_lifetime.channel != self.sender().address: return lt = 0 if _np.isnan(value) else value H = int(lt // 3600) m = int((lt % 3600) // 60) s = int((lt % 3600) % 60) lt_str = '{:d}:{:02d}:{:02d}'.format(H, m, s) self._lb_lifetime.setText(lt_str) @Slot(str) def _handle_lifetime_type_sel(self, text): """Handle lifetime type selection.""" cond = bool(text == 'DCCT') self._curve_current.setVisible(cond) self._curve_lifetimedcct.setVisible(cond) self._curve_dcct_buff.setVisible(cond) self._lb_bufsizetot_dcct.setVisible(cond) self._lb_bufsize_dcct.setVisible(cond) self._lb_smplintvl_dcct.setVisible(cond) self._curve_bpmsum.setVisible(not cond) self._curve_lifetimebpm.setVisible(not cond) self._curve_bpm_buff.setVisible(not cond) self._lb_bufsizetot_bpm.setVisible(not cond) self._lb_bufsize_bpm.setVisible(not cond) self._lb_smplintvl_bpm.setVisible(not cond) visi = self._pb_plussett.text() == '-' self._lb_firstsmpl_dcct.setVisible(cond and visi) self._lb_lastsmpl_dcct.setVisible(cond and visi) self._lb_firstsmpl_bpm.setVisible(not cond and visi) self._lb_lastsmpl_bpm.setVisible(not cond and visi) if not cond: self.graph.plotItem.getAxis('left').setLabel('01M1 BPM Sum', color='blue') self._lb_lifetime.channel = \ self.devname.substitute(propty='LifetimeBPM-Mon') else: self.graph.plotItem.getAxis('left').setLabel('Current [mA]', color='blue') self._lb_lifetime.channel = \ self.devname.substitute(propty='Lifetime-Mon') def _handle_intvl_sett_visibility(self): """Handle sampling interval settings.""" text = self.sender().text() visi = text == '+' self._ld_firstsmpl.setVisible(visi) self._le_firstsmpl.setVisible(visi) self._pb_firstnow.setVisible(visi) self._ld_lastsmpl.setVisible(visi) self._le_lastsmpl.setVisible(visi) self._pb_lastnow.setVisible(visi) showingdcct = self._cb_ltfrom.currentText() == 'DCCT' self._lb_firstsmpl_dcct.setVisible(showingdcct and visi) self._lb_lastsmpl_dcct.setVisible(showingdcct and visi) self._lb_firstsmpl_bpm.setVisible(not showingdcct and visi) self._lb_lastsmpl_bpm.setVisible(not showingdcct and visi) self.sender().setText('+' if text == '-' else '-') @Slot(int) def _handle_samples_visibility(self, state): """Handle samples visibility.""" showingdcct = self._cb_ltfrom.currentText() == 'DCCT' self._curve_dcct_buff.setVisible(showingdcct and state) self._curve_bpm_buff.setVisible(not showingdcct and state) def _handle_settings_vis(self): vis = self.settings.isVisible() text = '>' if vis else '<' ttip = 'Show' if vis else 'Hide' self.pb_showsett.setText(text) self.pb_showsett.setToolTip(ttip + ' settings') self.settings.setVisible(not vis) self.sender().parent().adjustSize() self.centralWidget().adjustSize() self.adjustSize() def _handle_efficiency_vis(self): vis = self.eff_graph.isVisible() text = 'v' if vis else '^' ttip = 'Show' if vis else 'Hide' self.pb_showeff.setText(text) self.pb_showeff.setToolTip(ttip + ' efficiency graph') self.eff_graph.setVisible(not vis) self.sender().parent().adjustSize() self.centralWidget().adjustSize() self.adjustSize() def _update_first_time(self): """Update first sample time to current timestamp.""" now = _time.time() self._le_firstsmpl.send_value_signal[float].emit(now) def _update_last_time(self): """Update last sample time to current timestamp.""" now = _time.time() self._le_lastsmpl.send_value_signal[float].emit(now) @Slot(float) def _update_graph(self, value): """Receive new lifetime values and update curves in hours.""" if 'BPM' in self.sender().address: self._curve_lifetimebpm.receiveNewValue(value / 3600) else: self._curve_lifetimedcct.receiveNewValue(value / 3600) @Slot(_np.ndarray) def _update_waveforms(self, value): """Update samples waveforms.""" address = self.sender().address if 'BPM' in address: if 'Timestamp' in address: self.bpm_wavx = value + _time.time() self._flag_need_bpmx = False elif 'Value' in address: self.bpm_wavy = value self._flag_need_bpmy = False if not self._flag_need_bpmy and not self._flag_need_bpmx: if len(self.bpm_wavx) != len(self.bpm_wavy): return self.graph.fill_curve_buffer(self._curve_bpm_buff, self.bpm_wavx, self.bpm_wavy) self._flag_need_bpmx = True self._flag_need_bpmy = True else: if 'Timestamp' in address: self.dcct_wavx = value + _time.time() self._flag_need_dcctx = False elif 'Value' in address: self.dcct_wavy = value self._flag_need_dccty = False if not self._flag_need_dccty and not self._flag_need_dcctx: if len(self.dcct_wavx) != len(self.dcct_wavy): return self.graph.fill_curve_buffer(self._curve_dcct_buff, self.dcct_wavx, self.dcct_wavy) self._flag_need_dcctx = True self._flag_need_dccty = True
def _setupIntlkTypeLayout(self, intlk): unit = 'nm' ld_enbl = QLabel('Enable: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) sb_enbl = PyDMStateButton( self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sel')) led_enbl = SiriusLedState( self, self.devpref.substitute(propty='Intlk' + intlk + 'En-Sts')) ld_clr = QLabel('Reset: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) bt_clr = PyDMPushButton(self, init_channel=self.devpref.substitute( propty='Intlk' + intlk + 'Clr-Sel'), pressValue=1) bt_clr.setIcon(qta.icon('fa5s.sync')) bt_clr.setObjectName('clr') bt_clr.setStyleSheet( '#clr{min-width:25px; max-width:25px; icon-size:20px;}') ld_minx = QLabel('Min.X Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_minx = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-SP')) sb_minx.showStepExponent = False sb_minx.limitsFromChannel = False sb_minx.setMinimum(-1e9) sb_minx.setMaximum(+1e9) lb_minx = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinX-RB')) ld_maxx = QLabel('Max.X Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_maxx = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-SP')) sb_maxx.showStepExponent = False sb_maxx.limitsFromChannel = False sb_maxx.setMinimum(-1e9) sb_maxx.setMaximum(+1e9) lb_maxx = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxX-RB')) ld_miny = QLabel('Min.Y Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_miny = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-SP')) sb_miny.showStepExponent = False sb_miny.limitsFromChannel = False sb_miny.setMinimum(-1e9) sb_miny.setMaximum(+1e9) lb_miny = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MinY-RB')) ld_maxy = QLabel('Max.Y Thres.[' + unit + ']: ', self, alignment=Qt.AlignRight | Qt.AlignVCenter) sb_maxy = SiriusSpinbox( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-SP')) sb_maxy.showStepExponent = False sb_maxy.limitsFromChannel = False sb_maxy.setMinimum(-1e9) sb_maxy.setMaximum(+1e9) lb_maxy = PyDMLabel( self, self.devpref.substitute(propty='IntlkLmt' + intlk + 'MaxY-RB')) ld_leglow = QLabel('Smaller', self, alignment=Qt.AlignCenter) ld_leghigh = QLabel('Bigger', self, alignment=Qt.AlignCenter) ld_legmask = QLabel('<h4>Masked By Enable</h4>', self, alignment=Qt.AlignCenter) ld_legmask_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_mask_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'Smaller-Mon')) led_mask_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'Bigger-Mon')) ld_leginst = QLabel('<h4>Instantaneous</h4>', self, alignment=Qt.AlignCenter) ld_leginst_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerAny-Mon')) led_inst_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerAny-Mon')) ld_leginst_x = QLabel('X', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_xlow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerX-Mon')) led_inst_xhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerX-Mon')) ld_leginst_y = QLabel('Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_inst_ylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerY-Mon')) led_inst_yhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerY-Mon')) ld_legltc = QLabel('<h4>Latch</h4>', self, alignment=Qt.AlignCenter) ld_legltc_any = QLabel('X or Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_anylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtc-Mon')) led_ltc_anyhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtc-Mon')) ld_legltc_x = QLabel('X', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_xlow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtcX-Mon')) led_ltc_xhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcX-Mon')) ld_legltc_y = QLabel('Y', self, alignment=Qt.AlignRight | Qt.AlignVCenter) led_ltc_ylow = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'SmallerLtcY-Mon')) led_ltc_yhigh = SiriusLedAlert( self, self.devpref.substitute(propty='Intlk' + intlk + 'BiggerLtcY-Mon')) lay_mon = QGridLayout() lay_mon.setAlignment(Qt.AlignCenter) lay_mon.addWidget(ld_leglow, 0, 1) lay_mon.addWidget(ld_leghigh, 0, 2) lay_mon.addWidget(ld_legmask, 1, 0) lay_mon.addWidget(ld_legmask_any, 2, 0) lay_mon.addWidget(led_mask_anylow, 2, 1) lay_mon.addWidget(led_mask_anyhigh, 2, 2) lay_mon.addWidget(ld_leginst, 3, 0) lay_mon.addWidget(ld_leginst_any, 4, 0) lay_mon.addWidget(led_inst_anylow, 4, 1) lay_mon.addWidget(led_inst_anyhigh, 4, 2) lay_mon.addWidget(ld_leginst_x, 5, 0) lay_mon.addWidget(led_inst_xlow, 5, 1) lay_mon.addWidget(led_inst_xhigh, 5, 2) lay_mon.addWidget(ld_leginst_y, 6, 0) lay_mon.addWidget(led_inst_ylow, 6, 1) lay_mon.addWidget(led_inst_yhigh, 6, 2) lay_mon.addWidget(ld_legltc, 7, 0) lay_mon.addWidget(ld_legltc_any, 8, 0) lay_mon.addWidget(led_ltc_anylow, 8, 1) lay_mon.addWidget(led_ltc_anyhigh, 8, 2) lay_mon.addWidget(ld_legltc_x, 9, 0) lay_mon.addWidget(led_ltc_xlow, 9, 1) lay_mon.addWidget(led_ltc_xhigh, 9, 2) lay_mon.addWidget(ld_legltc_y, 10, 0) lay_mon.addWidget(led_ltc_ylow, 10, 1) lay_mon.addWidget(led_ltc_yhigh, 10, 2) lay = QGridLayout() lay.setAlignment(Qt.AlignTop) lay.addWidget(ld_enbl, 0, 0) lay.addWidget(sb_enbl, 0, 1) lay.addWidget(led_enbl, 0, 2) lay.addWidget(ld_clr, 1, 0) lay.addWidget(bt_clr, 1, 1, alignment=Qt.AlignCenter) lay.addWidget(ld_minx, 2, 0) lay.addWidget(sb_minx, 2, 1) lay.addWidget(lb_minx, 2, 2) lay.addWidget(ld_maxx, 3, 0) lay.addWidget(sb_maxx, 3, 1) lay.addWidget(lb_maxx, 3, 2) lay.addWidget(ld_miny, 4, 0) lay.addWidget(sb_miny, 4, 1) lay.addWidget(lb_miny, 4, 2) lay.addWidget(ld_maxy, 5, 0) lay.addWidget(sb_maxy, 5, 1) lay.addWidget(lb_maxy, 5, 2) lay.addItem(QSpacerItem(1, 15, QSzPlc.Ignored, QSzPlc.Fixed), 6, 0) lay.addLayout(lay_mon, 7, 0, 1, 3) return lay
class InjSysStbyControlWidget(QWidget): """Injection System Control Widget.""" expand = Signal() def __init__(self, parent=None, prefix=VACA_PREFIX, is_summary=False, handler=None): """Init.""" super().__init__(parent) self.prefix = prefix self._inj_prefix = SiriusPVName('AS-Glob:AP-InjCtrl').substitute( prefix=prefix) self._is_summary = is_summary self._last_comm = None self._handler = handler or InjSysStandbyHandler() self._icon_off = qta.icon('mdi.power-off') self._icon_on = qta.icon('mdi.power-on') self._icon_check = qta.icon('fa5s.check') self._pixmap_check = self._icon_check.pixmap( self._icon_check.actualSize(QSize(16, 16))) self._icon_not = qta.icon('fa5s.times') self._pixmap_not = self._icon_not.pixmap( self._icon_not.actualSize(QSize(16, 16))) self.menu = QMenu(self) self.rstord_act = self.menu.addAction('Reset Commands') self.rstord_act.triggered.connect(self._reset_commands_order) if is_summary: self._setupSummary() else: self._setupFull() self._ch_cmdsts = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysCmdSts-Mon')) self._ch_off_order_sp = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysTurnOffOrder-SP')) self._ch_off_order_rb = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysTurnOffOrder-RB')) self._ch_on_order_sp = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysTurnOnOrder-SP')) self._ch_on_order_rb = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysTurnOnOrder-RB')) if not is_summary: self._ch_cmdone = SiriusConnectionSignal( self._inj_prefix.substitute(propty='InjSysCmdDone-Mon')) self._ch_cmdsts.new_value_signal[int].connect( self._handle_cmdsts_buttons_enbl) self._ch_off_order_rb.new_value_signal[str].connect( self._handle_buttons_color) self._ch_on_order_rb.new_value_signal[str].connect( self._handle_buttons_color) self._ch_off_order_rb.new_value_signal[str].connect( self._handle_actions_state) self._ch_on_order_rb.new_value_signal[str].connect( self._handle_actions_state) if not is_summary: self._ch_cmdone.new_value_signal[str].connect( self._handle_cmdone_labels) self._ch_cmdsts.new_value_signal[int].connect( self._handle_cmdsts_labels) def _setupSummary(self): self._pb_off = PyDMPushButton(self, label='', icon=self._icon_off, init_channel=self._inj_prefix.substitute( propty='InjSysTurnOff-Cmd'), pressValue=0) self._pb_off.setObjectName('bt') self._pb_off.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;}') self._pb_on = PyDMPushButton(self, label='', icon=self._icon_on, init_channel=self._inj_prefix.substitute( propty='InjSysTurnOn-Cmd'), pressValue=0) self._pb_on.setObjectName('bt') self._pb_on.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;}') self._led_sts = InjSysStbyLed(self) self._led_sts.setStyleSheet( 'QLed{min-width:1.29em; max-width:1.29em;}') lay = QGridLayout(self) lay.setAlignment(Qt.AlignCenter) lay.addWidget(self._pb_off, 0, 0) lay.addWidget(self._pb_on, 0, 1) lay.addWidget(self._led_sts, 1, 0, 1, 2, alignment=Qt.AlignCenter) # menu for cmmtype in ['on', 'off']: order = getattr(self._handler, cmmtype + '_order') menu = QMenu('Select Turn ' + cmmtype.upper() + ' Commands', self) setattr(self, cmmtype + '_menu', menu) self.menu.addMenu(menu) for cmm in order: act = menu.addAction(self._handler.HANDLER_DESC[cmm]) act.setObjectName(cmm) act.setCheckable(True) def _setupFull(self): lay = QGridLayout(self) lay.addWidget(QLabel('Off', self, alignment=Qt.AlignCenter), 0, 1) lay.addWidget(QLabel('On', self, alignment=Qt.AlignCenter), 0, 2) lay.addWidget(QLabel('Status', self, alignment=Qt.AlignCenter), 0, 3) self._checkbox_off = dict() self._checkbox_on = dict() self._labels_sts = dict() for idx, name in enumerate(self._handler.DEF_ON_ORDER): cb_off = QCheckBox(self) cb_off.setObjectName(name) self._checkbox_off[name] = cb_off cb_on = QCheckBox(self) cb_on.setObjectName(name) self._checkbox_on[name] = cb_on desc = self._handler.HANDLER_DESC[name] splitd = desc.split('(') lbl_txt = splitd[0] tip = '' if len(splitd) > 1: lbl_txt, tip = splitd lb_dsc = QLabel(lbl_txt, self, alignment=Qt.AlignLeft) if tip: lb_dsc.setToolTip(tip[:-1]) lb_sts = QLabel('', self, alignment=Qt.AlignCenter) lb_sts.setObjectName(name) self._labels_sts[name] = lb_sts lay.addWidget(lb_dsc, idx + 1, 0) lay.addWidget(cb_off, idx + 1, 1, alignment=Qt.AlignCenter) lay.addWidget(cb_on, idx + 1, 2, alignment=Qt.AlignCenter) lay.addWidget(lb_sts, idx + 1, 3) self._pb_off = PyDMPushButton(self, label='', icon=self._icon_off, init_channel=self._inj_prefix.substitute( propty='InjSysTurnOff-Cmd'), pressValue=0) self._pb_off.setObjectName('bt') self._pb_off.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;}') self._pb_on = PyDMPushButton(self, label='', icon=self._icon_on, init_channel=self._inj_prefix.substitute( propty='InjSysTurnOn-Cmd'), pressValue=0) self._pb_on.setObjectName('bt') self._pb_on.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;}') self._led_sts = InjSysStbyLed(self) lay.addWidget(self._pb_off, 6, 1) lay.addWidget(self._pb_on, 6, 2) lay.addWidget(self._led_sts, 6, 3) @Slot(int) def _handle_cmdsts_buttons_enbl(self, new_sts): if new_sts == _Const.InjSysCmdSts.On: self._pb_on.setEnabled(False) self._pb_on.setIcon( qta.icon('fa5s.spinner', animation=qta.Spin(self._pb_on))) self._pb_off.setEnabled(False) elif new_sts == _Const.InjSysCmdSts.Off: self._pb_on.setEnabled(False) self._pb_off.setEnabled(False) self._pb_off.setIcon( qta.icon('fa5s.spinner', animation=qta.Spin(self._pb_off))) else: if not self._pb_on.isEnabled(): self._pb_on.setEnabled(True) self._pb_off.setEnabled(True) self._pb_on.setIcon(self._icon_on) self._pb_off.setIcon(self._icon_off) @Slot(str) def _handle_cmdone_labels(self, new_done): for name in self._handler.DEF_ON_ORDER: lbl = self._labels_sts[name] if name in new_done: lbl.setPixmap(self._pixmap_check) elif self._ch_cmdsts.value == _Const.InjSysCmdSts.Idle: lbl.setPixmap(self._pixmap_not) @Slot(int) def _handle_cmdsts_labels(self, new_sts): if new_sts == _Const.InjSysCmdSts.On: self._last_comm = new_sts for name in self._handler.DEF_ON_ORDER: if self._ch_on_order_rb.value is None: break lbl = self._labels_sts[name] if name in self._ch_on_order_rb.value: icon = qta.icon('fa5s.spinner') pixmap = icon.pixmap(icon.actualSize(QSize(16, 16))) lbl.setPixmap(pixmap) else: lbl.setPixmap(QPixmap()) elif new_sts == _Const.InjSysCmdSts.Off: self._last_comm = new_sts for name in self._handler.DEF_OFF_ORDER: if self._ch_off_order_rb.value is None: break lbl = self._labels_sts[name] if name in self._ch_off_order_rb.value: icon = qta.icon('fa5s.spinner') pixmap = icon.pixmap(icon.actualSize(QSize(16, 16))) lbl.setPixmap(pixmap) else: lbl.setPixmap(QPixmap()) else: done = self._ch_cmdone.value for name in self._handler.DEF_ON_ORDER: if done is None or name in done: continue lbl = self._labels_sts[name] if self._last_comm == _Const.InjSysCmdSts.On and \ name in self._ch_on_order_rb.value: lbl.setPixmap(self._pixmap_not) elif self._last_comm == _Const.InjSysCmdSts.Off and \ name in self._ch_off_order_rb.value: lbl.setPixmap(self._pixmap_not) self._last_comm = None @Slot() def _set_commands_order(self): if self._is_summary: if self.sender() in self.on_menu.actions(): on_order = [ a.objectName() for a in self.on_menu.actions() if a.isChecked() ] self._ch_on_order_sp.send_value_signal[str].emit( ','.join(on_order)) elif self.sender() in self.off_menu.actions(): off_order = [ a.objectName() for a in self.off_menu.actions() if a.isChecked() ] self._ch_off_order_sp.send_value_signal[str].emit( ','.join(off_order)) else: if self.sender() in self._checkbox_on.values(): checked = [ w.objectName() for w in self._checkbox_on.values() if w.isChecked() ] on_order = [ h for h in self._handler.DEF_ON_ORDER if h in checked ] self._ch_on_order_sp.send_value_signal[str].emit( ','.join(on_order)) elif self.sender() in self._checkbox_off.values(): checked = [ w.objectName() for w in self._checkbox_off.values() if w.isChecked() ] off_order = [ h for h in self._handler.DEF_OFF_ORDER if h in checked ] self._ch_off_order_sp.send_value_signal[str].emit( ','.join(off_order)) @Slot() def _reset_commands_order(self): self._ch_off_order_sp.send_value_signal[str].emit(','.join( self._handler.DEF_OFF_ORDER)) self._ch_on_order_sp.send_value_signal[str].emit(','.join( self._handler.DEF_ON_ORDER)) if self._is_summary: for menu in [self.off_menu, self.on_menu]: for act in menu.actions(): act.toggled.disconnect() act.setChecked(True) act.toggled.connect(self._set_commands_order) else: for group in [self._checkbox_off, self._checkbox_on]: for wid in group.values(): wid.toggled.disconnect() wid.setChecked(True) wid.toggled.connect(self._set_commands_order) @Slot() def _handle_buttons_color(self): off_color = 'yellow' if self._ch_off_order_rb.value != \ ','.join(self._handler.DEF_OFF_ORDER) else 'white' self._pb_off.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;' 'background-color: ' + off_color + ';}') on_color = 'yellow' if self._ch_on_order_rb.value != \ ','.join(self._handler.DEF_ON_ORDER) else 'white' self._pb_on.setStyleSheet( '#bt{min-width:25px; max-width:25px; icon-size:20px;' 'background-color: ' + on_color + ';}') @Slot(str) def _handle_actions_state(self, sts): state = 'on' if 'On' in self.sender().address else 'off' channel = getattr(self, '_ch_' + state + '_order_rb') if channel.value is None: return if self._is_summary: group = getattr(self, state + '_menu').actions() else: group = getattr(self, '_checkbox_' + state).values() for obj in group: obj.disconnect() ost = obj.objectName() in sts obj.setChecked(ost) obj.toggled.connect(self._set_commands_order) def contextMenuEvent(self, event): """Show a custom context menu.""" self.menu.popup(self.mapToGlobal(event.pos()))
class VLightCamView(QWidget): """VLight Cam Viewer.""" def __init__(self, parent=None, prefix=VACA_PREFIX, section=''): """Init.""" super().__init__(parent) self.prefix = prefix self.section = section.upper() self.device = _PVName(conv_sec_2_device(self.section)) self.cam_prefix = self.device.substitute(prefix=prefix) self.setObjectName(self.section + 'App') self.setWindowTitle(self.device + ' View') self._setupUi() def _setupUi(self): label = QLabel('<h2>' + self.device + ' View</h2>', self, alignment=Qt.AlignCenter) self.cam_viewer = SiriusImageView( parent=self, image_channel=self.cam_prefix.substitute(propty='Data-Mon'), width_channel=self.cam_prefix.substitute(propty='AOIWidth-RB'), offsetx_channel=self.cam_prefix.substitute(propty='AOIOffsetX-RB'), offsety_channel=self.cam_prefix.substitute(propty='AOIOffsetY-RB'), maxwidth_channel=self.cam_prefix.substitute( propty='SensorWidth-Cte'), maxheight_channel=self.cam_prefix.substitute( propty='SensorHeight-Cte')) self.cam_viewer.setObjectName('camview') self.cam_viewer.setStyleSheet(""" #camview{min-width:42em; min-height:32em;}""") self.settings = QGroupBox('Settings', self) self.settings.setLayout(self._setupSettingsLayout()) lay = QVBoxLayout(self) lay.addWidget(label) lay.addWidget(self.cam_viewer) lay.addWidget(self.settings) def _setupSettingsLayout(self): label_CamEnbl = QLabel('Enable:', self) hbox_CamEnbl = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Enbl', propty_type='enbldisabl', width=3) label_FrameCnt = QLabel('Frame Count:', self) hbox_FrameCnt = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='FrameCnt', propty_type='mon') label_Conn = QLabel('Connection:', self) hbox_Conn = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Connection', propty_type='mon') label_Reset = QLabel('Reset Camera:', self) self.pb_dtl = PyDMPushButton( label='', icon=qta.icon('fa5s.sync'), parent=self, pressValue=1, init_channel=self.cam_prefix.substitute(propty='Rst-Cmd')) self.pb_dtl.setObjectName('reset') self.pb_dtl.setStyleSheet( "#reset{min-width:25px; max-width:25px; icon-size:20px;}") flay_sts = QFormLayout() flay_sts.setSpacing(6) flay_sts.setFormAlignment(Qt.AlignHCenter) flay_sts.setLabelAlignment(Qt.AlignRight) flay_sts.addRow(label_CamEnbl, hbox_CamEnbl) flay_sts.addRow(label_FrameCnt, hbox_FrameCnt) flay_sts.addRow(label_Conn, hbox_Conn) flay_sts.addRow(label_Reset, self.pb_dtl) label_AcqMode = QLabel('Acq. Mode:', self) hbox_AcqMode = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AcqMode', propty_type='enum') label_AcqPeriod = QLabel('Acq. Period [s]:', self) hbox_AcqPeriod = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='AcqPeriod', propty_type='sprb') label_ExpTime = QLabel('Exp. Time [us]:', self) hbox_ExpTime = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='ExposureTime', propty_type='sprb') label_Gain = QLabel('Gain [dB]:', self) hbox_Gain = create_propty_layout(parent=self, prefix=self.cam_prefix, propty='Gain', propty_type='sprb', cmd={ 'label': '', 'pressValue': 1, 'width': '25', 'height': '25', 'icon': qta.icon('mdi.auto-fix'), 'icon-size': '20', 'toolTip': 'Auto Gain', 'name': 'AutoGain' }) flay_ctrl = QFormLayout() flay_ctrl.setSpacing(6) flay_ctrl.setFormAlignment(Qt.AlignHCenter) flay_ctrl.setLabelAlignment(Qt.AlignRight) flay_ctrl.addRow(label_AcqMode, hbox_AcqMode) flay_ctrl.addRow(label_AcqPeriod, hbox_AcqPeriod) flay_ctrl.addRow(label_ExpTime, hbox_ExpTime) flay_ctrl.addRow(label_Gain, hbox_Gain) self.pb_details = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self) self.pb_details.setToolTip('More settings') self.pb_details.setObjectName('detail') self.pb_details.setStyleSheet( "#detail{min-width:25px; max-width:25px; icon-size:20px;}") self.pb_details.setSizePolicy(QSzPlcy.Expanding, QSzPlcy.Preferred) MyWindow = create_window_from_widget(BaslerCamSettings, title=self.device + ' Settings Details', is_main=True) util.connect_window(self.pb_details, MyWindow, parent=self, prefix=self.prefix, device=self.device) lay = QHBoxLayout() lay.setSpacing(20) lay.addLayout(flay_sts) lay.addLayout(flay_ctrl) lay.addWidget(self.pb_details, alignment=Qt.AlignTop) return lay