def closeEvent(self, event): if self.confirmexit and QMessageBox.question( self, 'Quit', 'Do you really want to quit?', QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: event.ignore() return for panel in self.panels: if not panel.requestClose(): event.ignore() return if self.autosavelayout: self.saveWindowLayout() with self.sgroup as settings: self.saveSettings(settings) for panel in self.panels: with panel.sgroup as settings: panel.saveSettings(settings) for window in list(self.windows.values()): if not window.close(): event.ignore() return if self.helpWindow: self.helpWindow.close() if self.client.isconnected: self.on_actionConnect_triggered(False) event.accept() QApplication.instance().quit()
def _handle_table_paste(self): indices = [] for index in self.tableView.selectedIndexes(): indices.append((index.row(), index.column())) if not indices: return top_left = indices[0] data_type = QApplication.instance().clipboard().mimeData() if not data_type.hasText(): # Don't paste images etc. return clipboard_text = QApplication.instance().clipboard().text() copied_table = extract_table_from_clipboard_text(clipboard_text) if len(copied_table) == 1 and len(copied_table[0]) == 1: # Only one value, so put it in all selected cells self._do_bulk_update(copied_table[0][0]) return self.model.update_data_from_clipboard( copied_table, top_left, self._get_hidden_column_indices())
def doInit(self, mode): CICacheClient.doInit(self, self._mode) self._qtapp = QApplication(sys.argv) self._qtapp.setOrganizationName('nicos') self._qtapp.setApplicationName('cacheinspector') self._window = MainWindow(self) self._window.setWindowIcon(QIcon(':/inspector')) session._qthandler.setStatusbar(self._window.statusBar())
def doInit(self, mode): self._qtapp = QApplication(sys.argv) self._qtapp.setOrganizationName('nicos') self._qtapp.setApplicationName('history') self._window = StandaloneHistoryWindow(self) # if no cache was given on the command line... if not self._config['cache']: dlg = SettingsDialog(self._window) dlg.exec_() self._setROParam('cache', dlg.cacheBox.currentText()) self._setROParam('prefix', dlg.prefixEdit.text()) CacheClient.doInit(self, mode)
def waitCursor(): """Context manager creating an hour glass style cursor for longer-running blocking tasks inside GUI code. Example:: with waitCursor(): # process takes some time pass """ try: QApplication.setOverrideCursor(Qt.WaitCursor) yield finally: QApplication.restoreOverrideCursor()
def on_client_connected(self): # retrieve datasets and put them into the scans window pd = QProgressDialog(labelText='Transferring datasets, please wait...') pd.setRange(0, 1) pd.setCancelButton(None) pd.show() QApplication.processEvents() datasets = self.client.ask('getdataset', '*', default=[]) self.bulk_adding = True for dataset in (datasets or []): try: self.on_client_dataset(dataset) except Exception: from nicos.clients.gui.main import log log.error('Error adding dataset', exc=1) self.bulk_adding = False pd.setValue(1) pd.close()
def event(self, event): if self._reconfiguring and event.type() == 76: # LayoutRequest self._reconfiguring = False # always resize first; works around layout bugs where the full # screen window is actually made larger than the full screen self.resize(self.sizeHint()) if self._wantFullScreen: self.setGeometry(QApplication.screens()[0].geometry()) return QMainWindow.event(self, event)
def on_roiItemClicked(self, event): if event.getButtons() & MouseEvent.RIGHT_BUTTON: if isinstance(event.roi.reference, FitResult): menu = QMenu(self) actionClipboard = QAction("Copy fit values to clipboard", menu) menu.addAction(actionClipboard) p0dc = event.getDC() selectedItem = menu.exec_( self.mapToGlobal(QPoint(p0dc.x, p0dc.y))) if selectedItem == actionClipboard: res = event.roi.reference text = '\n'.join( (n + '\t' if n else '\t') + (v + '\t' if isinstance(v, string_types) else '%g\t' % v) + (dv if isinstance(dv, string_types) else '%g' % dv) for (n, v, dv) in res.label_contents) QApplication.clipboard().setText(text)
class StandaloneHistoryApp(CacheClient): parameters = { 'views': Param('Strings specifying views (from command line)', type=listof(str)), } def doInit(self, mode): self._qtapp = QApplication(sys.argv) self._qtapp.setOrganizationName('nicos') self._qtapp.setApplicationName('history') self._window = StandaloneHistoryWindow(self) # if no cache was given on the command line... if not self._config['cache']: dlg = SettingsDialog(self._window) dlg.exec_() self._setROParam('cache', dlg.cacheBox.currentText()) self._setROParam('prefix', dlg.prefixEdit.text()) CacheClient.doInit(self, mode) def getDeviceList(self, only_explicit=True, special_clause=None): devlist = [ key[:-6] for (key, _) in self.query_db('') if key.endswith('/value') ] if special_clause: devlist = [ dn for dn in devlist if eval(special_clause, {'dn': dn}) ] return sorted(devlist) def getDeviceParam(self, devname, parname): return self.get(devname, parname) def getDeviceParams(self, devname): ldevname = devname.lower() index = len(ldevname) + 1 return { key[index:]: value for (key, value) in self.query_db('') if key.startswith(ldevname + '/') } def getDeviceParamInfo(self, _): return {} # we can't deliver this info from the cache alone def start(self): self._startup_done.wait(2) self._window.openViews(self.views) self._window.show() try: self._qtapp.exec_() except KeyboardInterrupt: pass self._stoprequest = True def _propagate(self, data): self._window.newValue.emit(data)
def mouseMoveEvent(self, event): if not (event.buttons() & Qt.LeftButton): return if not self._dragStartPos.isNull() and \ self.tabAt(self._dragStartPos) != -1 and \ (event.pos() - self._dragStartPos).manhattanLength() \ < QApplication.startDragDistance(): self._dragInitiated = True if (event.buttons() == Qt.LeftButton) and self._dragInitiated and \ not self.geometry().contains(event.pos()): finishMoveEvent = QMouseEvent(QEvent.MouseMove, event.pos(), Qt.NoButton, Qt.NoButton, Qt.NoModifier) QTabBar.mouseMoveEvent(self, finishMoveEvent) drag = QDrag(self) mimedata = QMimeData() mimedata.setData('action', b'application/tab-detach') drag.setMimeData(mimedata) if QT_VER == 4: pixmap = QPixmap.grabWidget(self.parentWidget().currentWidget()) else: pixmap = self.parentWidget().currentWidget().grab() pixmap = pixmap.scaled(640, 480, Qt.KeepAspectRatio) drag.setPixmap(pixmap) drag.setDragCursor(QPixmap(), Qt.LinkAction) dragged = drag.exec_(Qt.MoveAction) if dragged == Qt.IgnoreAction: # moved outside of tab widget event.accept() self.tabDetached.emit(self.tabAt(self._dragStartPos), QCursor.pos()) elif dragged == Qt.MoveAction: # moved inside of tab widget if not self._dragDroppedPos.isNull(): event.accept() self.tabMoved.emit(self.tabAt(self._dragStartPos), self.tabAt(self._dragDroppedPos)) self._dragDroppedPos = QPoint() else: QTabBar.mouseMoveEvent(self, event)
class CacheInspector(CICacheClient): def doInit(self, mode): CICacheClient.doInit(self, self._mode) self._qtapp = QApplication(sys.argv) self._qtapp.setOrganizationName('nicos') self._qtapp.setApplicationName('cacheinspector') self._window = MainWindow(self) self._window.setWindowIcon(QIcon(':/inspector')) session._qthandler.setStatusbar(self._window.statusBar()) def start(self): self._window.show() if self.cache: self.connect(self.cache) try: self._qtapp.exec_() except KeyboardInterrupt: pass self._stoprequest = True
def copy(): QApplication.clipboard().setText(tb+'\n', QClipboard.Selection) QApplication.clipboard().setText(tb+'\n', QClipboard.Clipboard)
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 main(argv): global log # pylint: disable=global-statement userpath = path.join(path.expanduser('~'), '.config', 'nicos') # Set up logging for the GUI instance. initLoggers() log = NicosLogger('gui') log.parent = None log.setLevel(logging.INFO) log.addHandler(ColoredConsoleHandler()) log.addHandler( NicosLogfileHandler(path.join(userpath, 'log'), 'gui', use_subdir=False)) # set up logging for unhandled exceptions in Qt callbacks def log_unhandled(*exc_info): traceback.print_exception(*exc_info) log.exception('unhandled exception in QT callback', exc_info=exc_info) sys.excepthook = log_unhandled app = QApplication(argv, organizationName='nicos', applicationName='gui') opts = parseargs() if opts.configfile is None: try: config.apply() except RuntimeError: pass # If "demo" is detected automatically, let the user choose their # instrument configuration. need_dialog = config.instrument is None or \ (config.setup_package == 'nicos_demo' and config.instrument == 'demo' and 'INSTRUMENT' not in os.environ) if need_dialog: opts.configfile = InstrSelectDialog.select( 'Your instrument could not be automatically detected.') if opts.configfile is None: return else: opts.configfile = path.join(config.setup_package_path, config.instrument, 'guiconfig.py') with open(opts.configfile, 'rb') as fp: configcode = fp.read() gui_conf = processGuiConfig(configcode) gui_conf.stylefile = '' if gui_conf.options.get('facility') in ['ess', 'sinq']: gui_conf.stylefile = f"{config.nicos_root}" \ f"/nicos/clients/flowui/guiconfig.qss" stylefiles = [ path.join(userpath, 'style-%s.qss' % sys.platform), path.join(userpath, 'style.qss'), path.splitext(opts.configfile)[0] + '-%s.qss' % sys.platform, path.splitext(opts.configfile)[0] + '.qss', ] for stylefile in [gui_conf.stylefile] or stylefiles: if path.isfile(stylefile): try: with open(stylefile, 'r', encoding='utf-8') as fd: app.setStyleSheet(fd.read()) gui_conf.stylefile = stylefile break except Exception: log.warning('Error setting user style sheet from %s', stylefile, exc=1) mainwindow_cls = _mainwindow_cls.get( gui_conf.options.get('facility', 'default')) mainwindow = mainwindow_cls(log, gui_conf, opts.viewonly, opts.tunnel) log.addHandler(DebugHandler(mainwindow)) if opts.connect: parsed = parseConnectionString(opts.connect, DEFAULT_PORT) if parsed: cdata = ConnectionData(**parsed) cdata.viewonly = opts.viewonly mainwindow.setConnData(cdata) if cdata.password is not None: # we have a password, connect right away mainwindow.client.connect(mainwindow.conndata) else: # we need to ask for password, override last preset (uses given # connection data) and force showing connect window mainwindow.lastpreset = '' mainwindow.autoconnect = True mainwindow.startup() return app.exec_()
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()
def wait_cursor(): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) yield finally: QApplication.restoreOverrideCursor()
def setQSS(self, stylefile): with open(stylefile, 'r') as fd: try: QApplication.instance().setStyleSheet(fd.read()) except Exception as e: print(e)
return self._setStart(v) elif index == self._SPLIT_END: _lockWidth(self._head) if v <= self.start(): return self._setEnd(v) _unlockWidth(self._tail) _unlockWidth(self._head) _unlockWidth(self._handle) #------------------------------------------------------------------------------- # MAIN #------------------------------------------------------------------------------- if __name__ == '__main__': app = QApplication(sys.argv) rs = QRangeSlider() rs.show() rs.setRange(15, 35) rs.setBackgroundStyle( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);' ) rs.handle.setStyleSheet( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);' ) app.exec_()
def keyPressEvent(self, kev): key_code = kev.key() # if it's a shifted scroll key... if kev.modifiers() & Qt.ShiftModifier and \ self.scrollWidget and \ key_code in self.scrollingKeys: # create a new, unshifted key event and send it to the # scrolling widget nev = QKeyEvent(kev.type(), kev.key(), Qt.NoModifier) QApplication.sendEvent(self.scrollWidget, nev) return if key_code == Qt.Key_Escape: # abort history search self.setText(self._start_text) self._current = -1 self.escapePressed.emit() QLineEdit.keyPressEvent(self, kev) elif key_code == Qt.Key_Up: # go earlier if self._current == -1: self._start_text = self.text() self._current = len(self.history) self.stepHistory(-1) elif key_code == Qt.Key_Down: # go later if self._current == -1: return self.stepHistory(1) elif key_code == Qt.Key_PageUp: # go earlier with prefix if self._current == -1: self._current = len(self.history) self._start_text = self.text() prefix = self.text()[:self.cursorPosition()] self.stepHistoryUntil(prefix, 'up') elif key_code == Qt.Key_PageDown: # go later with prefix if self._current == -1: return prefix = self.text()[:self.cursorPosition()] self.stepHistoryUntil(prefix, 'down') elif key_code == Qt.Key_Return or key_code == Qt.Key_Enter: # accept - add to history and do normal processing self._current = -1 text = self.text() if text and (not self.history or self.history[-1] != text): # append to history, but only if it isn't equal to the last self.history.append(text) self._completer.setCompletionPrefix('') self._completer.setModel(QStringListModel([], self)) QLineEdit.keyPressEvent(self, kev) else: # process normally QLineEdit.keyPressEvent(self, kev)
def _handle_copy_cells(self): selected_data = self._extract_selected_data() clipboard_text = convert_table_to_clipboard_text(selected_data) QApplication.instance().clipboard().setText(clipboard_text)
def on_runBtn_clicked(self): # Make sure we add the command to the history. event = QKeyEvent(QKeyEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier) QApplication.postEvent(self.commandInput, event)
def main(): app = QApplication(sys.argv) myWindow = MainWindow() myWindow.resize(800, 600) myWindow.show() sys.exit(app.exec_())