diff --git a/artiq/dashboard/experiments.py b/artiq/dashboard/experiments.py index 5a35063f1..460cbd357 100644 --- a/artiq/dashboard/experiments.py +++ b/artiq/dashboard/experiments.py @@ -8,7 +8,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets import h5py from artiq.gui.tools import LayoutWidget, log_level_to_name, get_open_file_name -from artiq.gui.entries import argty_to_entry +from artiq.gui.entries import argty_to_entry, ScanEntry from artiq.protocols import pyon @@ -78,9 +78,24 @@ class _ArgumentEditor(QtWidgets.QTreeWidget): 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) + + tool_buttons = LayoutWidget() + tool_buttons.addWidget(recompute_argument, 1) + + if isinstance(entry, ScanEntry): + disable_other_scans = QtWidgets.QToolButton() + 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) + + self.setItemWidget(widget_item, 2, tool_buttons) widget_item = QtWidgets.QTreeWidgetItem() self.addTopLevelItem(widget_item) @@ -142,6 +157,11 @@ class _ArgumentEditor(QtWidgets.QTreeWidget): self._arg_to_entry_widgetitem[name] = entry, widget_item self.setItemWidget(widget_item, 1, entry) + def _disable_other_scans(self, current_name): + for name, (entry, _) in self._arg_to_entry_widgetitem.items(): + if name != current_name and isinstance(entry, ScanEntry): + entry.disable() + def save_state(self): expanded = [] for k, v in self._groups.items(): diff --git a/artiq/dashboard/shortcuts.py b/artiq/dashboard/shortcuts.py index 23ee871ca..c7750d2a7 100644 --- a/artiq/dashboard/shortcuts.py +++ b/artiq/dashboard/shortcuts.py @@ -44,7 +44,7 @@ class ShortcutsDock(QtWidgets.QDockWidget): clear = QtWidgets.QToolButton() clear.setIcon(QtWidgets.QApplication.style().standardIcon( - QtWidgets.QStyle.SP_DialogResetButton)) + QtWidgets.QStyle.SP_DialogDiscardButton)) layout.addWidget(clear, row, 2) clear.clicked.connect(partial(self.set_shortcut, i, "")) diff --git a/artiq/gui/entries.py b/artiq/gui/entries.py index 020000d33..9571e34af 100644 --- a/artiq/gui/entries.py +++ b/artiq/gui/entries.py @@ -11,7 +11,7 @@ from artiq.gui.scientific_spinbox import ScientificSpinBox logger = logging.getLogger(__name__) -class _StringEntry(QtWidgets.QLineEdit): +class StringEntry(QtWidgets.QLineEdit): def __init__(self, argument): QtWidgets.QLineEdit.__init__(self) self.setText(argument["state"]) @@ -28,7 +28,7 @@ class _StringEntry(QtWidgets.QLineEdit): return procdesc.get("default", "") -class _BooleanEntry(QtWidgets.QCheckBox): +class BooleanEntry(QtWidgets.QCheckBox): def __init__(self, argument): QtWidgets.QCheckBox.__init__(self) self.setChecked(argument["state"]) @@ -45,7 +45,7 @@ class _BooleanEntry(QtWidgets.QCheckBox): return procdesc.get("default", False) -class _EnumerationEntry(QtWidgets.QComboBox): +class EnumerationEntry(QtWidgets.QComboBox): def __init__(self, argument): QtWidgets.QComboBox.__init__(self) disable_scroll_wheel(self) @@ -69,7 +69,7 @@ class _EnumerationEntry(QtWidgets.QComboBox): return procdesc["choices"][0] -class _NumberEntry(QtWidgets.QDoubleSpinBox): +class NumberEntry(QtWidgets.QDoubleSpinBox): def __init__(self, argument): QtWidgets.QDoubleSpinBox.__init__(self) disable_scroll_wheel(self) @@ -224,7 +224,7 @@ class _ExplicitScan(LayoutWidget): self.value.textEdited.connect(update) -class _ScanEntry(LayoutWidget): +class ScanEntry(LayoutWidget): def __init__(self, argument): LayoutWidget.__init__(self) self.argument = argument @@ -256,6 +256,9 @@ class _ScanEntry(LayoutWidget): selected = argument["state"]["selected"] self.radiobuttons[selected].setChecked(True) + def disable(self): + self.radiobuttons["NoScan"].setChecked(True) + @staticmethod def state_to_value(state): selected = state["selected"] @@ -301,10 +304,10 @@ class _ScanEntry(LayoutWidget): argty_to_entry = { - "PYONValue": _StringEntry, - "BooleanValue": _BooleanEntry, - "EnumerationValue": _EnumerationEntry, - "NumberValue": _NumberEntry, - "StringValue": _StringEntry, - "Scannable": _ScanEntry + "PYONValue": StringEntry, + "BooleanValue": BooleanEntry, + "EnumerationValue": EnumerationEntry, + "NumberValue": NumberEntry, + "StringValue": StringEntry, + "Scannable": ScanEntry }