def __init__(self, datasets_sub, dataset_ctl): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) self.dataset_ctl = dataset_ctl grid = LayoutWidget() self.setWidget(grid) self.search = QtWidgets.QLineEdit() self.search.setPlaceholderText("search...") self.search.editingFinished.connect(self._search_datasets) grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.table.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) grid.addWidget(self.table, 1, 0) self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) delete_action = QtWidgets.QAction("Delete dataset", self.table) delete_action.triggered.connect(self.delete_clicked) delete_action.setShortcut("DELETE") delete_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.table.addAction(delete_action) self.table_model = Model(dict()) datasets_sub.add_setmodel_callback(self.set_model)
def __init__(self): LayoutWidget.__init__(self) self.waiting_spinner = QtWaitingSpinner() self.addWidget(self.waiting_spinner, 1, 1) self.addWidget(QtWidgets.QLabel("Repository scan in progress..."), 1, 2)
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] self.value = QtWidgets.QDoubleSpinBox() disable_scroll_wheel(self.value) self.value.setDecimals(procdesc["ndecimals"]) if procdesc["global_min"] is not None: self.value.setMinimum(procdesc["global_min"]/scale) else: self.value.setMinimum(float("-inf")) if procdesc["global_max"] is not None: self.value.setMaximum(procdesc["global_max"]/scale) else: self.value.setMaximum(float("inf")) self.value.setSingleStep(procdesc["global_step"]/scale) if procdesc["unit"]: self.value.setSuffix(" " + procdesc["unit"]) self.addWidget(QtWidgets.QLabel("Value:"), 0, 0) self.addWidget(self.value, 0, 1) self.value.setValue(state["value"]/scale) def update(value): state["value"] = value*scale self.value.valueChanged.connect(update)
def __init__(self, argument): LayoutWidget.__init__(self) self.argument = argument self.stack = QtWidgets.QStackedWidget() self.addWidget(self.stack, 1, 0, colspan=4) procdesc = argument["desc"] state = argument["state"] self.widgets = OrderedDict() self.widgets["NoScan"] = _NoScan(procdesc, state["NoScan"]) self.widgets["RangeScan"] = _RangeScan(procdesc, state["RangeScan"]) self.widgets["CenterScan"] = _CenterScan(procdesc, state["CenterScan"]) self.widgets["ExplicitScan"] = _ExplicitScan(state["ExplicitScan"]) for widget in self.widgets.values(): self.stack.addWidget(widget) self.radiobuttons = OrderedDict() self.radiobuttons["NoScan"] = QtWidgets.QRadioButton("No scan") self.radiobuttons["RangeScan"] = QtWidgets.QRadioButton("Range") self.radiobuttons["CenterScan"] = QtWidgets.QRadioButton("Center") self.radiobuttons["ExplicitScan"] = QtWidgets.QRadioButton("Explicit") scan_type = QtWidgets.QButtonGroup() for n, b in enumerate(self.radiobuttons.values()): self.addWidget(b, 0, n) scan_type.addButton(b) b.toggled.connect(self._scan_type_toggled) selected = argument["state"]["selected"] self.radiobuttons[selected].setChecked(True)
def __init__(self, argument): LayoutWidget.__init__(self) self.argument = argument self.stack = QtWidgets.QStackedWidget() self.addWidget(self.stack, 1, 0, colspan=4) procdesc = argument["desc"] state = argument["state"] self.widgets = OrderedDict() self.widgets["NoScan"] = _NoScan(procdesc, state["NoScan"]) self.widgets["LinearScan"] = _RangeScan(procdesc, state["LinearScan"]) self.widgets["RandomScan"] = _RangeScan(procdesc, state["RandomScan"]) self.widgets["ExplicitScan"] = _ExplicitScan(state["ExplicitScan"]) for widget in self.widgets.values(): self.stack.addWidget(widget) self.radiobuttons = OrderedDict() self.radiobuttons["NoScan"] = QtWidgets.QRadioButton("No scan") self.radiobuttons["LinearScan"] = QtWidgets.QRadioButton("Linear") self.radiobuttons["RandomScan"] = QtWidgets.QRadioButton("Random") self.radiobuttons["ExplicitScan"] = QtWidgets.QRadioButton("Explicit") scan_type = QtWidgets.QButtonGroup() for n, b in enumerate(self.radiobuttons.values()): self.addWidget(b, 0, n) scan_type.addButton(b) b.toggled.connect(self._scan_type_toggled) selected = argument["state"]["selected"] self.radiobuttons[selected].setChecked(True)
def _make_add_override_prompt_item(self): self._override_prompt_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(self._override_prompt_item) # Layout to display button/prompt label, depending on which one is active. left = LayoutWidget() self._add_override_button = QtWidgets.QToolButton() self._add_override_button.setIcon(self._add_override_icon) self._add_override_button.clicked.connect( self._set_override_line_active) self._add_override_button.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_T) left.addWidget(self._add_override_button, 0, 0) self._add_override_prompt_label = QtWidgets.QLabel("Add parameter:") left.addWidget(self._add_override_prompt_label, 0, 0) left.layout.setColumnStretch(0, 0) left.layout.setColumnStretch(1, 1) self.setItemWidget(self._override_prompt_item, 0, left) prompt = LayoutWidget() self._add_override_prompt_box = FuzzySelectWidget([]) self._add_override_prompt_box.finished.connect( lambda a: self._make_override_item(*self._param_choice_map[a])) self._add_override_prompt_box.aborted.connect( self._set_override_line_idle) prompt.addWidget(self._add_override_prompt_box) self.setItemWidget(self._override_prompt_item, 1, prompt)
def __init__(self, state): LayoutWidget.__init__(self) self.value = QtWidgets.QLineEdit() self.addWidget(QtWidgets.QLabel("Sequence:"), 0, 0) self.addWidget(self.value, 0, 1) float_regexp = r"(([+-]?\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)" regexp = "(float)?( +float)* *".replace("float", float_regexp) self.value.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(regexp))) self.value.setText(" ".join([str(x) for x in state["sequence"]])) def update(text): if self.value.hasAcceptableInput(): state["sequence"] = [float(x) for x in text.split()] self.value.textEdited.connect(update)
def __init__(self, state): LayoutWidget.__init__(self) self.value = QtWidgets.QLineEdit() self.addWidget(QtWidgets.QLabel("Sequence:"), 0, 0) self.addWidget(self.value, 0, 1) float_regexp = "[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?" regexp = "(float)?( +float)* *".replace("float", float_regexp) self.value.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(regexp), self.value)) self.value.setText(" ".join([str(x) for x in state["sequence"]])) def update(text): state["sequence"] = [float(x) for x in text.split()] self.value.textEdited.connect(update)
async def _recompute_vanilla_argument(self, name): try: arginfo, _ = await self.manager.examine_arginfo(self.expurl) except Exception: logger.error( "Could not recompute argument '%s' of '%s'", name, self.expurl, exc_info=True) return argument = self.manager.get_submission_arguments(self.expurl)[name] procdesc = arginfo[name][0] state = procdesc_to_entry(procdesc).default_state(procdesc) argument["desc"] = procdesc argument["state"] = state widgets = self._arg_to_widgets[name] widgets["entry"].deleteLater() widgets["entry"] = procdesc_to_entry(procdesc)(argument) widgets["fix_layout"].deleteLater() widgets["fix_layout"] = LayoutWidget() widgets["fix_layout"].addWidget(widgets["entry"]) self.setItemWidget(widgets["widget_item"], 1, widgets["fix_layout"]) self.updateGeometries()
async def _recompute_argument(self, name): try: expdesc = await self.manager.compute_expdesc(self.expurl) except: logger.error("Could not recompute argument '%s' of '%s'", name, self.expurl, exc_info=True) return argument = self.manager.get_submission_arguments(self.expurl)[name] procdesc = expdesc["arginfo"][name][0] state = procdesc_to_entry(procdesc).default_state(procdesc) argument["desc"] = procdesc argument["state"] = state # Qt needs a setItemWidget() to handle layout correctly, # simply replacing the entry inside the LayoutWidget # results in a bug. widgets = self._arg_to_widgets[name] widgets["entry"].deleteLater() widgets["entry"] = procdesc_to_entry(procdesc)(argument) widgets["disable_other_scans"].setVisible( isinstance(widgets["entry"], ScanEntry)) widgets["fix_layout"].deleteLater() widgets["fix_layout"] = LayoutWidget() widgets["fix_layout"].addWidget(widgets["entry"]) self.setItemWidget(widgets["widget_item"], 1, widgets["fix_layout"]) self.updateGeometries()
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] self.value = ScientificSpinBox() disable_scroll_wheel(self.value) self.value.setDecimals(procdesc["ndecimals"]) self.value.setPrecision() if procdesc["global_min"] is not None: self.value.setMinimum(procdesc["global_min"] / scale) else: self.value.setMinimum(float("-inf")) if procdesc["global_max"] is not None: self.value.setMaximum(procdesc["global_max"] / scale) else: self.value.setMaximum(float("inf")) self.value.setSingleStep(procdesc["global_step"] / scale) self.value.setRelativeStep() if procdesc["unit"]: self.value.setSuffix(" " + procdesc["unit"]) self.addWidget(QtWidgets.QLabel("Value:"), 0, 0) self.addWidget(self.value, 0, 1) self.value.setValue(state["value"] / scale) def update(value): state["value"] = value * scale self.value.valueChanged.connect(update) self.repetitions = QtWidgets.QSpinBox() self.repetitions.setMinimum(1) self.repetitions.setMaximum((1 << 31) - 1) disable_scroll_wheel(self.repetitions) self.addWidget(QtWidgets.QLabel("Repetitions:"), 1, 0) self.addWidget(self.repetitions, 1, 1) self.repetitions.setValue(state["repetitions"]) def update_repetitions(value): state["repetitions"] = value self.repetitions.valueChanged.connect(update_repetitions)
def __init__(self, channel, send_to_device, force_out, title): self.channel = channel self.send_to_device = send_to_device self.force_out = force_out _MoninjWidget.__init__(self) grid = QtWidgets.QGridLayout() self.setLayout(grid) label = QtWidgets.QLabel(title) label.setAlignment(QtCore.Qt.AlignCenter) label.setWordWrap(True) grid.addWidget(label, 1, 1) self.stack = QtWidgets.QStackedWidget() grid.addWidget(self.stack, 2, 1) self.direction = QtWidgets.QLabel() self.direction.setAlignment(QtCore.Qt.AlignCenter) self.stack.addWidget(self.direction) grid_cb = LayoutWidget() self.override = QtWidgets.QCheckBox("Override") grid_cb.addWidget(self.override, 3, 1) self.level = QtWidgets.QCheckBox("Level") grid_cb.addWidget(self.level, 3, 2) self.stack.addWidget(grid_cb) self.value = QtWidgets.QLabel() self.value.setAlignment(QtCore.Qt.AlignCenter) grid.addWidget(self.value, 3, 1) grid.setRowStretch(1, 1) grid.setRowStretch(2, 0) grid.setRowStretch(3, 0) grid.setRowStretch(4, 1) self.programmatic_change = False self.override.stateChanged.connect(self.override_toggled) self.level.stateChanged.connect(self.level_toggled) self.set_value(0, False, False)
def __init__(self, datasets_sub): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) grid = LayoutWidget() self.setWidget(grid) self.search = QtWidgets.QLineEdit() self.search.setPlaceholderText("search...") self.search.editingFinished.connect(self._search_datasets) grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.table.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) grid.addWidget(self.table, 1, 0) self.table_model = Model(dict()) datasets_sub.add_setmodel_callback(self.set_model)
def __init__(self, channel, send_to_device, force_out, title): QtWidgets.QFrame.__init__(self) self.channel = channel self.send_to_device = send_to_device self.force_out = force_out self.setFrameShape(QtWidgets.QFrame.Box) self.setFrameShadow(QtWidgets.QFrame.Raised) grid = QtWidgets.QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setHorizontalSpacing(0) grid.setVerticalSpacing(0) self.setLayout(grid) label = QtWidgets.QLabel(title) label.setAlignment(QtCore.Qt.AlignCenter) label.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Preferred) grid.addWidget(label, 1, 1) self.stack = QtWidgets.QStackedWidget() grid.addWidget(self.stack, 2, 1) self.direction = QtWidgets.QLabel() self.direction.setAlignment(QtCore.Qt.AlignCenter) self.stack.addWidget(self.direction) grid_cb = LayoutWidget() grid_cb.layout.setContentsMargins(0, 0, 0, 0) grid_cb.layout.setHorizontalSpacing(0) grid_cb.layout.setVerticalSpacing(0) self.override = QtWidgets.QToolButton() self.override.setText("OVR") self.override.setCheckable(True) self.override.setToolTip("Override") grid_cb.addWidget(self.override, 3, 1) self.level = QtWidgets.QToolButton() self.level.setText("LVL") self.level.setCheckable(True) self.level.setToolTip("Level") grid_cb.addWidget(self.level, 3, 2) self.stack.addWidget(grid_cb) self.value = QtWidgets.QLabel() self.value.setAlignment(QtCore.Qt.AlignCenter) grid.addWidget(self.value, 3, 1) grid.setRowStretch(1, 1) grid.setRowStretch(2, 0) grid.setRowStretch(3, 0) grid.setRowStretch(4, 1) self.programmatic_change = False self.override.clicked.connect(self.override_toggled) self.level.clicked.connect(self.level_toggled) self.set_value(0, False, False)
def _make_vanilla_argument_item(self, name, argument): if name in self._arg_to_widgets: logger.warning("Argument with name '%s' already exists, skipping.", name) return widgets = dict() self._arg_to_widgets[name] = widgets entry = procdesc_to_entry(argument["desc"])(argument) widget_item = QtWidgets.QTreeWidgetItem([name]) if argument["tooltip"]: widget_item.setToolTip(1, argument["tooltip"]) widgets["entry"] = entry widgets["widget_item"] = widget_item for col in range(3): widget_item.setBackground(col, self._bg_gradient) font = widget_item.font(0) font.setBold(True) widget_item.setFont(0, font) if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._ensure_group_widget(argument["group"]).addChild(widget_item) fix_layout = LayoutWidget() widgets["fix_layout"] = fix_layout fix_layout.addWidget(entry) self.setItemWidget(widget_item, 1, fix_layout) buttons = LayoutWidget() recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon(self._default_value_icon) recompute_argument.clicked.connect( partial(self._recompute_vanilla_argument_clicked, name)) buttons.addWidget(recompute_argument) buttons.layout.setColumnStretch(0, 0) buttons.layout.setColumnStretch(1, 1) self.setItemWidget(widget_item, 2, buttons)
async def _recompute_argument(self, name): try: arginfo = await self._dock.compute_arginfo() except: logger.error("Could not recompute argument '%s' of '%s'", name, self._dock.expurl, exc_info=True) return argument = self._dock.arguments[name] procdesc = arginfo[name][0] state = argty_to_entry[procdesc["ty"]].default_state(procdesc) argument["desc"] = procdesc argument["state"] = state widgets = self._arg_to_widgets[name] widgets["entry"].deleteLater() widgets["entry"] = argty_to_entry[procdesc["ty"]](argument) widgets["fix_layout"] = LayoutWidget() widgets["fix_layout"].addWidget(widgets["entry"]) self.setItemWidget(widgets["widget_item"], 1, widgets["fix_layout"]) self.updateGeometries()
def __init__(self, datasets_sub): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) grid = LayoutWidget() self.setWidget(grid) self.search = QtWidgets.QLineEdit() self.search.setPlaceholderText("search...") self.search.editingFinished.connect(self._search_datasets) grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.table.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) grid.addWidget(self.table, 1, 0) self.set_model(Model(dict())) datasets_sub.add_setmodel_callback(self.set_model)
def __init__(self, manager, dock, expurl): self.manager = manager self.expurl = expurl QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) if hasattr(self.header(), "setSectionResizeMode"): set_resize_mode = self.header().setSectionResizeMode else: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_entry_widgetitem = dict() arguments = self.manager.get_submission_arguments(self.expurl) if not arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) for name, argument in arguments.items(): entry = argty_to_entry[argument["desc"]["ty"]](argument) widget_item = QtWidgets.QTreeWidgetItem([name]) self._arg_to_entry_widgetitem[name] = entry, widget_item if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) self.setItemWidget(widget_item, 1, entry) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) fix_layout = LayoutWidget() fix_layout.addWidget(recompute_argument) self.setItemWidget(widget_item, 2, fix_layout) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) buttons.addWidget(load_hdf5, 1, 2) buttons.layout.setColumnStretch(0, 1) buttons.layout.setColumnStretch(1, 0) buttons.layout.setColumnStretch(2, 0) buttons.layout.setColumnStretch(3, 1) self.setItemWidget(widget_item, 1, buttons)
def __init__(self, datasets_sub, master_host, master_port): QtWidgets.QDockWidget.__init__(self, "Datasets") self.setObjectName("Datasets") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) grid = LayoutWidget() self.setWidget(grid) self.search = QtWidgets.QLineEdit() self.search.setPlaceholderText("search...") self.search.editingFinished.connect(self._search_datasets) grid.addWidget(self.search, 0, 0) self.table = QtWidgets.QTreeView() self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) self.table.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) grid.addWidget(self.table, 1, 0) metadata_grid = LayoutWidget() self.metadata = {} for i, label in enumerate("artiq_version repo_rev file class_name " "rid start_time".split()): metadata_grid.addWidget(QtWidgets.QLabel(label), i, 0) v = QtWidgets.QLabel() v.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) metadata_grid.addWidget(v, i, 1) self.metadata[label] = v grid.addWidget(metadata_grid, 2, 0) self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) upload_action = QtWidgets.QAction("Upload dataset to master", self.table) upload_action.triggered.connect(self.upload_clicked) self.table.addAction(upload_action) self.set_model(Model(dict())) datasets_sub.add_setmodel_callback(self.set_model) self.master_host = master_host self.master_port = master_port
def __init__(self, channel, set_mode, force_out, title): QtWidgets.QFrame.__init__(self) self.channel = channel self.set_mode = set_mode self.force_out = force_out self.setFrameShape(QtWidgets.QFrame.Box) self.setFrameShadow(QtWidgets.QFrame.Raised) grid = QtWidgets.QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setHorizontalSpacing(0) grid.setVerticalSpacing(0) self.setLayout(grid) label = QtWidgets.QLabel(title) label.setAlignment(QtCore.Qt.AlignCenter) label.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Preferred) grid.addWidget(label, 1, 1) self.stack = QtWidgets.QStackedWidget() grid.addWidget(self.stack, 2, 1) self.direction = QtWidgets.QLabel() self.direction.setAlignment(QtCore.Qt.AlignCenter) self.stack.addWidget(self.direction) grid_cb = LayoutWidget() grid_cb.layout.setContentsMargins(0, 0, 0, 0) grid_cb.layout.setHorizontalSpacing(0) grid_cb.layout.setVerticalSpacing(0) self.override = QtWidgets.QToolButton() self.override.setText("OVR") self.override.setCheckable(True) self.override.setToolTip("Override") grid_cb.addWidget(self.override, 3, 1) self.level = QtWidgets.QToolButton() self.level.setText("LVL") self.level.setCheckable(True) self.level.setToolTip("Level") grid_cb.addWidget(self.level, 3, 2) self.stack.addWidget(grid_cb) self.value = QtWidgets.QLabel() self.value.setAlignment(QtCore.Qt.AlignCenter) grid.addWidget(self.value, 3, 1) grid.setRowStretch(1, 1) grid.setRowStretch(2, 0) grid.setRowStretch(3, 0) grid.setRowStretch(4, 1) self.programmatic_change = False self.override.clicked.connect(self.override_toggled) self.level.clicked.connect(self.level_toggled) self.cur_level = False self.cur_oe = False self.cur_override = False self.refresh_display()
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] def apply_properties(widget): widget.setDecimals(procdesc["ndecimals"]) if procdesc["global_min"] is not None: widget.setMinimum(procdesc["global_min"]/scale) else: widget.setMinimum(float("-inf")) if procdesc["global_max"] is not None: widget.setMaximum(procdesc["global_max"]/scale) else: widget.setMaximum(float("inf")) if procdesc["global_step"] is not None: widget.setSingleStep(procdesc["global_step"]/scale) if procdesc["unit"]: widget.setSuffix(" " + procdesc["unit"]) center = ScientificSpinBox() disable_scroll_wheel(center) apply_properties(center) center.setPrecision() center.setRelativeStep() center.setValue(state["center"]/scale) self.addWidget(center, 0, 1) self.addWidget(QtWidgets.QLabel("Center:"), 0, 0) span = ScientificSpinBox() disable_scroll_wheel(span) apply_properties(span) span.setPrecision() span.setRelativeStep() span.setMinimum(0) span.setValue(state["span"]/scale) self.addWidget(span, 1, 1) self.addWidget(QtWidgets.QLabel("Span:"), 1, 0) step = ScientificSpinBox() disable_scroll_wheel(step) apply_properties(step) step.setPrecision() step.setRelativeStep() step.setMinimum(0) step.setValue(state["step"]/scale) self.addWidget(step, 2, 1) self.addWidget(QtWidgets.QLabel("Step:"), 2, 0) randomize = QtWidgets.QCheckBox("Randomize") self.addWidget(randomize, 3, 1) randomize.setChecked(state["randomize"]) def update_center(value): state["center"] = value*scale def update_span(value): state["span"] = value*scale def update_step(value): state["step"] = value*scale def update_randomize(value): state["randomize"] = value center.valueChanged.connect(update_center) span.valueChanged.connect(update_span) step.valueChanged.connect(update_step) randomize.stateChanged.connect(update_randomize)
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] def apply_properties(widget): widget.setDecimals(procdesc["ndecimals"]) if procdesc["global_min"] is not None: widget.setMinimum(procdesc["global_min"]/scale) else: widget.setMinimum(float("-inf")) if procdesc["global_max"] is not None: widget.setMaximum(procdesc["global_max"]/scale) else: widget.setMaximum(float("inf")) if procdesc["global_step"] is not None: widget.setSingleStep(procdesc["global_step"]/scale) if procdesc["unit"]: widget.setSuffix(" " + procdesc["unit"]) scanner = ScanWidget() disable_scroll_wheel(scanner) self.addWidget(scanner, 0, 0, -1, 1) start = ScientificSpinBox() start.setStyleSheet("QDoubleSpinBox {color:blue}") start.setMinimumSize(110, 0) start.setSizePolicy(QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)) disable_scroll_wheel(start) self.addWidget(start, 0, 1) npoints = QtWidgets.QSpinBox() npoints.setMinimum(1) npoints.setMaximum((1 << 31) - 1) disable_scroll_wheel(npoints) self.addWidget(npoints, 1, 1) stop = ScientificSpinBox() stop.setStyleSheet("QDoubleSpinBox {color:red}") stop.setMinimumSize(110, 0) disable_scroll_wheel(stop) self.addWidget(stop, 2, 1) randomize = QtWidgets.QCheckBox("Randomize") self.addWidget(randomize, 3, 1) apply_properties(start) start.setPrecision() start.setRelativeStep() apply_properties(stop) stop.setPrecision() stop.setRelativeStep() apply_properties(scanner) def update_start(value): state["start"] = value*scale scanner.setStart(value) if start.value() != value: start.setValue(value) def update_stop(value): state["stop"] = value*scale scanner.setStop(value) if stop.value() != value: stop.setValue(value) def update_npoints(value): state["npoints"] = value scanner.setNum(value) if npoints.value() != value: npoints.setValue(value) def update_randomize(value): state["randomize"] = value randomize.setChecked(value) scanner.startChanged.connect(update_start) scanner.numChanged.connect(update_npoints) scanner.stopChanged.connect(update_stop) start.valueChanged.connect(update_start) npoints.valueChanged.connect(update_npoints) stop.valueChanged.connect(update_stop) randomize.stateChanged.connect(update_randomize) scanner.setStart(state["start"]/scale) scanner.setNum(state["npoints"]) scanner.setStop(state["stop"]/scale) randomize.setChecked(state["randomize"])
def _make_param_items(self, fqn, path, show_always, insert_at_idx=-1): if (fqn, path) in self._param_entries: return schema = self._schema_for_fqn(fqn) added_item_count = 0 def add_item(widget_item): nonlocal added_item_count group = schema.get("group", None) if not group: if insert_at_idx == -1: self.addTopLevelItem(widget_item) else: self.insertTopLevelItem(insert_at_idx + added_item_count, widget_item) added_item_count += 1 else: self._ensure_group_widget(group).addChild(widget_item) id_string = self._param_display_name(fqn, path) id_item = QtWidgets.QTreeWidgetItem([id_string]) add_item(id_item) for col in range(3): id_item.setBackground(col, self._bg_gradient) id_item.setFirstColumnSpanned(True) id_item.setForeground(0, self.palette().mid()) main_item = QtWidgets.QTreeWidgetItem([schema["description"]]) add_item(main_item) # Render description in bold. font = main_item.font(0) font.setBold(True) main_item.setFont(0, font) entry = self._make_override_entry(fqn, path) # KLUDGE: On dashboard startup, the datasets have not necessarily been # synced yet (self.manager.datasets is still an empty dict). However, # all experiments opened on startup were open previously, so all parameters # should have override values set. datasets = getattr(self.manager.datasets, "backing_store", {}) entry.read_from_params(self._ndscan_params, datasets) entry.value_changed.connect(self._set_save_timer) self._param_entries[(fqn, path)] = entry self.setItemWidget(main_item, 1, entry) buttons = LayoutWidget() reset_default = QtWidgets.QToolButton() reset_default.setToolTip("Reset parameter to default value") reset_default.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) reset_default.clicked.connect( partial(self._reset_entry_to_default, fqn, path)) buttons.addWidget(reset_default, col=0) remove_override = QtWidgets.QToolButton() remove_override.setIcon(self._remove_override_icon) remove_override.setToolTip("Remove this parameter override") remove_override.clicked.connect( partial(self._remove_override, fqn, path)) buttons.addWidget(remove_override, col=1) self.setItemWidget(main_item, 2, buttons) if show_always: sp = remove_override.sizePolicy() sp.setRetainSizeWhenHidden(True) remove_override.setSizePolicy(sp) remove_override.setVisible(False) return id_item, main_item
def __init__(self, exp_manager, d_shortcuts, explist_sub, explist_status_sub, schedule_ctl, experiment_db_ctl): QtWidgets.QDockWidget.__init__(self, "Explorer") self.setObjectName("Explorer") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) top_widget = LayoutWidget() self.setWidget(top_widget) self.exp_manager = exp_manager self.d_shortcuts = d_shortcuts self.schedule_ctl = schedule_ctl top_widget.addWidget(QtWidgets.QLabel("Revision:"), 0, 0) self.revision = QtWidgets.QLabel() self.revision.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) top_widget.addWidget(self.revision, 0, 1) self.stack = QtWidgets.QStackedWidget() top_widget.addWidget(self.stack, 1, 0, colspan=2) self.el_buttons = LayoutWidget() self.el_buttons.layout.setContentsMargins(0, 0, 0, 0) self.stack.addWidget(self.el_buttons) self.el = QtWidgets.QTreeView() self.el.setHeaderHidden(True) self.el.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) self.el.doubleClicked.connect(partial(self.expname_action, "open_experiment")) self.el_buttons.addWidget(self.el, 0, 0, colspan=2) open = QtWidgets.QPushButton("Open") open.setIcon(QtWidgets.QApplication.style().standardIcon(QtWidgets.QStyle.SP_DialogOpenButton)) open.setToolTip("Open the selected experiment (Return)") self.el_buttons.addWidget(open, 1, 0) open.clicked.connect(partial(self.expname_action, "open_experiment")) submit = QtWidgets.QPushButton("Submit") submit.setIcon(QtWidgets.QApplication.style().standardIcon(QtWidgets.QStyle.SP_DialogOkButton)) submit.setToolTip("Schedule the selected experiment (Ctrl+Return)") self.el_buttons.addWidget(submit, 1, 1) submit.clicked.connect(partial(self.expname_action, "submit")) self.explist_model = Model(dict()) explist_sub.add_setmodel_callback(self.set_model) self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) open_action = QtWidgets.QAction("Open", self.el) open_action.triggered.connect(partial(self.expname_action, "open_experiment")) open_action.setShortcut("RETURN") open_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(open_action) submit_action = QtWidgets.QAction("Submit", self.el) submit_action.triggered.connect(partial(self.expname_action, "submit")) submit_action.setShortcut("CTRL+RETURN") submit_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(submit_action) reqterm_action = QtWidgets.QAction("Request termination of instances", self.el) reqterm_action.triggered.connect(partial(self.expname_action, "request_inst_term")) reqterm_action.setShortcut("CTRL+BACKSPACE") reqterm_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(reqterm_action) set_shortcut_menu = QtWidgets.QMenu() for i in range(12): action = QtWidgets.QAction("F" + str(i + 1), self.el) action.triggered.connect(partial(self.set_shortcut, i)) set_shortcut_menu.addAction(action) set_shortcut_action = QtWidgets.QAction("Set shortcut", self.el) set_shortcut_action.setMenu(set_shortcut_menu) self.el.addAction(set_shortcut_action) sep = QtWidgets.QAction(self.el) sep.setSeparator(True) self.el.addAction(sep) scan_repository_action = QtWidgets.QAction("Scan repository HEAD", self.el) def scan_repository(): asyncio.ensure_future(experiment_db_ctl.scan_repository_async()) scan_repository_action.triggered.connect(scan_repository) self.el.addAction(scan_repository_action) self.current_directory = "" open_file_action = QtWidgets.QAction("Open file outside repository", self.el) open_file_action.triggered.connect(lambda: _OpenFileDialog(self, self.exp_manager, experiment_db_ctl).open()) self.el.addAction(open_file_action) self.waiting_panel = WaitingPanel() self.stack.addWidget(self.waiting_panel) explist_status_sub.add_setmodel_callback(lambda updater: updater.set_explorer(self))
def __init__(self, dock): QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) try: set_resize_mode = self.header().setSectionResizeMode except AttributeError: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_widgets = dict() self._dock = dock if not self._dock.arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing()*2.5) gradient.setColorAt(0, self.palette().base().color()) gradient.setColorAt(1, self.palette().midlight().color()) for name, argument in self._dock.arguments.items(): widgets = dict() self._arg_to_widgets[name] = widgets entry = procdesc_to_entry(argument["desc"])(argument) widget_item = QtWidgets.QTreeWidgetItem([name]) if argument["tooltip"]: widget_item.setToolTip(0, argument["tooltip"]) widgets["entry"] = entry widgets["widget_item"] = widget_item for col in range(3): widget_item.setBackground(col, gradient) font = widget_item.font(0) font.setBold(True) widget_item.setFont(0, font) if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) fix_layout = LayoutWidget() widgets["fix_layout"] = fix_layout fix_layout.addWidget(entry) self.setItemWidget(widget_item, 1, fix_layout) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) fix_layout = LayoutWidget() fix_layout.addWidget(recompute_argument) self.setItemWidget(widget_item, 2, fix_layout) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(self._recompute_arguments_clicked) load = QtWidgets.QPushButton("Set arguments from HDF5") load.setToolTip("Set arguments from currently selected HDF5 file") load.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogApplyButton)) load.clicked.connect(self._load_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) buttons.addWidget(load, 1, 2) for i, s in enumerate((1, 0, 0, 1)): buttons.layout.setColumnStretch(i, s) self.setItemWidget(widget_item, 1, buttons)
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] def apply_properties(widget): widget.setDecimals(procdesc["ndecimals"]) if procdesc["global_min"] is not None: widget.setMinimum(procdesc["global_min"]/scale) else: widget.setMinimum(float("-inf")) if procdesc["global_max"] is not None: widget.setMaximum(procdesc["global_max"]/scale) else: widget.setMaximum(float("inf")) if procdesc["global_step"] is not None: widget.setSingleStep(procdesc["global_step"]/scale) if procdesc["unit"]: widget.setSuffix(" " + procdesc["unit"]) center = ScientificSpinBox() disable_scroll_wheel(center) apply_properties(center) center.setPrecision() center.setRelativeStep() center.setValue(state["center"]) self.addWidget(center, 0, 1) self.addWidget(QtWidgets.QLabel("Center:"), 0, 0) span = ScientificSpinBox() disable_scroll_wheel(span) apply_properties(span) span.setPrecision() span.setRelativeStep() span.setMinimum(0) span.setValue(state["span"]) self.addWidget(span, 1, 1) self.addWidget(QtWidgets.QLabel("Span:"), 1, 0) step = ScientificSpinBox() disable_scroll_wheel(step) apply_properties(step) step.setPrecision() step.setRelativeStep() step.setMinimum(0) step.setValue(state["step"]) self.addWidget(step, 2, 1) self.addWidget(QtWidgets.QLabel("Step:"), 2, 0) randomize = QtWidgets.QCheckBox("Randomize") self.addWidget(randomize, 3, 1) randomize.setChecked(state["randomize"]) def update_center(value): state["center"] = value*scale def update_span(value): state["span"] = value*scale def update_step(value): state["step"] = value*scale def update_randomize(value): state["randomize"] = value center.valueChanged.connect(update_center) span.valueChanged.connect(update_span) step.valueChanged.connect(update_step) randomize.stateChanged.connect(update_randomize)
def __init__(self, procdesc, state): LayoutWidget.__init__(self) scale = procdesc["scale"] def apply_properties(widget): widget.setDecimals(procdesc["ndecimals"]) if procdesc["global_min"] is not None: widget.setMinimum(procdesc["global_min"]/scale) else: widget.setMinimum(float("-inf")) if procdesc["global_max"] is not None: widget.setMaximum(procdesc["global_max"]/scale) else: widget.setMaximum(float("inf")) if procdesc["global_step"] is not None: widget.setSingleStep(procdesc["global_step"]/scale) if procdesc["unit"]: widget.setSuffix(" " + procdesc["unit"]) scanner = ScanWidget() disable_scroll_wheel(scanner) self.addWidget(scanner, 0, 0, -1, 1) start = ScientificSpinBox() start.setStyleSheet("QDoubleSpinBox {color:blue}") start.setMinimumSize(110, 0) start.setSizePolicy(QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)) disable_scroll_wheel(start) self.addWidget(start, 0, 1) npoints = QtWidgets.QSpinBox() npoints.setMinimum(1) npoints.setMaximum((1 << 31) - 1) disable_scroll_wheel(npoints) self.addWidget(npoints, 1, 1) stop = ScientificSpinBox() stop.setStyleSheet("QDoubleSpinBox {color:red}") stop.setMinimumSize(110, 0) disable_scroll_wheel(stop) self.addWidget(stop, 2, 1) def update_start(value): state["start"] = value*scale scanner.setStart(value) def update_stop(value): state["stop"] = value*scale scanner.setStop(value) def update_npoints(value): state["npoints"] = value scanner.setNum(value) scanner.startChanged.connect(start.setValue) scanner.numChanged.connect(npoints.setValue) scanner.stopChanged.connect(stop.setValue) start.valueChanged.connect(update_start) npoints.valueChanged.connect(update_npoints) stop.valueChanged.connect(update_stop) scanner.setStart(state["start"]/scale) scanner.setNum(state["npoints"]) scanner.setStop(state["stop"]/scale) apply_properties(start) apply_properties(stop) apply_properties(scanner)
def __init__(self, manager, dock, expurl): super().__init__() self.manager = manager self.expurl = expurl self.setColumnCount(3) self.header().setStretchLastSection(False) if hasattr(self.header(), "setSectionResizeMode"): set_resize_mode = self.header().setSectionResizeMode else: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._bg_gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing()) self._bg_gradient.setColorAt(0, self.palette().base().color()) self._bg_gradient.setColorAt(1, self.palette().midlight().color()) self._save_timer = QtCore.QTimer(self) self._save_timer.timeout.connect(self._save_to_argument) self._param_entries = OrderedDict() self._groups = dict() self._arg_to_widgets = dict() self._override_items = dict() def icon_path(name): return os.path.join(os.path.dirname(os.path.abspath(__file__)), "icons", name) self._add_override_icon = QtGui.QIcon(icon_path("list-add-32.png")) self._remove_override_icon = QtGui.QIcon(icon_path("list-remove-32.png")) self._randomise_scan_icon = QtGui.QIcon( icon_path("media-playlist-shuffle-32.svg")) self._default_value_icon = self.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload) self._disable_scans_icon = self.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton) self._arguments = self.manager.get_submission_arguments(self.expurl) ndscan_params, vanilla_args = _try_extract_ndscan_params(self._arguments) if not ndscan_params: self.addTopLevelItem( QtWidgets.QTreeWidgetItem(["Error: Parameter metadata not found."])) else: self._ndscan_params = ndscan_params self.override_separator = None self._build_shortened_fqns() self.scan_options = None if "scan" in ndscan_params: self.scan_options = ScanOptions(ndscan_params["scan"]) for fqn, path in ndscan_params["always_shown"]: self._make_param_items(fqn, path, True) for name, argument in vanilla_args.items(): self._make_vanilla_argument_item(name, argument) self.override_separator = self._make_line_separator() self._make_add_override_prompt_item() self._set_override_line_idle() for ax in ndscan_params.get("scan", {}).get("axes", []): self._make_override_item(ax["fqn"], ax["path"]) for fqn, overrides in ndscan_params["overrides"].items(): for o in overrides: self._make_override_item(fqn, o["path"]) self._make_line_separator() if self.scan_options: scan_options_group = self._make_group_header_item("Scan options") self.addTopLevelItem(scan_options_group) for widget in self.scan_options.get_widgets(): twi = QtWidgets.QTreeWidgetItem() scan_options_group.addChild(twi) self.setItemWidget(twi, 1, widget) buttons_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(buttons_item) buttons_item.setFirstColumnSpanned(True) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon(self._default_value_icon) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) disable_scans = QtWidgets.QPushButton("Disable all scans") disable_scans.setIcon(self._disable_scans_icon) disable_scans.clicked.connect(self.disable_all_scans) disable_scans.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_R) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, col=1) buttons.addWidget(load_hdf5, col=2) buttons.addWidget(disable_scans, col=3) buttons.layout.setColumnStretch(0, 1) buttons.layout.setColumnStretch(1, 0) buttons.layout.setColumnStretch(2, 0) buttons.layout.setColumnStretch(3, 0) buttons.layout.setColumnStretch(4, 1) self.setItemWidget(buttons_item, 0, buttons)
def __init__(self, dm, title, bus_channel=0, channel=0, dds_model=None): self.dm = dm self.bus_channel = bus_channel self.channel = channel self.dds_name = title self.cur_frequency = 0 self.dds_model = dds_model QtWidgets.QFrame.__init__(self) self.setFrameShape(QtWidgets.QFrame.Box) self.setFrameShadow(QtWidgets.QFrame.Raised) grid = QtWidgets.QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setHorizontalSpacing(0) grid.setVerticalSpacing(0) self.setLayout(grid) label = QtWidgets.QLabel(title) label.setAlignment(QtCore.Qt.AlignCenter) grid.addWidget(label, 1, 1) # FREQ DATA/EDIT FIELD self.data_stack = QtWidgets.QStackedWidget() # page 1: display data grid_disp = LayoutWidget() grid_disp.layout.setContentsMargins(0, 0, 0, 0) grid_disp.layout.setHorizontalSpacing(0) grid_disp.layout.setVerticalSpacing(0) self.value_label = QtWidgets.QLabel() self.value_label.setAlignment(QtCore.Qt.AlignCenter) grid_disp.addWidget(self.value_label, 0, 1, 1, 2) unit = QtWidgets.QLabel("MHz") unit.setAlignment(QtCore.Qt.AlignCenter) grid_disp.addWidget(unit, 0, 3, 1, 1) self.data_stack.addWidget(grid_disp) # page 2: edit data grid_edit = LayoutWidget() grid_edit.layout.setContentsMargins(0, 0, 0, 0) grid_edit.layout.setHorizontalSpacing(0) grid_edit.layout.setVerticalSpacing(0) self.value_edit = _CancellableLineEdit(self) self.value_edit.setAlignment(QtCore.Qt.AlignRight) grid_edit.addWidget(self.value_edit, 0, 1, 1, 2) unit = QtWidgets.QLabel("MHz") unit.setAlignment(QtCore.Qt.AlignCenter) grid_edit.addWidget(unit, 0, 3, 1, 1) self.data_stack.addWidget(grid_edit) grid.addWidget(self.data_stack, 2, 1) # BUTTONS self.button_stack = QtWidgets.QStackedWidget() # page 1: SET button set_grid = LayoutWidget() set_btn = QtWidgets.QToolButton() set_btn.setText("Set") set_btn.setToolTip("Set frequency") set_grid.addWidget(set_btn, 0, 1, 1, 1) # for urukuls also allow switching off RF if self.dds_model.is_urukul: off_btn = QtWidgets.QToolButton() off_btn.setText("Off") off_btn.setToolTip("Switch off the output") set_grid.addWidget(off_btn, 0, 2, 1, 1) self.button_stack.addWidget(set_grid) # page 2: apply/cancel buttons apply_grid = LayoutWidget() apply = QtWidgets.QToolButton() apply.setText("Apply") apply.setToolTip("Apply changes") apply_grid.addWidget(apply, 0, 1, 1, 1) cancel = QtWidgets.QToolButton() cancel.setText("Cancel") cancel.setToolTip("Cancel changes") apply_grid.addWidget(cancel, 0, 2, 1, 1) self.button_stack.addWidget(apply_grid) grid.addWidget(self.button_stack, 3, 1) grid.setRowStretch(1, 1) grid.setRowStretch(2, 1) grid.setRowStretch(3, 1) set_btn.clicked.connect(self.set_clicked) apply.clicked.connect(self.apply_changes) if self.dds_model.is_urukul: off_btn.clicked.connect(self.off_clicked) self.value_edit.returnPressed.connect(lambda: self.apply_changes(None)) self.value_edit.escapePressedConnect(self.cancel_changes) cancel.clicked.connect(self.cancel_changes) self.refresh_display()
def __init__(self, manager, name): QDockWidgetCloseDetect.__init__(self, "Log") self.setObjectName(name) grid = LayoutWidget() self.setWidget(grid) grid.addWidget(QtWidgets.QLabel("Minimum level: "), 0, 0) self.filter_level = QtWidgets.QComboBox() self.filter_level.addItems( ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]) self.filter_level.setToolTip("Receive entries at or above this level") grid.addWidget(self.filter_level, 0, 1) self.filter_freetext = QtWidgets.QLineEdit() self.filter_freetext.setPlaceholderText("freetext filter...") self.filter_freetext.setToolTip("Receive entries containing this text") grid.addWidget(self.filter_freetext, 0, 2) scrollbottom = QtWidgets.QToolButton() scrollbottom.setToolTip("Scroll to bottom") scrollbottom.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_ArrowDown)) grid.addWidget(scrollbottom, 0, 3) scrollbottom.clicked.connect(self.scroll_to_bottom) clear = QtWidgets.QToolButton() clear.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton)) grid.addWidget(clear, 0, 4) clear.clicked.connect(lambda: self.model.clear()) if manager: newdock = QtWidgets.QToolButton() newdock.setToolTip("Create new log dock") newdock.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_FileDialogNewFolder)) # note the lambda, the default parameter is overriden otherwise newdock.clicked.connect(lambda: manager.create_new_dock()) grid.addWidget(newdock, 0, 5) grid.layout.setColumnStretch(2, 1) self.log = QtWidgets.QTreeView() self.log.setHorizontalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.log.setVerticalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.log.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) grid.addWidget(self.log, 1, 0, colspan=6 if manager else 5) self.scroll_at_bottom = False self.scroll_value = 0 self.log.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) copy_action = QtWidgets.QAction("Copy entry to clipboard", self.log) copy_action.triggered.connect(self.copy_to_clipboard) self.log.addAction(copy_action) clear_action = QtWidgets.QAction("Clear", self.log) clear_action.triggered.connect(lambda: self.model.clear()) self.log.addAction(clear_action) # If Qt worked correctly, this would be nice to have. Alas, resizeSections # is broken when the horizontal scrollbar is enabled. # sizeheader_action = QtWidgets.QAction("Resize header", self.log) # sizeheader_action.triggered.connect( # lambda: self.log.header().resizeSections(QtWidgets.QHeaderView.ResizeToContents)) # self.log.addAction(sizeheader_action) cw = QtGui.QFontMetrics(self.font()).averageCharWidth() self.log.header().resizeSection(0, 26 * cw) self.model = _Model() self.log.setModel(self.model) self.model.rowsAboutToBeInserted.connect(self.rows_inserted_before) self.model.rowsInserted.connect(self.rows_inserted_after) self.model.rowsRemoved.connect(self.rows_removed)
def __init__(self, manager, dock, expurl): self.manager = manager self.expurl = expurl QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) if hasattr(self.header(), "setSectionResizeMode"): set_resize_mode = self.header().setSectionResizeMode else: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_widgets = dict() arguments = self.manager.get_submission_arguments(self.expurl) if not arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing() * 2.5) gradient.setColorAt(0, self.palette().base().color()) gradient.setColorAt(1, self.palette().midlight().color()) for name, argument in arguments.items(): widgets = dict() self._arg_to_widgets[name] = widgets entry = procdesc_to_entry(argument["desc"])(argument) widget_item = QtWidgets.QTreeWidgetItem([name]) if argument["tooltip"]: widget_item.setToolTip(0, argument["tooltip"]) widgets["entry"] = entry widgets["widget_item"] = widget_item for col in range(3): widget_item.setBackground(col, gradient) font = widget_item.font(0) font.setBold(True) widget_item.setFont(0, font) if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) fix_layout = LayoutWidget() widgets["fix_layout"] = fix_layout fix_layout.addWidget(entry) self.setItemWidget(widget_item, 1, fix_layout) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) tool_buttons = LayoutWidget() tool_buttons.addWidget(recompute_argument, 1) disable_other_scans = QtWidgets.QToolButton() widgets["disable_other_scans"] = disable_other_scans disable_other_scans.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton)) disable_other_scans.setToolTip("Disable all other scans in " "this experiment") disable_other_scans.clicked.connect( partial(self._disable_other_scans, name)) tool_buttons.layout.setRowStretch(0, 1) tool_buttons.layout.setRowStretch(3, 1) tool_buttons.addWidget(disable_other_scans, 2) if not isinstance(entry, ScanEntry): disable_other_scans.setVisible(False) self.setItemWidget(widget_item, 2, tool_buttons) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) buttons.addWidget(load_hdf5, 1, 2) buttons.layout.setColumnStretch(0, 1) buttons.layout.setColumnStretch(1, 0) buttons.layout.setColumnStretch(2, 0) buttons.layout.setColumnStretch(3, 1) self.setItemWidget(widget_item, 1, buttons)
def __init__(self, manager, name): QDockWidgetCloseDetect.__init__(self, "Log") self.setObjectName(name) grid = LayoutWidget() self.setWidget(grid) grid.addWidget(QtWidgets.QLabel("Minimum level: "), 0, 0) self.filter_level = QtWidgets.QComboBox() self.filter_level.addItems(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]) self.filter_level.setToolTip("Receive entries at or above this level") grid.addWidget(self.filter_level, 0, 1) self.filter_freetext = QtWidgets.QLineEdit() self.filter_freetext.setPlaceholderText("freetext filter...") self.filter_freetext.setToolTip("Receive entries containing this text") grid.addWidget(self.filter_freetext, 0, 2) scrollbottom = QtWidgets.QToolButton() scrollbottom.setToolTip("Scroll to bottom") scrollbottom.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_ArrowDown)) grid.addWidget(scrollbottom, 0, 3) scrollbottom.clicked.connect(self.scroll_to_bottom) clear = QtWidgets.QToolButton() clear.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton)) grid.addWidget(clear, 0, 4) clear.clicked.connect(lambda: self.model.clear()) if manager: newdock = QtWidgets.QToolButton() newdock.setToolTip("Create new log dock") newdock.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_FileDialogNewFolder)) # note the lambda, the default parameter is overriden otherwise newdock.clicked.connect(lambda: manager.create_new_dock()) grid.addWidget(newdock, 0, 5) grid.layout.setColumnStretch(2, 1) self.log = QtWidgets.QTreeView() self.log.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.log.setHorizontalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.log.setVerticalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) self.log.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) grid.addWidget(self.log, 1, 0, colspan=6 if manager else 5) self.scroll_at_bottom = False self.scroll_value = 0 # If Qt worked correctly, this would be nice to have. Alas, resizeSections # is broken when the horizontal scrollbar is enabled. # self.log.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) # sizeheader_action = QtWidgets.QAction("Resize header", self.log) # sizeheader_action.triggered.connect( # lambda: self.log.header().resizeSections(QtWidgets.QHeaderView.ResizeToContents)) # self.log.addAction(sizeheader_action) cw = QtGui.QFontMetrics(self.font()).averageCharWidth() self.log.header().resizeSection(0, 26*cw) self.model = _Model() self.log.setModel(self.model) self.model.rowsAboutToBeInserted.connect(self.rows_inserted_before) self.model.rowsInserted.connect(self.rows_inserted_after) self.model.rowsRemoved.connect(self.rows_removed)
def __init__(self, manager, dock, expurl): self.manager = manager self.expurl = expurl QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) if hasattr(self.header(), "setSectionResizeMode"): set_resize_mode = self.header().setSectionResizeMode else: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_widgets = dict() arguments = self.manager.get_submission_arguments(self.expurl) if not arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing()*2.5) gradient.setColorAt(0, self.palette().base().color()) gradient.setColorAt(1, self.palette().midlight().color()) for name, argument in arguments.items(): widgets = dict() self._arg_to_widgets[name] = widgets entry = procdesc_to_entry(argument["desc"])(argument) widget_item = QtWidgets.QTreeWidgetItem([name]) if argument["tooltip"]: widget_item.setToolTip(0, argument["tooltip"]) widgets["entry"] = entry widgets["widget_item"] = widget_item for col in range(3): widget_item.setBackground(col, gradient) font = widget_item.font(0) font.setBold(True) widget_item.setFont(0, font) if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) fix_layout = LayoutWidget() widgets["fix_layout"] = fix_layout fix_layout.addWidget(entry) self.setItemWidget(widget_item, 1, fix_layout) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) tool_buttons = LayoutWidget() tool_buttons.addWidget(recompute_argument, 1) disable_other_scans = QtWidgets.QToolButton() widgets["disable_other_scans"] = disable_other_scans disable_other_scans.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton)) disable_other_scans.setToolTip("Disable all other scans in " "this experiment") disable_other_scans.clicked.connect( partial(self._disable_other_scans, name)) tool_buttons.layout.setRowStretch(0, 1) tool_buttons.layout.setRowStretch(3, 1) tool_buttons.addWidget(disable_other_scans, 2) if not isinstance(entry, ScanEntry): disable_other_scans.setVisible(False) self.setItemWidget(widget_item, 2, tool_buttons) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) buttons.addWidget(load_hdf5, 1, 2) buttons.layout.setColumnStretch(0, 1) buttons.layout.setColumnStretch(1, 0) buttons.layout.setColumnStretch(2, 0) buttons.layout.setColumnStretch(3, 1) self.setItemWidget(widget_item, 1, buttons)
def __init__(self, dock): QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) try: set_resize_mode = self.header().setSectionResizeMode except AttributeError: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_widgets = dict() self._dock = dock if not self._dock.arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing() * 2.5) gradient.setColorAt(0, self.palette().base().color()) gradient.setColorAt(1, self.palette().midlight().color()) for name, argument in self._dock.arguments.items(): widgets = dict() self._arg_to_widgets[name] = widgets entry = procdesc_to_entry(argument["desc"])(argument) widget_item = QtWidgets.QTreeWidgetItem([name]) if argument["tooltip"]: widget_item.setToolTip(0, argument["tooltip"]) widgets["entry"] = entry widgets["widget_item"] = widget_item for col in range(3): widget_item.setBackground(col, gradient) font = widget_item.font(0) font.setBold(True) widget_item.setFont(0, font) if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) fix_layout = LayoutWidget() widgets["fix_layout"] = fix_layout fix_layout.addWidget(entry) self.setItemWidget(widget_item, 1, fix_layout) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) fix_layout = LayoutWidget() fix_layout.addWidget(recompute_argument) self.setItemWidget(widget_item, 2, fix_layout) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(self._recompute_arguments_clicked) load = QtWidgets.QPushButton("Set arguments from HDF5") load.setToolTip("Set arguments from currently selected HDF5 file") load.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogApplyButton)) load.clicked.connect(self._load_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) buttons.addWidget(load, 1, 2) for i, s in enumerate((1, 0, 0, 1)): buttons.layout.setColumnStretch(i, s) self.setItemWidget(widget_item, 1, buttons)
def __init__(self, manager, dock, expurl): super().__init__() self.manager = manager self.expurl = expurl self.setColumnCount(3) self.header().setStretchLastSection(False) if hasattr(self.header(), "setSectionResizeMode"): set_resize_mode = self.header().setSectionResizeMode else: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.setStyleSheet("QTreeWidget {background: " + self.palette().midlight().color().name() + " ;}") self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._bg_gradient = QtGui.QLinearGradient( 0, 0, 0, QtGui.QFontMetrics(self.font()).lineSpacing()) self._bg_gradient.setColorAt(0, self.palette().base().color()) self._bg_gradient.setColorAt(1, self.palette().midlight().color()) self._save_timer = QtCore.QTimer(self) self._save_timer.timeout.connect(self._save_to_argument) self._param_entries = OrderedDict() self._groups = dict() self._arg_to_widgets = dict() self._override_items = dict() def icon_path(name): return os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "icons", name) self._add_override_icon = QtGui.QIcon(icon_path("list-add-32.png")) self._remove_override_icon = QtGui.QIcon( icon_path("list-remove-32.png")) self._randomise_scan_icon = QtGui.QIcon( icon_path("media-playlist-shuffle-32.svg")) self._default_value_icon = self.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload) self._disable_scans_icon = self.style().standardIcon( QtWidgets.QStyle.SP_DialogResetButton) self._arguments = self.manager.get_submission_arguments(self.expurl) ndscan_params, vanilla_args = _try_extract_ndscan_params( self._arguments) if not ndscan_params: self.addTopLevelItem( QtWidgets.QTreeWidgetItem( ["Error: Parameter metadata not found."])) else: self._ndscan_params = ndscan_params self.override_separator = None self._build_shortened_fqns() for fqn, path in ndscan_params["always_shown"]: self._make_param_items(fqn, path, True) for name, argument in vanilla_args.items(): self._make_vanilla_argument_item(name, argument) self.override_separator = self._make_line_separator() self._make_add_override_prompt_item() self._set_override_line_idle() for ax in ndscan_params["scan"]["axes"]: self._make_override_item(ax["fqn"], ax["path"]) for fqn, overrides in ndscan_params["overrides"].items(): for o in overrides: self._make_override_item(fqn, o["path"]) self._make_line_separator() scan_options_group = self._make_group_header_item("Scan options") self.addTopLevelItem(scan_options_group) # num_repeats_container = QtWidgets.QWidget() num_repeats_layout = QtWidgets.QHBoxLayout() num_repeats_container.setLayout(num_repeats_layout) num_repeats_label = QtWidgets.QLabel("Number of repeats: ") num_repeats_layout.addWidget(num_repeats_label) num_repeats_layout.setStretchFactor(num_repeats_label, 0) self.num_repeats_box = QtWidgets.QSpinBox() self.num_repeats_box.setMinimum(1) self.num_repeats_box.setMaximum( 2**16) # A gratuitous, but hopefully generous restriction self.num_repeats_box.setValue(ndscan_params["scan"].get( "num_repeats", 1)) num_repeats_layout.addWidget(self.num_repeats_box) num_repeats_layout.setStretchFactor(self.num_repeats_box, 0) num_repeats_layout.addStretch() num_repeats_item = QtWidgets.QTreeWidgetItem() scan_options_group.addChild(num_repeats_item) self.setItemWidget(num_repeats_item, 1, num_repeats_container) # cwa_container = QtWidgets.QWidget() cwa_layout = QtWidgets.QHBoxLayout() cwa_container.setLayout(cwa_layout) cwa_label = QtWidgets.QLabel("Repeat continuously without axes: ") cwa_layout.addWidget(cwa_label) cwa_layout.setStretchFactor(cwa_label, 0) self.cwa_box = QtWidgets.QCheckBox() self.cwa_box.setChecked(ndscan_params["scan"].get( "continuous_without_axes", True)) cwa_layout.addWidget(self.cwa_box) cwa_layout.setStretchFactor(self.cwa_box, 1) cwa_item = QtWidgets.QTreeWidgetItem() scan_options_group.addChild(cwa_item) self.setItemWidget(cwa_item, 1, cwa_container) # randomise_globally_container = QtWidgets.QWidget() randomise_globally_layout = QtWidgets.QHBoxLayout() randomise_globally_container.setLayout(randomise_globally_layout) randomise_globally_label = QtWidgets.QLabel( "Randomise point order across axes: ") randomise_globally_layout.addWidget(randomise_globally_label) randomise_globally_layout.setStretchFactor( randomise_globally_label, 0) self.randomise_globally_box = QtWidgets.QCheckBox() self.randomise_globally_box.setChecked(ndscan_params["scan"].get( "randomise_order_globally", False)) randomise_globally_layout.addWidget(self.randomise_globally_box) randomise_globally_layout.setStretchFactor( self.randomise_globally_box, 1) randomise_globally_item = QtWidgets.QTreeWidgetItem() scan_options_group.addChild(randomise_globally_item) self.setItemWidget(randomise_globally_item, 1, randomise_globally_container) buttons_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(buttons_item) buttons_item.setFirstColumnSpanned(True) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon(self._default_value_icon) recompute_arguments.clicked.connect(dock._recompute_arguments_clicked) load_hdf5 = QtWidgets.QPushButton("Load HDF5") load_hdf5.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) load_hdf5.clicked.connect(dock._load_hdf5_clicked) disable_scans = QtWidgets.QPushButton("Disable all scans") disable_scans.setIcon(self._disable_scans_icon) disable_scans.clicked.connect(self.disable_all_scans) disable_scans.setShortcut(QtCore.Qt.CTRL + QtCore.Qt.Key_R) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, col=1) buttons.addWidget(load_hdf5, col=2) buttons.addWidget(disable_scans, col=3) buttons.layout.setColumnStretch(0, 1) buttons.layout.setColumnStretch(1, 0) buttons.layout.setColumnStretch(2, 0) buttons.layout.setColumnStretch(3, 0) buttons.layout.setColumnStretch(4, 1) self.setItemWidget(buttons_item, 0, buttons)
def __init__(self, exp_manager, d_shortcuts, explist_sub, explist_status_sub, schedule_ctl, experiment_db_ctl): QtWidgets.QDockWidget.__init__(self, "Explorer") self.setObjectName("Explorer") self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) top_widget = LayoutWidget() self.setWidget(top_widget) self.exp_manager = exp_manager self.d_shortcuts = d_shortcuts self.schedule_ctl = schedule_ctl top_widget.addWidget(QtWidgets.QLabel("Revision:"), 0, 0) self.revision = QtWidgets.QLabel() self.revision.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) top_widget.addWidget(self.revision, 0, 1) self.stack = QtWidgets.QStackedWidget() top_widget.addWidget(self.stack, 1, 0, colspan=2) self.el_buttons = LayoutWidget() self.el_buttons.layout.setContentsMargins(0, 0, 0, 0) self.stack.addWidget(self.el_buttons) self.el = QtWidgets.QTreeView() self.el.setHeaderHidden(True) self.el.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems) self.el.doubleClicked.connect( partial(self.expname_action, "open_experiment")) self.el_buttons.addWidget(self.el, 0, 0, colspan=2) open = QtWidgets.QPushButton("Open") open.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOpenButton)) open.setToolTip("Open the selected experiment (Return)") self.el_buttons.addWidget(open, 1, 0) open.clicked.connect(partial(self.expname_action, "open_experiment")) submit = QtWidgets.QPushButton("Submit") submit.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_DialogOkButton)) submit.setToolTip("Schedule the selected experiment (Ctrl+Return)") self.el_buttons.addWidget(submit, 1, 1) submit.clicked.connect(partial(self.expname_action, "submit")) self.explist_model = Model(dict()) explist_sub.add_setmodel_callback(self.set_model) self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) open_action = QtWidgets.QAction("Open", self.el) open_action.triggered.connect( partial(self.expname_action, "open_experiment")) open_action.setShortcut("RETURN") open_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(open_action) submit_action = QtWidgets.QAction("Submit", self.el) submit_action.triggered.connect(partial(self.expname_action, "submit")) submit_action.setShortcut("CTRL+RETURN") submit_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(submit_action) reqterm_action = QtWidgets.QAction("Request termination of instances", self.el) reqterm_action.triggered.connect( partial(self.expname_action, "request_inst_term")) reqterm_action.setShortcut("CTRL+BACKSPACE") reqterm_action.setShortcutContext(QtCore.Qt.WidgetShortcut) self.el.addAction(reqterm_action) set_shortcut_menu = QtWidgets.QMenu() for i in range(12): action = QtWidgets.QAction("F" + str(i + 1), self.el) action.triggered.connect(partial(self.set_shortcut, i)) set_shortcut_menu.addAction(action) set_shortcut_action = QtWidgets.QAction("Set shortcut", self.el) set_shortcut_action.setMenu(set_shortcut_menu) self.el.addAction(set_shortcut_action) sep = QtWidgets.QAction(self.el) sep.setSeparator(True) self.el.addAction(sep) scan_repository_action = QtWidgets.QAction("Scan repository HEAD", self.el) def scan_repository(): asyncio.ensure_future(experiment_db_ctl.scan_repository_async()) scan_repository_action.triggered.connect(scan_repository) self.el.addAction(scan_repository_action) self.current_directory = "" open_file_action = QtWidgets.QAction("Open file outside repository", self.el) open_file_action.triggered.connect(lambda: _OpenFileDialog( self, self.exp_manager, experiment_db_ctl).open()) self.el.addAction(open_file_action) self.waiting_panel = WaitingPanel() self.stack.addWidget(self.waiting_panel) explist_status_sub.add_setmodel_callback( lambda updater: updater.set_explorer(self))
def __init__(self, dock): QtWidgets.QTreeWidget.__init__(self) self.setColumnCount(3) self.header().setStretchLastSection(False) try: set_resize_mode = self.header().setSectionResizeMode except AttributeError: set_resize_mode = self.header().setResizeMode set_resize_mode(0, QtWidgets.QHeaderView.ResizeToContents) set_resize_mode(1, QtWidgets.QHeaderView.Stretch) set_resize_mode(2, QtWidgets.QHeaderView.ResizeToContents) self.header().setVisible(False) self.setSelectionMode(self.NoSelection) self.setHorizontalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel) self.viewport().installEventFilter(_WheelFilter(self.viewport())) self._groups = dict() self._arg_to_entry_widgetitem = dict() self._dock = dock if not self._dock.arguments: self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No arguments"])) for name, argument in self._dock.arguments.items(): try: entry = argty_to_entry[argument["desc"]["ty"]](argument) except: print(name, argument) widget_item = QtWidgets.QTreeWidgetItem([name]) self._arg_to_entry_widgetitem[name] = entry, widget_item if argument["group"] is None: self.addTopLevelItem(widget_item) else: self._get_group(argument["group"]).addChild(widget_item) self.setItemWidget(widget_item, 1, entry) recompute_argument = QtWidgets.QToolButton() recompute_argument.setToolTip("Re-run the experiment's build " "method and take the default value") recompute_argument.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_argument.clicked.connect( partial(self._recompute_argument_clicked, name)) fix_layout = LayoutWidget() fix_layout.addWidget(recompute_argument) self.setItemWidget(widget_item, 2, fix_layout) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) recompute_arguments = QtWidgets.QPushButton("Recompute all arguments") recompute_arguments.setIcon( QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_BrowserReload)) recompute_arguments.clicked.connect(self._recompute_arguments_clicked) buttons = LayoutWidget() buttons.addWidget(recompute_arguments, 1, 1) for i, s in enumerate((1, 0, 0, 1)): buttons.layout.setColumnStretch(i, s) self.setItemWidget(widget_item, 1, buttons)
def make_GUI(self): grid = LayoutWidget() self.setWidget(grid) self.table = QtWidgets.QTreeWidget() self.table.setFocusPolicy(QtCore.Qt.StrongFocus) self.table.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectItems) self.table.setSelectionMode( QtWidgets.QAbstractItemView.SingleSelection) self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.table.setSortingEnabled(False) self.table.header().setStretchLastSection(False) p = QtGui.QPalette() p.setColor(9, QtGui.QColor(248, 248, 248)) self.setPalette(p) self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.open_menu) self.table.setIndentation(10) grid.addWidget(self.table, 0, 0) self.table.setHeaderLabels(["Collection", "Value"]) self.region_widget_items = dict() self.collection_widget_items = [dict(), dict()] self.param_widget_items = [dict(), dict()] if not self.cxn: return all_params_registry = dict() common_params_registry = dict() accessed_params_registry = dict() r = self.cxn["registry"] if self.accessed_params: # accessed parameters list for param in self.accessed_params: param_split = param.split(".") collection = param_split[0] param_name = param_split[1] if not collection in accessed_params_registry.keys(): accessed_params_registry[collection] = dict() r.cd("", "Servers", "Parameter Vault", collection) accessed_params_registry[collection][param_name] = r.get( param_name) for collection in sorted(accessed_params_registry.keys()): collection_item = self.make_collection_item( accessed_params_registry, collection, region_index=0) if collection_item: self.table.addTopLevelItem(collection_item) if self.expand_accessed_params: collection_item.setExpanded(True) else: collection_item.setExpanded(False) self.collection_widget_items[0][ collection] = collection_item else: # set up top-level items for all parameters and common parameters region_common_params_item = self.make_region_item( "Commonly Used Parameters") region_all_params_item = self.make_region_item("All Parameters") # common parameters list for param in commonly_used_parameters: param_split = param.split(".") collection = param_split[0] param_name = param_split[1] param_value = "" try: r.cd("", "Servers", "Parameter Vault", collection) param_value = r.get(param_name) except: continue if not collection in common_params_registry.keys(): common_params_registry[collection] = dict() common_params_registry[collection][param_name] = param_value for collection in sorted(common_params_registry.keys()): collection_item = self.make_collection_item( common_params_registry, collection, region_index=0) if collection_item: region_common_params_item.addChild(collection_item) self.collection_widget_items[0][ collection] = collection_item # all parameters list r.cd("", "Servers", "Parameter Vault") collections = r.dir()[0] for collection in collections: collection_dict = dict() r.cd("", "Servers", "Parameter Vault", collection) params = r.dir()[1] for param in params: collection_dict[param] = r.get(param) all_params_registry[collection] = collection_dict for collection in sorted(all_params_registry.keys()): collection_item = self.make_collection_item( all_params_registry, collection, region_index=1) if collection_item: region_all_params_item.addChild(collection_item) self.collection_widget_items[1][ collection] = collection_item self.table.setColumnWidth(0, 225) self.table.setColumnWidth(1, 150) self.table.header().setFocusPolicy(QtCore.Qt.NoFocus) self.cxn.disconnect()