def __init__(self, parent=None, statusbar=None): super(StatusBarOverlay, self).__init__(parent) self.statusbar = statusbar print(parent.__class__.__name__) layout = QVBoxLayout() line = QHBoxLayout() self.graphicsButton = QPushButton('Graphics') self.logButton = QPushButton('Log') self.toggleButton = QPushButton('Show') self.graphicsButton.setCheckable(True) self.logButton.setCheckable(True) self.toggleButton.setCheckable(True) self.buttonsBox = QButtonGroup() self.buttonsBox.addButton(self.graphicsButton) self.buttonsBox.addButton(self.logButton) # self.buttonsBox.addButton(self.toggleButton) line.addStretch() line.addWidget(self.graphicsButton) line.addWidget(self.logButton) line.addWidget(self.toggleButton) line.addStretch() line.setObjectName('ButtonsLayout') layout.addLayout(line) del line line = QHBoxLayout() layout.addLayout(line) self.setLayout(layout) self.toggleButton.clicked.connect(self.on_toggle) self.set_hidden()
class BaseDev(QWidget): base_address = 0 has_target = False has_status = False offset = 1 def __init__(self, model, name, index, addr, has_status=False, target=None, value_offset=1): QWidget.__init__(self) self.index = index self.name = name self.model = model self.offset = value_offset self.has_status = has_status self.has_target = target is not None self.base_address = addr self._namelabel = QLabel(name) self._namelabel.setMinimumWidth(120) self._namelabel.setMaximumWidth(120) # self._groupbox = QGroupBox(name) self._groupbox = QFrame() # self._groupbox.setFlat(False) # self._groupbox.setCheckable(False) self._hlayout = QHBoxLayout() self._hlayout.addWidget(self._namelabel) self._hlayout.addWidget(self._groupbox) self._hlayout.setSpacing(0) # inside of the groupbox there is a vbox with 1 or 2 hboxes self._inner_vbox = QVBoxLayout() self._groupbox.setLayout(self._inner_vbox) # upper inner hbox self._inner_hbox1 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox1) # fill upper hbox self.valueWidget = QLineEdit('0b123456789abcdef0') self.valueWidget.setMaximumWidth(120) self._inner_hbox1.addWidget(self.valueWidget) if self.has_target: self.targetWidget = QLineEdit() self.targetWidget.setPlaceholderText(target) self.targetWidget.setMaximumWidth(120) self.targetWidget.returnPressed.connect(lambda *a: model.targeter( index, (self.targetWidget.text(), self.targetWidget.setText(''))[0])) self._inner_hbox1.addWidget(self.targetWidget) self.goButton = QPushButton('Go') self.goButton.clicked.connect(lambda *a: model.targeter( index, (self.targetWidget.text(), self.targetWidget.setText(''))[0])) self._inner_hbox1.addWidget(self.goButton) self.stopButton = QPushButton('Stop') self.stopButton.clicked.connect(lambda *a: model.stopper(index)) self._inner_hbox1.addWidget(self.stopButton) # now (conditionally) the second hbox if has_status: self._inner_hbox2 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox2) self.statvalueWidget = QLineEdit('statval') self.statvalueWidget.setMaximumWidth(120) self._inner_hbox2.addWidget(self.statvalueWidget) self.statusWidget = QLineEdit('Statusstring if available') self.statusWidget.setMaximumWidth(10000) self._inner_hbox2.addWidget(self.statusWidget) self.resetButton = QPushButton('Reset') self.resetButton.clicked.connect(lambda *a: model.resetter(index)) self._inner_hbox1.addWidget(self.resetButton) # self._inner_hbox2.addStretch(0.1) # allow space for resizing self._inner_hbox1.addStretch(1) self._inner_vbox.setSpacing(0) self._inner_vbox.setContentsMargins(0, 0, 0, 0) self._hlayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._hlayout) self.show()
class BaseDev(QWidget): has_target = False has_status = False def __init__(self, model, name, addr): super(BaseDev, self).__init__() self.name = name self.model = model self.addr = addr self._namelabel = QLabel(name) self._namelabel.setMinimumWidth(120) self._namelabel.setMaximumWidth(120) # self._groupbox = QGroupBox(name) self._groupbox = QFrame() # self._groupbox.setFlat(False) # self._groupbox.setCheckable(False) self._hlayout = QHBoxLayout() self._hlayout.addWidget(self._namelabel) self._hlayout.addWidget(self._groupbox) self._hlayout.setSpacing(0) # inside of the groupbox there is a vbox with 1 or 2 hboxes self._inner_vbox = QVBoxLayout() self._groupbox.setLayout(self._inner_vbox) # upper inner hbox self._inner_hbox1 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox1) # fill upper hbox self.valueWidget = QLineEdit('0b123456789abcdef0') self.valueWidget.setMaximumWidth(120) self._inner_hbox1.addWidget(self.valueWidget) if self.has_target: self.targetWidget = QLineEdit() self.targetWidget.setPlaceholderText('') self.targetWidget.setMaximumWidth(120) self.targetWidget.returnPressed.connect(self._go_clicked) self._inner_hbox1.addWidget(self.targetWidget) self.goButton = QPushButton('Go') self.goButton.clicked.connect(self._go_clicked) self._inner_hbox1.addWidget(self.goButton) self.stopButton = QPushButton('Stop') self.stopButton.clicked.connect(self._stop_clicked) self._inner_hbox1.addWidget(self.stopButton) # now (conditionally) the second hbox if self.has_status: self._inner_hbox2 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox2) self.statvalueWidget = QLineEdit('statval') self.statvalueWidget.setMaximumWidth(120) self._inner_hbox2.addWidget(self.statvalueWidget) self.statusWidget = QLineEdit('Statusstring if available') self.statusWidget.setMaximumWidth(10000) self._inner_hbox2.addWidget(self.statusWidget) self.resetButton = QPushButton('Reset') self.resetButton.clicked.connect(self._reset_clicked) self._inner_hbox1.addWidget(self.resetButton) # self._inner_hbox2.addStretch(0.1) # allow space for resizing self._inner_hbox1.addStretch(1) self._inner_vbox.setSpacing(0) self._inner_vbox.setContentsMargins(0, 0, 0, 0) self._hlayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._hlayout) self.show() def _go_clicked(self): self.model.targeter(self.index, self.targetWidget.text()) self.targetWidget.setText('') def _stop_clicked(self): self.model.stopper(self.index) def _reset_clicked(self): self.resetter(self.index) def _update(self): pass def _str2bin(self, value): return int(value) def _bin2str(self, value): return str(value) def _status(self, value): return "no status decoder implemented"
def initGui(self): def log_unhandled(*exc_info): traceback.print_exception(*exc_info) self.log.exception('unhandled exception in QT callback', exc_info=exc_info) sys.excepthook = log_unhandled self._qtapp = QApplication(['qtapp'], organizationName='nicos', applicationName='gui') self._master = master = MonitorWindow() if self._geometry == 'fullscreen': master.showFullScreen() master._wantFullScreen = True # In some Qt5 versions, showFullScreen is buggy and doesn't # actually resize the window (but hides decoration etc). # So, explicitly set the geometry of the first screen. master.setGeometry(QApplication.screens()[0].geometry()) QCursor.setPos(master.geometry().bottomRight()) elif isinstance(self._geometry, tuple): w, h, x, y = self._geometry master.setGeometry(x, y, w, h) # colors used for the display of watchdog warnings, not for the # individual value displays self._bgcolor = QColor('gray') self._black = QColor('black') self._red = QColor('red') self._gray = QColor('gray') master.setWindowTitle(self.title) self._bgcolor = master.palette().color(QPalette.Window) timefont = QFont(self.font, self._timefontsize) blockfont = QFont(self.font, self._fontsizebig) warnfont = QFont(self.font, self._fontsizebig) warnfont.setBold(True) labelfont = QFont(self.font, self._fontsize) stbarfont = QFont(self.font, int(self._fontsize * 0.8)) valuefont = QFont(self.valuefont or self.font, self._fontsize) blheight = QFontMetrics(blockfont).height() tiheight = QFontMetrics(timefont).height() # split window into to panels/frames below each other: # one displays time, the other is divided further to display blocks. # first the timeframe: masterframe = QFrame(master) masterlayout = QVBoxLayout() if self.title: self._titlelabel = QLabel( '', master, font=timefont, autoFillBackground=True, alignment=Qt.AlignHCenter) pal = self._titlelabel.palette() pal.setColor(QPalette.WindowText, self._gray) self._titlelabel.setPalette(pal) self._titlelabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self._master.updateTitle.connect(self._titlelabel.setText) masterlayout.addWidget(self._titlelabel) masterlayout.addSpacing(0.2 * tiheight) else: self._titlelabel = None self._warnpanel = QFrame(master) self._warnpanel.setVisible(False) warningslayout = QVBoxLayout() lbl = QLabel('Warnings', self._warnpanel, font=warnfont) lbl.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) warningslayout.addWidget(lbl) self._warnlabel = SqueezedLabel('', self._warnpanel, font=blockfont) warningslayout.addWidget(self._warnlabel) self._warnpanel.setLayout(warningslayout) masterlayout.addWidget(self._warnpanel) master.switchWarnPanel.connect(self._switch_warnpanel) displayframe = QFrame(master) self._plots = {} colorScheme = lightColorScheme if self.colors == 'light' else None fontCache = {1.0: valuefont} def _create_field(groupframe, field): def _setup(widget): fontscale = field.get('fontscale', 1.0) if fontscale not in fontCache: fontCache[fontscale] = scaledFont(valuefont, fontscale) widget.valueFont = fontCache[fontscale] widget.setFont(labelfont) for key in field: if key in widget.properties: setattr(widget, key, field[key]) widget.setSource(self) if hasattr(widget, 'widgetInfo'): widget.widgetInfo.connect(self.newWidgetInfo) return widget if isinstance(field, str): field = {'dev': field} if 'min' in field: field['min'] = repr(field['min']) if 'max' in field: field['max'] = repr(field['max']) setups = field.get('setups', None) if 'gui' in field: resource = findResource(field.pop('gui')) try: instance = uic.loadUi(resource) except Exception as err: self.log.exception('could not load .ui file %r, ignoring', resource) instance = QLabel('%r could not be loaded:\n%s' % (resource, err)) else: for child in instance.findChildren(NicosWidget): _setup(child) instance.setups = setups return instance elif 'widget' in field: widget_class = self._class_import(field.pop('widget')) widget = widget_class(groupframe) if isinstance(widget, NicosWidget): _setup(widget) for child in widget.findChildren(NicosWidget): _setup(child) widget.setups = setups return widget elif 'plot' in field and plot_available: # XXX make this more standard plotwidget = self._plots.get(field['plot']) if plotwidget: plotwidget.devices += [field.get('dev', field.get('key', ''))] plotwidget.names += [field.get('name', field.get('dev', field.get('key', '')))] return None plotwidget = TrendPlot(groupframe) _setup(plotwidget) plotwidget.legend = field.get('legend', True) plotwidget.plotwindow = field.get('plotwindow', 3600) plotwidget.plotinterval = field.get('plotinterval', 2) self._plots[field['plot']] = plotwidget plotwidget.devices = [field.get('dev', field.get('key', ''))] plotwidget.names = [field.get('name', field.get('dev', field.get('key', '')))] plotwidget.setups = setups return plotwidget elif 'picture' in field: picwidget = PictureDisplay(groupframe) picwidget.filepath = field['picture'] picwidget.setups = setups return _setup(picwidget) else: display = ValueDisplay(groupframe, colorScheme=colorScheme, showExpiration=self.noexpired) display.setups = setups return _setup(display) # now iterate through the layout and create the widgets to display it displaylayout = QVBoxLayout(spacing=20) for superrow in self.layout: boxlayout = QHBoxLayout(spacing=20) boxlayout.setContentsMargins(10, 10, 10, 10) for column in superrow: columnlayout = QVBoxLayout(spacing=0.8*blheight) for block in column: block = self._resolve_block(block) blocklayout_outer = QHBoxLayout() blocklayout_outer.addStretch() blocklayout = QVBoxLayout() blocklayout.addSpacing(0.5 * blheight) blockbox = BlockBox(displayframe, block._title, blockfont, block._options) for row in block: if row in (None, '---'): blocklayout.addSpacing(12) else: rowlayout = QHBoxLayout() rowlayout.addStretch() rowlayout.addSpacing(self._padding) for field in row: fieldwidget = _create_field(blockbox, field) if fieldwidget: rowlayout.addWidget(fieldwidget) rowlayout.addSpacing(self._padding) if fieldwidget.setups: if blockbox.setups: blockbox._onlyfields.append(fieldwidget) else: self._onlyfields.append(fieldwidget) # start hidden fieldwidget.setHidden(True) rowlayout.addStretch() blocklayout.addLayout(rowlayout) if blockbox.setups: self._onlyblocks.append((blocklayout_outer, blockbox)) blockbox.setHidden(True) # start hidden blocklayout.addSpacing(0.3 * blheight) blockbox.setLayout(blocklayout) blocklayout_outer.addWidget(blockbox) blocklayout_outer.addStretch() columnlayout.addLayout(blocklayout_outer) columnlayout.addStretch() boxlayout.addLayout(columnlayout) displaylayout.addLayout(boxlayout) displayframe.setLayout(displaylayout) for plot in self._plots.values(): plot.setSource(self) masterlayout.addWidget(displayframe) masterframe.setLayout(masterlayout) master.setCentralWidget(masterframe) # initialize status bar self._statuslabel = QLabel(font=stbarfont) master.statusBar().addWidget(self._statuslabel) self._statustimer = None master.show()