def __init__(self, controller, parent=None, state=None): CellItem.__init__(self, controller, parent, state) self.label = QLabel('%s' % self.state) self.label.setAlignment(Qt.AlignCenter) self.widgets.append(self.label) self.set_layout() self.setMinimumWidth(20)
def _queryDetails(self): dlg = QDialog(self) dlg.setWindowTitle('Login details for ticket tracker required') layout = QGridLayout() layout.addWidget( QLabel( 'Please enter details for the ticket tracker. ' 'You can contact the instrument control group ' 'for help.', dlg)) layout.addWidget(QLabel('Instrument name:', dlg)) instrBox = QLineEdit(self.instrument, dlg) instrBox.setEnabled(self.instrument != 'none') layout.addWidget(instrBox) noinstrBox = QCheckBox('No instrument', dlg) noinstrBox.setChecked(self.instrument == 'none') noinstrBox.toggled.connect(lambda c: instrBox.setEnabled(not c)) layout.addWidget(noinstrBox) layout.addWidget(QLabel('Username:'******'Password:'******'Login successful. Your API key has been stored ' 'for further reports.') settings = CompatSettings('nicos', 'secrets') settings.beginGroup('Redmine') if noinstrBox.isChecked(): self.instrument = 'none' else: self.instrument = instrBox.text() self.apikey = apikey self.username = userBox.text() settings.setValue('instrument', self.instrument) settings.setValue('apikey', self.apikey) settings.setValue('username', self.username) if not self.instrument or not self.apikey: return False self.titleLabel.setText( 'Submit a ticket for instrument "%s" (as user %s)' % (self.instrument, self.username)) return True
def __init__(self, parent, curvalue, client, allow_enter=False): MultiWidget.__init__(self, parent, (float, float), curvalue, client, allow_enter=allow_enter) self._layout.addWidget(QLabel('from', self), 0, 0) self._layout.addWidget(QLabel('to', self), 0, 1)
def _init_toolbar(self): self.statusLabel = QLabel('', self, pixmap=QPixmap(':/disconnected'), margin=5, minimumSize=QSize(30, 10)) self.toolbar = self.toolBarMain self.toolbar.addWidget(self.statusLabel) self.setStatus('disconnected')
def _init_toolbar(self): self.statusLabel = QLabel('', self, pixmap=QPixmap(':/disconnected'), margin=5, minimumSize=QSize(30, 10)) self.statusLabel.setStyleSheet('color: white') self.toolbar = self.toolBarRight self.toolbar.addWidget(self.statusLabel) self.setStatus('disconnected')
def __init__(self, parent=None, designMode=False, **kwds): QWidget.__init__(self, parent, **kwds) NicosWidget.__init__(self) self._last_mtime = None self.namelabel = QLabel(self) self.namelabel.setAlignment(Qt.AlignHCenter) self.piclabel = QLabel(self) self.piclabel.setScaledContents(True) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.piclabel, 1) self.setLayout(layout)
def __init__(self, parent=None): QMainWindow.__init__(self, parent) uic.loadUi( path.join(path.dirname(path.abspath(__file__)), 'ui', 'mainwindow.ui'), self) logging.basicConfig() self.log = logging.getLogger() setupcontroller.init(self.log) classparser.init(self.log) # dictionary of absolute path to a setup - setupWidget self.setupWidgets = {} # dictionary of absolute path to setup - dict # which is deviceName - deviceWidget self.deviceWidgets = {} self.labelHeader = QLabel('Select Setup or device...') self.labelHeader.setAlignment(Qt.AlignCenter) # signal/slot connections self.treeWidget.itemActivated.connect(self.loadSelection) self.treeWidget.deviceRemoved.connect(self.deviceRemovedSlot) self.treeWidget.deviceAdded.connect(self.deviceAddedSlot) self.treeWidget.newDeviceAdded.connect(self.newDeviceAddedSlot) # setup the menu bar self.actionNewFile.triggered.connect(self.treeWidget.newSetup) self.actionSave.triggered.connect(self.actionSaveSlot) self.actionSaveAs.triggered.connect(self.actionSaveAsSlot) self.actionExit.triggered.connect(self.close) self.instrumentMenu = self.menuView.addMenu('Instrument') self.actionShowAllInstrument = self.menuView.addAction( 'Show all instruments') self.actionShowAllInstrument.triggered.connect( self.treeWidget.setAllInstrumentsVisible) self.menuView.addAction(self.dockWidget.toggleViewAction()) self.dockWidget.toggleViewAction().setText('Show Tree') self.actionAboutSetupFileTool.triggered.connect( self.aboutSetupFileTool) self.actionAboutQt.triggered.connect(QApplication.aboutQt) self.workarea.addWidget(self.labelHeader) self.treeWidget.loadNicosData() for directory in sorted(setupcontroller.setup_directories): instrumentAction = self.instrumentMenu.addAction(directory) instrumentAction.triggered.connect( self.treeWidget.setInstrumentMode) if config.instrument and config.instrument not in ('jcns', 'demo'): self.treeWidget.setSingleInstrument(config.instrument)
def _init_instrument_name(self): self.instrument_text = QLabel() self.instrument_text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.instrument_text.setStyleSheet( 'font-size: 17pt; font-weight: bold') self.toolBarMain.addWidget(self.instrument_text) self.instrument_label = QLabel() self.instrument_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.instrument_label.setStyleSheet('font-size: 17pt') self.toolBarMain.addWidget(self.instrument_label)
class BlockBox(QFrame): """Provide the equivalent of a Tk LabelFrame: a group box that has a definite frame around it. """ def __init__(self, parent, text, font, config): if config.get('frames', True): QFrame.__init__(self, parent, frameShape=QFrame.Panel, frameShadow=QFrame.Raised, lineWidth=2) else: QFrame.__init__(self, parent, frameShape=QFrame.NoFrame) self._label = None if text: self._label = QLabel(' ' + text + ' ', parent, autoFillBackground=True, font=font) self._label.resize(self._label.sizeHint()) self._label.show() self._onlyfields = [] self.setups = config.get('setups', None) def moveEvent(self, event): self._repos() return QFrame.moveEvent(self, event) def resizeEvent(self, event): self._repos() return QFrame.resizeEvent(self, event) def _repos(self): if self._label: mps = self.pos() msz = self.size() lsz = self._label.size() self._label.move(mps.x() + 0.5 * (msz.width() - lsz.width()), mps.y() - 0.5 * lsz.height()) def enableDisplay(self, layout, isvis): QFrame.setVisible(self, isvis) if self._label: self._label.setVisible(isvis) if not isvis: layout.removeWidget(self) else: layout.insertWidget(1, self) self.updateGeometry()
def __init__(self, parent, text, font, config): if config.get('frames', True): QFrame.__init__(self, parent, frameShape=QFrame.Panel, frameShadow=QFrame.Raised, lineWidth=2) else: QFrame.__init__(self, parent, frameShape=QFrame.NoFrame) self._label = None if text: self._label = QLabel(' ' + text + ' ', parent, autoFillBackground=True, font=font) self._label.resize(self._label.sizeHint()) self._label.show() self._onlyfields = [] self.setups = config.get('setups', None)
def __init__(self, parent, client, **settings): QMainWindow.__init__(self, parent) DlgUtils.__init__(self, 'Instrument config') loadUi(self, findResource('nicos_mlz/kws1/gui/instrconfig.ui')) self.setWindowTitle('Reconfigure Instrument') self.client = client self.client.connected.connect(self.on_client_connected) self.client.disconnected.connect(self.on_client_disconnected) self._parts = settings['parts'] self._widgets = [] for (i, part) in enumerate(self._parts): label = QLabel(part + ':', self) bgrp = QButtonGroup(self) rbtn = QRadioButton('real', self) vbtn = QRadioButton('virtual', self) bgrp.addButton(rbtn) bgrp.addButton(vbtn) self.grid.addWidget(label, i, 0) self.grid.addWidget(rbtn, i, 1) self.grid.addWidget(vbtn, i, 2) self._widgets.append((label, bgrp, rbtn, vbtn)) self.resize(self.sizeHint()) if self.client.isconnected: self._update() else: self.frame.setDisabled(True)
def __init__(self, parent, types, curvalue, client, allow_enter=False, valinfo=None): QWidget.__init__(self, parent) layout = self._layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) self._widgets = [] if valinfo is not None: for i, info in enumerate(valinfo): layout.addWidget(QLabel(info.name), 0, i) for i, (typ, val) in enumerate(zip(types, curvalue)): widget = create(self, typ, val, client=client, allow_enter=allow_enter) self._widgets.append(widget) widget.valueModified.connect(self.valueModified) if allow_enter: widget.valueChosen.connect( lambda val: self.valueChosen.emit(self.getValue())) layout.addWidget(widget, 1, i) self.setLayout(layout)
def initUi(self): self.namelabel = QLabel(' ', self, textFormat=Qt.RichText) self.update_namelabel() valuelabel = SensitiveSMLabel('----', self, self._label_entered, self._label_left) valuelabel.setFrameShape(QFrame.Panel) valuelabel.setAlignment(Qt.AlignHCenter) valuelabel.setFrameShadow(QFrame.Sunken) valuelabel.setAutoFillBackground(True) setBothColors(valuelabel, (self._colorscheme['fore'][UNKNOWN], self._colorscheme['back'][UNKNOWN])) valuelabel.setLineWidth(2) self.valuelabel = valuelabel self.width = 8 self.reinitLayout()
def __init__(self, parent, designMode=False, **kwds): self._inner = None QWidget.__init__(self, parent, **kwds) NicosWidget.__init__(self) self._layout = QHBoxLayout() self._layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._layout) if designMode: self._layout.insertWidget(0, QLabel('(Value Editor)', self))
def __init__(self, parent, inner, annotation): QWidget.__init__(self, parent) layout = self._layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self._inner = inner self._inner.valueModified.connect(self.valueModified) self._inner.valueChosen.connect(self.valueChosen) layout.addWidget(inner) layout.addWidget(QLabel(annotation, parent)) self.setLayout(layout)
def _squeeze(self, text=None): if text is None: text = self._fulltext or self.text() fm = self.fontMetrics() labelwidth = self.size().width() squeezed = False new_lines = [] for line in text.split('\n'): if fm.width(line) > labelwidth: squeezed = True new_lines.append(fm.elidedText(line, Qt.ElideRight, labelwidth)) else: new_lines.append(line) if squeezed: QLabel.setText(self, '\n'.join(map(text_type, new_lines))) self.setToolTip(self._fulltext) else: QLabel.setText(self, self._fulltext) self.setToolTip('')
def add_logo(self): logo_label = QLabel() pxr = decolor_logo( QPixmap(path.join(root_path, 'resources', 'logo-icon.png')), Qt.white) logo_label.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) logo_label.setMargin(5) self.toolBarMain.insertWidget(self.toolBarMain.actions()[0], logo_label) nicos_label = QLabel() pxr = decolor_logo( QPixmap(path.join(root_path, 'resources', 'nicos-logo-high.svg')), Qt.white) nicos_label.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) self.toolBarMain.insertWidget(self.toolBarMain.actions()[1], nicos_label)
def __init__(self, viewplot, curvenames, *args): QFileDialog.__init__(self, viewplot, *args) self.setOption(self.DontConfirmOverwrite, False) # allow adding some own widgets self.setOption(self.DontUseNativeDialog, True) self.setAcceptMode(QFileDialog.AcceptSave) layout = self.layout() layout.addWidget(QLabel('Curve:', self), 4, 0) self.curveCombo = QComboBox(self) if len(curvenames) > 1: self.curveCombo.addItem('all (in separate files)') self.curveCombo.addItem('all (in one file, multiple data columns)') self.curveCombo.addItems(curvenames) layout.addWidget(self.curveCombo, 4, 1) layout.addWidget(QLabel('Time format:', self), 5, 0) self.formatCombo = QComboBox(self) self.formatCombo.addItems([ 'Seconds since first datapoint', 'UNIX timestamp', 'Text timestamp (YYYY-MM-dd.HH:MM:SS)' ]) layout.addWidget(self.formatCombo, 5, 1)
def __init__(self, parent): QMainWindow.__init__(self, parent) DlgUtils.__init__(self, 'Live data') self.panel = parent layout1 = QVBoxLayout() self.plot = QwtPlot(self) layout1.addWidget(self.plot) self.curve = QwtPlotCurve() self.curve.setRenderHint(QwtPlotCurve.RenderAntialiased) self.curve.attach(self.plot) self.marker = QwtPlotMarker() self.marker.attach(self.plot) self.markerpen = QPen(Qt.red) self.marker.setSymbol( QwtSymbol(QwtSymbol.Ellipse, QBrush(), self.markerpen, QSize(7, 7))) self.zoomer = QwtPlotZoomer(self.plot.canvas()) self.zoomer.setMousePattern(QwtPlotZoomer.MouseSelect3, Qt.NoButton) self.picker = QwtPlotPicker(self.plot.canvas()) self.picker.setSelectionFlags(QwtPlotPicker.PointSelection | QwtPlotPicker.ClickSelection) self.picker.setMousePattern(QwtPlotPicker.MouseSelect1, Qt.MidButton) self.picker.selected.connect(self.pickerSelected) layout2 = QHBoxLayout() layout2.addWidget(QLabel('Scale:', self)) self.scale = QComboBox(self) self.scale.addItems([ 'Single detectors, sorted by angle', 'Scattering angle 2theta (deg)', 'Q value (A-1)' ]) self.scale.currentIndexChanged[int].connect(self.scaleChanged) layout2.addWidget(self.scale) layout2.addStretch() self.scaleframe = QFrame(self) self.scaleframe.setLayout(layout2) self.scaleframe.setVisible(False) layout1.addWidget(self.scaleframe) mainframe = QFrame(self) mainframe.setLayout(layout1) self.setCentralWidget(mainframe) self.setContentsMargins(6, 6, 6, 6) plotfont = scaledFont(self.font(), 0.7) self.plot.setAxisFont(QwtPlot.xBottom, plotfont) self.plot.setAxisFont(QwtPlot.yLeft, plotfont) self.plot.setCanvasBackground(Qt.white) self.resize(800, 200) self._detinfo = None self._anglemap = None self._infowindow = None self._infolabel = None self._xs = self._ys = None self._type = None
def _retrieve_detinfo(self): if self._detinfo is None: info = self.panel.client.eval( 'det._detinfo_parsed, ' 'det._anglemap', None) if not info: return self.showError('Cannot retrieve detector info.') self._lambda = self.panel.client.eval('chWL()', None) if not self._lambda: return self.showError('Cannot retrieve wavelength.') self._detinfo, self._anglemap = info self._inverse_anglemap = 0 self._infowindow = QMainWindow(self) self._infolabel = QLabel(self._infowindow) self._infolabel.setTextFormat(Qt.RichText) self._infowindow.setCentralWidget(self._infolabel) self._infowindow.setContentsMargins(10, 10, 10, 10) self._inv_anglemap = [[ entry for entry in self._detinfo[1:] if entry[12] == self._anglemap[detnr] + 1 ][0] for detnr in range(len(self._xs))]
def addLogo(self): logoLabel = QLabel() pxr = decolor_logo(QPixmap("resources/logo-icon.png"), Qt.white) logoLabel.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) self.toolBarMain.insertWidget(self.toolBarMain.actions()[0], logoLabel) nicosLabel = QLabel() pxr = decolor_logo(QPixmap("resources/nicos-logo-high.svg"), Qt.white) nicosLabel.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) self.toolBarMain.insertWidget(self.toolBarMain.actions()[1], nicosLabel)
def viewTextFile(self, fname): with open(fname) as f: contents = f.read() qd = QDialog(self, 'PreviewDlg', True) qd.setCaption('File preview') qd.resize(QSize(500, 500)) lay = QVBoxLayout(qd, 11, 6, 'playout') lb = QLabel(qd, 'label') lb.setText('Viewing %s:' % fname) lay.addWidget(lb) tx = QTextEdit(qd, 'preview') tx.setReadOnly(1) tx.setText(contents) font = QFont(tx.font()) font.setFamily('monospace') tx.setFont(font) lay.addWidget(tx) btn = QPushButton(qd, 'ok') btn.setAutoDefault(1) btn.setDefault(1) btn.setText('Close') btn.clicked.connect(qd.accept) lay.addWidget(btn, 0, QWidget.AlignRight) qd.show()
def __init__(self, parent, name, selections, preselect): QFrame.__init__(self, parent) self.name = name self.selections = selections layout = QHBoxLayout() layout.addWidget(QLabel(name, self)) self.combo = QComboBox(self) self.combo.addItems(selections) if preselect in selections: self.combo.setCurrentIndex(selections.index(preselect)) else: self.combo.setCurrentIndex(0) layout.addWidget(self.combo) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout)
def __init__(self, title, xlabel, ylabel, name='unknown', parent=None, **kwds): QWidget.__init__(self, parent) self.name = name parent.setLayout(QVBoxLayout()) self.plot = MiniPlot(xlabel, ylabel, self, color1=COLOR_BLACK, color2=COLOR_RED) titleLabel = QLabel(title) titleLabel.setAlignment(Qt.AlignCenter) titleLabel.setStyleSheet('QLabel {font-weight: 600}') parent.layout().insertWidget(0, titleLabel) self.plot.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) parent.layout().insertWidget(1, self.plot)
def __init__(self, parent, measdef, client): self._edit = None self.measdef = measdef self.client = client QDialog.__init__(self, parent) loadUi(self, findResource('nicos_ess/loki/gui/ui_files/detsets.ui')) self.table.setColumnCount(len(measdef.getElements())) # apply current settings self._rows = [] if measdef.detsets: for row in measdef.detsets[0]: self.addRow(row) # create widgets for new setting self._new_elements = {} headers = [] for i, (eltype, cls) in enumerate(measdef.getElements()): element = self._new_elements[eltype] = cls(eltype, self.client) w = element.createWidget(self, self.client) for other in self._new_elements.values(): if other is not element: element.otherChanged(other.eltype, other.getValue()) def handler(new_value, eltype=eltype): for other in self._new_elements.values(): other.otherChanged(eltype, new_value) element.changed.connect(handler) headers.append(element.getLabel()) layout = QVBoxLayout() layout.addWidget(QLabel(headers[-1], self)) layout.addWidget(w) self.widgetFrame.layout().insertLayout(i, layout) # update table widget self.table.setHorizontalHeaderLabels(headers) self.table.resizeColumnsToContents() for i in range(len(measdef.getElements())): self.table.setColumnWidth(i, max(50, 1.5 * self.table.columnWidth(i))) self.table.resizeRowsToContents()
def getToolbars(self): bar = QToolBar('Live data') bar.addAction(self.actionWriteXml) bar.addAction(self.actionPrint) bar.addSeparator() bar.addAction(self.actionLogScale) bar.addSeparator() bar.addAction(self.actionUnzoom) bar.addAction(self.actionSetAsROI) bar.addSeparator() bar.addAction(self.actionSelectChannels) bar.addSeparator() bar.addAction(self.actionCustomRange) bar.addWidget(self.rangeFrom) bar.addWidget(QLabel(' to ')) bar.addWidget(self.rangeTo) bar.addSeparator() bar.addAction(self.actionOverviewMode) bar.addAction(self.actionPhaseMode) bar.addAction(self.actionContrastMode) return [bar]
def createItem(self, keyval=None): if keyval is None: key = self.keytype() val = self.valtype() else: key, val = keyval # pylint: disable=W0633 keywidget = create(self, self.keytype, key, client=self.client, allow_enter=self.allow_enter) keywidget.valueModified.connect(self.valueModified) keywidget.valueChosen.connect( lambda val: self.valueChosen.emit(self.getValue())) valwidget = create(self, self.valtype, val, client=self.client, allow_enter=self.allow_enter) valwidget.valueModified.connect(self.valueModified) valwidget.valueChosen.connect( lambda val: self.valueChosen.emit(self.getValue())) return (keywidget, QLabel('=>', self), valwidget)
def __init__(self, parent, client, options): CustomButtonPanel.__init__(self, parent, client, options) # our content is a simple widget ... self._tableWidget = TableWidget(self) self._tableWidget.setColumnCount(1) self._tableWidget.setHorizontalHeaderLabels(['Sample name']) self._tableWidget.horizontalHeaderItem(0).setTextAlignment( Qt.AlignLeft | Qt.AlignVCenter) self._tableWidget.setSortingEnabled(False) self._tableWidget.setCornerLabel('Position') self.vBoxLayout.insertWidget(0, self._tableWidget) client.connected.connect(self.on_client_connected) client.setup.connect(self.on_client_connected) image = options.get('image', None) # insert the optional image at top... if image: l = QLabel(self) l.setText(image) # insert above scrollArea self.vBoxLayout.insertWidget(0, l, alignment=Qt.AlignHCenter) p = QPixmap() if p.load(findResource(image)): l.setPixmap(p) else: msg = 'Loading of Image %r failed:' % image msg += '\n\nCheck GUI config file for %r' % __file__ self.showError(msg) self._numSamples = int(options.get('positions', 11)) self._tableWidget.setRowCount(self._numSamples) # fill in widgets into grid for pos in range(self._numSamples): self._tableWidget.setCellWidget(pos, 0, QLineEdit('')) self._tableWidget.horizontalHeader().setStretchLastSection(100) # now fill in data self._update_sample_info()
class PictureDisplay(NicosWidget, QWidget): """A display widget to show a picture.""" designer_description = 'Widget to display a picture file' filepath = PropDef('filepath', str, '', 'Path to the picture that should ' 'be displayed') name = PropDef('name', str, '', 'Name (caption) to be displayed above ' 'the picture') refresh = PropDef('refresh', int, 0, 'Interval to check for updates ' 'in seconds') height = PropDef('height', int, 0) width = PropDef('width', int, 0) def __init__(self, parent=None, designMode=False, **kwds): QWidget.__init__(self, parent, **kwds) NicosWidget.__init__(self) self._last_mtime = None self.namelabel = QLabel(self) self.namelabel.setAlignment(Qt.AlignHCenter) self.piclabel = QLabel(self) self.piclabel.setScaledContents(True) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.piclabel, 1) self.setLayout(layout) def registerKeys(self): pass def setPicture(self): size = QSize(self.props['width'] * self._scale, self.props['height'] * self._scale) if isfile(self._filePath): pixmap = QPixmap(self._filePath) else: pixmap = QPixmap(size) pixmap.fill() if size.isEmpty(): self.piclabel.setPixmap(pixmap) else: self.piclabel.setPixmap(pixmap.scaled(size)) self.piclabel.resize(self.piclabel.sizeHint()) def updatePicture(self): if not isfile(self._filePath): return # on first iteration self._last_mtime is None -> always setPicture() mtime = getmtime(self._filePath) if self._last_mtime != mtime: self._last_mtime = mtime self.setPicture() def propertyUpdated(self, pname, value): NicosWidget.propertyUpdated(self, pname, value) if pname == 'filepath': self._filePath = findResource(value) self.setPicture() elif pname == 'name': layout = QVBoxLayout() if value: layout.addWidget(self.namelabel) layout.addSpacing(5) layout.addWidget(self.piclabel, 1) sip.delete(self.layout()) self.setLayout(layout) self.namelabel.setText(value) elif pname in ('width', 'height'): self.setPicture() elif pname == 'refresh': if value: self._refreshTimer = QTimer() self._refreshTimer.setInterval(value * 1000) self._refreshTimer.timeout.connect(self.updatePicture) self._refreshTimer.start()
class MainWindow(DefaultMainWindow): ui = '%s/main.ui' % uipath def __init__(self, log, gui_conf, viewonly=False, tunnel=''): DefaultMainWindow.__init__(self, log, gui_conf, viewonly, tunnel) self.add_logo() self.set_icons() self.style_file = gui_conf.stylefile # Cheeseburger menu dropdown = QMenu('') dropdown.addAction(self.actionConnect) dropdown.addAction(self.actionViewOnly) dropdown.addAction(self.actionPreferences) dropdown.addAction(self.actionExpert) dropdown.addSeparator() dropdown.addAction(self.actionExit) self.actionUser.setMenu(dropdown) self.actionUser.setIconVisibleInMenu(True) self.dropdown = dropdown self.actionExpert.setEnabled(self.client.isconnected) self.actionEmergencyStop.setEnabled(self.client.isconnected) self._init_instrument_name() self._init_experiment_name() def _init_toolbar(self): self.statusLabel = QLabel('', self, pixmap=QPixmap(':/disconnected'), margin=5, minimumSize=QSize(30, 10)) self.statusLabel.setStyleSheet('color: white') self.toolbar = self.toolBarRight self.toolbar.addWidget(self.statusLabel) self.setStatus('disconnected') def _init_experiment_name(self): self.experiment_text = QLabel() self.experiment_text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.experiment_text.setStyleSheet( 'font-size: 17pt; font-weight: bold') self.toolBarMain.addWidget(self.experiment_text) self.experiment_label = QLabel() self.experiment_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.experiment_label.setStyleSheet('font-size: 17pt') self.toolBarMain.addWidget(self.experiment_label) def _init_instrument_name(self): self.instrument_text = QLabel() self.instrument_text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.instrument_text.setStyleSheet( 'font-size: 17pt; font-weight: bold') self.toolBarMain.addWidget(self.instrument_text) self.instrument_label = QLabel() self.instrument_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.instrument_label.setStyleSheet('font-size: 17pt') self.toolBarMain.addWidget(self.instrument_label) def set_icons(self): self.actionUser.setIcon(get_icon('settings_applications-24px.svg')) self.actionEmergencyStop.setIcon( get_icon('emergency_stop_cross-24px.svg')) self.actionConnect.setIcon(get_icon('power-24px.svg')) self.actionExit.setIcon(get_icon('exit_to_app-24px.svg')) self.actionViewOnly.setIcon(get_icon('lock-24px.svg')) self.actionPreferences.setIcon(get_icon('tune-24px.svg')) self.actionExpert.setIcon(get_icon('fingerprint-24px.svg')) def add_logo(self): logo_label = QLabel() pxr = decolor_logo( QPixmap(path.join(root_path, 'resources', 'logo-icon.png')), Qt.white) logo_label.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) logo_label.setMargin(5) self.toolBarMain.insertWidget(self.toolBarMain.actions()[0], logo_label) nicos_label = QLabel() pxr = decolor_logo( QPixmap(path.join(root_path, 'resources', 'nicos-logo-high.svg')), Qt.white) nicos_label.setPixmap( pxr.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) self.toolBarMain.insertWidget(self.toolBarMain.actions()[1], nicos_label) def update_instrument_text(self): instrument = self.client.eval('session.instrument', None) self.instrument_text.setText('Instrument:') if instrument: logo = decolor_logo( QPixmap( path.join(root_path, 'resources', f'{instrument}-logo.svg')), Qt.white) if logo.isNull(): self.instrument_label.setText(instrument.upper()) return self.instrument_label.setPixmap( logo.scaledToHeight(self.toolBarMain.height(), Qt.SmoothTransformation)) else: self.instrument_label.setText('UNKNOWN') def update_experiment_text(self): max_text_length = 50 experiment = self.client.eval('session.experiment.title', None) if experiment is not None: self.experiment_text.setText(" Experiment:") self.experiment_label.setText(experiment[0:max_text_length]) def remove_experiment_and_instrument(self): self.experiment_label.clear() self.experiment_text.clear() self.instrument_label.clear() self.instrument_text.clear() def reloadQSS(self): self.setQSS(self.stylefile) def selectQSS(self): style_file = QFileDialog.getOpenFileName( self, filter="Qt Stylesheet Files (*.qss)")[0] if style_file: self.style_file = style_file self.setQSS(self.style_file) @staticmethod def setQSS(style_file): with open(style_file, 'r', encoding='utf-8') as fd: try: QApplication.instance().setStyleSheet(fd.read()) except Exception as e: print(e) def setStatus(self, status, exception=False): if status == self.current_status: return if self.client.last_action_at and \ self.current_status == 'running' and \ status in ('idle', 'paused') and \ current_time() - self.client.last_action_at > 20: # show a visual indication of what happened if status == 'paused': msg = 'Script is now paused.' elif exception: msg = 'Script has exited with an error.' else: msg = 'Script has finished.' self.trayIcon.showMessage(self.instrument, msg) self.client.last_action_at = 0 self.current_status = status is_connected = status != 'disconnected' if is_connected: self.actionConnect.setText('Disconnect') self.statusLabel.setText('\u2713 Connected') self.update_instrument_text() self.update_experiment_text() else: self.actionConnect.setText('Connect to server...') self.statusLabel.setText('Disconnected') self.setTitlebar(False) # new status icon pixmap = QPixmap(':/' + status + ('exc' if exception else '')) new_icon = QIcon() new_icon.addPixmap(pixmap, QIcon.Disabled) self.trayIcon.setIcon(new_icon) self.trayIcon.setToolTip('%s status: %s' % (self.instrument, status)) if self.showtrayicon: self.trayIcon.show() if self.promptWindow and status != 'paused': self.promptWindow.close() # propagate to panels for panel in self.panels: panel.updateStatus(status, exception) for window in self.windows.values(): for panel in window.panels: panel.updateStatus(status, exception) def on_client_connected(self): DefaultMainWindow.on_client_connected(self) self.actionConnect.setIcon(get_icon("power_off-24px.svg")) self.actionExpert.setEnabled(True) self.actionEmergencyStop.setEnabled(not self.client.viewonly) def on_client_disconnected(self): DefaultMainWindow.on_client_disconnected(self) self.remove_experiment_and_instrument() self.actionConnect.setIcon(get_icon("power-24px.svg")) self.actionExpert.setEnabled(False) self.actionExpert.setChecked(False) self.actionEmergencyStop.setEnabled(False) def on_actionViewOnly_toggled(self, on): DefaultMainWindow.on_actionViewOnly_toggled(self, on) if self.client.isconnected: self.actionEmergencyStop.setEnabled(not self.client.viewonly) else: self.actionEmergencyStop.setEnabled(False) @pyqtSlot(bool) def on_actionConnect_triggered(self, _): # connection or disconnection request? connection_req = self.current_status == "disconnected" super().on_actionConnect_triggered(connection_req) @pyqtSlot() def on_actionUser_triggered(self): w = self.toolBarRight.widgetForAction(self.actionUser) self.dropdown.popup(w.mapToGlobal(QPoint(0, w.height()))) @pyqtSlot() def on_actionEmergencyStop_triggered(self): self.client.tell_action('emergency')