class ConsoleRestartDialog(QDialog): """ Dialog to apply preferences that need a restart of the console kernel. """ # Constants for actions when Preferences require a kernel restart NO_RESTART = 1 RESTART_CURRENT = 2 RESTART_ALL = 3 def __init__(self, parent): super(ConsoleRestartDialog, self).__init__(parent) self.setWindowFlags(Qt.Dialog | Qt.WindowTitleHint) self._parent = parent self._action = self.NO_RESTART self._action_string = { self.NO_RESTART: _("Keep Existing Kernels"), self.RESTART_CURRENT: _("Restart Current Kernel"), self.RESTART_ALL: _("Restart All Kernels") } # Dialog widgets # Text self._text_label = QLabel( _("By default, some IPython console preferences will be " "applied to new consoles only. To apply preferences to " "existing consoles, select from the options below.<br><br>" "Please note: applying changes to running consoles will force" " a kernel restart and all current work will be lost."), self) self._text_label.setWordWrap(True) self._text_label.setFixedWidth(450) # Checkboxes self._restart_current = QCheckBox( _("Apply to current console and restart kernel"), self) self._restart_all = QCheckBox( _("Apply to all existing consoles and restart all kernels"), self) self._checkbox_group = QButtonGroup(self) self._checkbox_group.setExclusive(False) self._checkbox_group.addButton(self._restart_current, id=self.RESTART_CURRENT) self._checkbox_group.addButton(self._restart_all, id=self.RESTART_ALL) self._action_button = QPushButton(self._action_string[self.NO_RESTART], parent=self) # Dialog Layout layout = QVBoxLayout(self) layout.addWidget(self._text_label) layout.addSpacing(5) layout.addWidget(self._restart_current) layout.addWidget(self._restart_all) layout.addSpacing(10) layout.addWidget(self._action_button, 0, Qt.AlignRight) layout.setContentsMargins(20, 20, 20, 20) self.setLayout(layout) # Signals self._checkbox_group.buttonToggled.connect( self.update_action_button_text) self._action_button.clicked.connect(self.accept) def update_action_button_text(self, checkbox, is_checked): """ Update action button text. Takes into account the given checkbox to update the text. """ checkbox_id = self._checkbox_group.id(checkbox) if is_checked: text = self._action_string[checkbox_id] self._checkbox_group.buttonToggled.disconnect( self.update_action_button_text) self._restart_current.setChecked(False) self._restart_all.setChecked(False) checkbox.setChecked(True) self._checkbox_group.buttonToggled.connect( self.update_action_button_text) else: text = self._action_string[self.NO_RESTART] self._action_button.setText(text) def get_action_value(self): """ Return tuple indicating True or False for the available actions. """ restart_current = self._restart_current.isChecked() restart_all = self._restart_all.isChecked() no_restart = not any([restart_all, restart_current]) return restart_all, restart_current, no_restart
class BaseWindow(SiriusMainWindow): """Base class.""" def __init__(self, parent=None, prefix=_VACA_PREFIX): """Init.""" super().__init__(parent) self.prefix = prefix self._curr_dir = _os.path.abspath(_os.path.dirname(__file__)) def _setupUi(self): # menubar self.menubar = QMenuBar(self) self.menubar.setNativeMenuBar(False) self.setMenuBar(self.menubar) self.menu = self.menubar.addMenu("Open...") self._setupMenu() # auxiliar diagnostics widget self.auxdig_wid = None self._setupDiagWidget() # lattice widget self.lattice_wid = QSvgWidget( _os.path.join(self._curr_dir, self.SVG_FILE)) # screens view widget (create only one ScrnView) self._scrns_wids_dict = dict() self._currScrn = 0 scrn_wid = SiriusScrnView(parent=self, prefix=self.prefix, device=self._scrns[self._currScrn]) scrn_wid.setVisible(True) self._scrns_wids_dict[self._currScrn] = scrn_wid self.scrns_wid = QWidget() lay_scrns = QGridLayout(self.scrns_wid) lay_scrns.addWidget(scrn_wid) # correction widget self.corr_wid = QGroupBox('Screens and Correctors Panel') self._scrns_sel_bg = QButtonGroup(parent=self.corr_wid) self._scrns_sel_bg.setExclusive(True) self._setupScrnsCorrsWidget() vlay1 = QVBoxLayout() if self.auxdig_wid: vlay1.addWidget(self.auxdig_wid) vlay1.addWidget(self.scrns_wid) vlay2 = QVBoxLayout() vlay2.addWidget(self.lattice_wid) vlay2.addWidget(self.corr_wid) cw = QWidget() lay = QHBoxLayout(cw) lay.addLayout(vlay1) lay.addLayout(vlay2) self.setCentralWidget(cw) def _setupMenu(self): raise NotImplementedError def _setupScrnsCorrsWidget(self): raise NotImplementedError def _setupDiagWidget(self): raise NotImplementedError @Slot() def _setScrnWidget(self): scrn_obj = self._scrns_wids_dict[self._currScrn] scrn_obj.setVisible(False) sender = self.sender() self._currScrn = self._scrns_sel_bg.id(sender) if self._currScrn not in self._scrns_wids_dict.keys(): scrn_obj = SiriusScrnView(parent=self, prefix=self.prefix, device=self._scrns[self._currScrn]) self.scrns_wid.layout().addWidget(scrn_obj, 2, 0) self._scrns_wids_dict[self._currScrn] = scrn_obj else: scrn_obj = self._scrns_wids_dict[self._currScrn] self._scrns_wids_dict[self._currScrn].setVisible(True) def _create_headerline(self, labels): """Create and return a headerline.""" hl = QWidget() hl.setLayout(QHBoxLayout()) hl.layout().setContentsMargins(0, 9, 0, 0) glay = None for text, width in labels: if not width: if glay: hl.layout().addLayout(glay) hl.layout().addStretch() glay = QGridLayout() glay.setAlignment(Qt.AlignCenter) glay.setContentsMargins(0, 0, 0, 0) c = 0 else: label = QLabel(text, self) label.setStyleSheet(""" min-width:valueem; min-height:1.29em; max-height:1.29em; font-weight:bold; qproperty-alignment: AlignCenter; """.replace('value', str(width))) glay.addWidget(label, 0, c) c += 1 return hl def _create_scrn_summwidget(self, scrn_device, scrn_idx): """Create and return a screen detail widget.""" cb_scrn = QCheckBox(scrn_device.get_nickname(dev=True), self) self._scrns_sel_bg.addButton(cb_scrn) self._scrns_sel_bg.setId(cb_scrn, scrn_idx) if scrn_idx == self._currScrn: cb_scrn.setChecked(True) cb_scrn.clicked.connect(self._setScrnWidget) cb_scrn.setStyleSheet(""" min-width:6.5em; max-width:6.5em; font-weight:bold;""") led_camenbl = SiriusLedState( self, scrn_device.substitute(prefix=self.prefix, propty='CamEnbl-Sts')) led_camenbl.setStyleSheet("min-width:3.2em; max-width:3.2em;") cb_scrntype = PyDMEnumComboBox( self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sel')) cb_scrntype.setSizePolicy(QSzPlcy.Minimum, QSzPlcy.Fixed) cb_scrntype.setStyleSheet("min-width:4.5em;max-width:4.5em;") lb_scrntype = PyDMLabel( self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sts')) lb_scrntype.setStyleSheet("min-width:4.5em; max-width:4.5em;") lb_scrntype.setAlignment(Qt.AlignCenter) led_scrntype = PyDMLed(self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sts'), color_list=[ PyDMLed.LightGreen, PyDMLed.Red, PyDMLed.Red, PyDMLed.Yellow ]) led_scrntype.shape = 2 led_scrntype.setStyleSheet("""min-width:4.5em; max-width:4.5em;""") wid = QWidget() lay = QGridLayout(wid) lay.setAlignment(Qt.AlignCenter) lay.addWidget(cb_scrn, 1, 1) lay.addWidget(led_camenbl, 1, 2) lay.addWidget(cb_scrntype, 1, 3) lay.addWidget(lb_scrntype, 1, 4) lay.addWidget(led_scrntype, 2, 4) return wid def _create_corr_summwidget(self, corr): """Create and return a corrector detail widget.""" wid = QWidget() wid.setSizePolicy(QSzPlcy.Preferred, QSzPlcy.Maximum) lay = QGridLayout(wid) lay.setContentsMargins(0, 0, 0, 0) lay.setAlignment(Qt.AlignCenter) propty_sp = 'Current-SP' if corr.sec == 'LI' else 'Kick-SP' propty_mon = propty_sp.replace('SP', 'Mon') led = SiriusLedState( self, corr.substitute(prefix=self.prefix, propty='PwrState-Sts')) led.setStyleSheet("max-width:1.29em;") lay.addWidget(led, 1, 1) nickname = corr.get_nickname(sec=corr.sec == 'LI', dev=True) pb = QPushButton(nickname, self) if corr.dis == 'PU': util.connect_window(pb, PUDetailWindow, parent=self, devname=corr) else: util.connect_window(pb, PSDetailWindow, parent=self, psname=corr) pb.setStyleSheet(""" min-width:6em; max-width:6em; min-height:1.29em;""") lay.addWidget(pb, 1, 2) sp_kick = PyDMSpinboxScrollbar( self, corr.substitute(prefix=self.prefix, propty=propty_sp)) sp_kick.setStyleSheet("QDoubleSpinBox{min-width:4em; max-width:4em; }" "QScrollBar{max-width:4em;}") sp_kick.spinbox.precisionFromPV = False sp_kick.spinbox.precision = 1 sp_kick.scrollbar.limitsFromPV = True lay.addWidget(sp_kick, 1, 3, 2, 1) lb_kick = PyDMLabel( self, corr.substitute(prefix=self.prefix, propty=propty_mon)) lb_kick.setStyleSheet(""" min-width:5em; max-width:5em; min-height:1.29em;""") lb_kick.showUnits = True lb_kick.precisionFromPV = False lb_kick.precision = 1 lb_kick.setAlignment(Qt.AlignCenter) lay.addWidget(lb_kick, 1, 4) return wid
class PeriodicTableWidget(QWidget): selectionChanged = Signal() def __init__(self, parent=None): QWidget.__init__(self, parent) # Widgets, layouts and signals self._group = QButtonGroup() layout = QGridLayout() layout.setSpacing(0) ## Element for z, position in _ELEMENT_POSITIONS.items(): widget = ElementPushButton(z) widget.setCheckable(True) layout.addWidget(widget, *position) self._group.addButton(widget, z) ## Labels layout.addWidget(QLabel(''), 7, 0) # Dummy layout.addWidget(QLabel('*'), 5, 2, Qt.AlignRight) layout.addWidget(QLabel('*'), 8, 2, Qt.AlignRight) layout.addWidget(QLabel('**'), 6, 2, Qt.AlignRight) layout.addWidget(QLabel('**'), 9, 2, Qt.AlignRight) for row in [0, 1, 2, 3, 4, 5, 6, 8, 9]: layout.setRowStretch(row, 1) self.setLayout(layout) # Signals self._group.buttonClicked.connect(self.selectionChanged) # Default self.setColorFunction(_category_color_function) def setColorFunction(self, func): if not callable(func): raise ValueError('Not a function') self._color_function = func # Redraw for widget in self._group.buttons(): z = self._group.id(widget) bcolor = func(z) fcolor = 'white' if _calculate_brightness(bcolor) < 128 else 'black' sheet = 'background-color: %s; color: %s' % (bcolor.name(), fcolor) widget.setStyleSheet(sheet) def colorFunction(self): return self._color_function def setMultipleSelection(self, multiple): self._group.setExclusive(not multiple) def isMultipleSelection(self): return not self._group.exclusive() def setSelection(self, selection): def _uncheckedAll(): for widget in self._group.buttons(): widget.setChecked(False) if selection is None: _uncheckedAll() self.selectionChanged.emit() return if isinstance(selection, (int, six.string_types)): selection = [selection] if not self.isMultipleSelection() and len(selection) > 1: raise ValueError('Multiple selection mode is off. Cannot select more than one element') _uncheckedAll() for z in selection: if isinstance(z, six.string_types): z = get_atomic_number(z) self._group.button(z).setChecked(True) self.selectionChanged.emit() # def selection(self): selection = set() for widget in self._group.buttons(): if widget.isChecked(): selection.add(self._group.id(widget)) if self.isMultipleSelection(): return frozenset(selection) else: if len(selection) > 0: return list(selection)[0] else: return None def selectionSymbol(self): selection = self.selection() if self.isMultipleSelection(): return frozenset(map(get_symbol, selection)) else: if selection is None: return None else: return get_symbol(selection)