mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-18 07:56:30 +08:00
dashboard: subclass _ArgumentEditor as EntryTreeWidget
This commit is contained in:
parent
6978101b1f
commit
1a41b16fb6
@ -9,10 +9,9 @@ import h5py
|
|||||||
|
|
||||||
from sipyco import pyon
|
from sipyco import pyon
|
||||||
|
|
||||||
from artiq.gui.entries import procdesc_to_entry, ScanEntry
|
from artiq.gui.entries import procdesc_to_entry, EntryTreeWidget
|
||||||
from artiq.gui.fuzzy_select import FuzzySelectWidget
|
from artiq.gui.fuzzy_select import FuzzySelectWidget
|
||||||
from artiq.gui.tools import (LayoutWidget, WheelFilter,
|
from artiq.gui.tools import (LayoutWidget, log_level_to_name, get_open_file_name)
|
||||||
log_level_to_name, get_open_file_name)
|
|
||||||
from artiq.tools import parse_devarg_override, unparse_devarg_override
|
from artiq.tools import parse_devarg_override, unparse_devarg_override
|
||||||
|
|
||||||
|
|
||||||
@ -25,99 +24,21 @@ logger = logging.getLogger(__name__)
|
|||||||
# 2. file:<class name>@<file name>
|
# 2. file:<class name>@<file name>
|
||||||
|
|
||||||
|
|
||||||
class _ArgumentEditor(QtWidgets.QTreeWidget):
|
class _ArgumentEditor(EntryTreeWidget):
|
||||||
def __init__(self, manager, dock, expurl):
|
def __init__(self, manager, dock, expurl):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
self.expurl = expurl
|
self.expurl = expurl
|
||||||
|
|
||||||
QtWidgets.QTreeWidget.__init__(self)
|
EntryTreeWidget.__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(), True))
|
|
||||||
|
|
||||||
self._groups = dict()
|
|
||||||
self._arg_to_widgets = dict()
|
|
||||||
|
|
||||||
arguments = self.manager.get_submission_arguments(self.expurl)
|
arguments = self.manager.get_submission_arguments(self.expurl)
|
||||||
|
|
||||||
if not arguments:
|
if not arguments:
|
||||||
self.addTopLevelItem(QtWidgets.QTreeWidgetItem(["No 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():
|
for name, argument in arguments.items():
|
||||||
widgets = dict()
|
self.set_argument(name, argument)
|
||||||
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 = QtWidgets.QPushButton("Recompute all arguments")
|
||||||
recompute_arguments.setIcon(
|
recompute_arguments.setIcon(
|
||||||
QtWidgets.QApplication.style().standardIcon(
|
QtWidgets.QApplication.style().standardIcon(
|
||||||
@ -136,41 +57,10 @@ class _ArgumentEditor(QtWidgets.QTreeWidget):
|
|||||||
buttons.layout.setColumnStretch(1, 0)
|
buttons.layout.setColumnStretch(1, 0)
|
||||||
buttons.layout.setColumnStretch(2, 0)
|
buttons.layout.setColumnStretch(2, 0)
|
||||||
buttons.layout.setColumnStretch(3, 1)
|
buttons.layout.setColumnStretch(3, 1)
|
||||||
self.setItemWidget(widget_item, 1, buttons)
|
self.setItemWidget(self.bottom_item, 1, buttons)
|
||||||
|
|
||||||
def _get_group(self, name):
|
def reset_entry(self, key):
|
||||||
if name in self._groups:
|
asyncio.ensure_future(self._recompute_argument(key))
|
||||||
return self._groups[name]
|
|
||||||
group = QtWidgets.QTreeWidgetItem([name])
|
|
||||||
for col in range(3):
|
|
||||||
group.setBackground(col, self.palette().mid())
|
|
||||||
group.setForeground(col, self.palette().brightText())
|
|
||||||
font = group.font(col)
|
|
||||||
font.setBold(True)
|
|
||||||
group.setFont(col, font)
|
|
||||||
self.addTopLevelItem(group)
|
|
||||||
self._groups[name] = group
|
|
||||||
return group
|
|
||||||
|
|
||||||
def update_argument(self, name, argument):
|
|
||||||
widgets = self._arg_to_widgets[name]
|
|
||||||
|
|
||||||
# Qt needs a setItemWidget() to handle layout correctly,
|
|
||||||
# simply replacing the entry inside the LayoutWidget
|
|
||||||
# results in a bug.
|
|
||||||
|
|
||||||
widgets["entry"].deleteLater()
|
|
||||||
widgets["entry"] = procdesc_to_entry(argument["desc"])(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 _recompute_argument_clicked(self, name):
|
|
||||||
asyncio.ensure_future(self._recompute_argument(name))
|
|
||||||
|
|
||||||
async def _recompute_argument(self, name):
|
async def _recompute_argument(self, name):
|
||||||
try:
|
try:
|
||||||
@ -187,30 +77,6 @@ class _ArgumentEditor(QtWidgets.QTreeWidget):
|
|||||||
argument["state"] = state
|
argument["state"] = state
|
||||||
self.update_argument(name, argument)
|
self.update_argument(name, argument)
|
||||||
|
|
||||||
def _disable_other_scans(self, current_name):
|
|
||||||
for name, widgets in self._arg_to_widgets.items():
|
|
||||||
if (name != current_name
|
|
||||||
and isinstance(widgets["entry"], ScanEntry)):
|
|
||||||
widgets["entry"].disable()
|
|
||||||
|
|
||||||
def save_state(self):
|
|
||||||
expanded = []
|
|
||||||
for k, v in self._groups.items():
|
|
||||||
if v.isExpanded():
|
|
||||||
expanded.append(k)
|
|
||||||
return {
|
|
||||||
"expanded": expanded,
|
|
||||||
"scroll": self.verticalScrollBar().value()
|
|
||||||
}
|
|
||||||
|
|
||||||
def restore_state(self, state):
|
|
||||||
for e in state["expanded"]:
|
|
||||||
try:
|
|
||||||
self._groups[e].setExpanded(True)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
self.verticalScrollBar().setValue(state["scroll"])
|
|
||||||
|
|
||||||
# Hooks that allow user-supplied argument editors to react to imminent user
|
# Hooks that allow user-supplied argument editors to react to imminent user
|
||||||
# actions. Here, we always keep the manager-stored submission arguments
|
# actions. Here, we always keep the manager-stored submission arguments
|
||||||
# up-to-date, so no further action is required.
|
# up-to-date, so no further action is required.
|
||||||
|
Loading…
Reference in New Issue
Block a user