mirror of https://github.com/m-labs/artiq.git
gui: reorganize experiment/entry code
This commit is contained in:
parent
6a972eb591
commit
e2c7578e48
|
@ -10,6 +10,100 @@ from artiq.gui.tools import disable_scroll_wheel
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class _StringEntry(QtGui.QLineEdit):
|
||||||
|
def __init__(self, argument):
|
||||||
|
QtGui.QLineEdit.__init__(self)
|
||||||
|
self.setText(argument["state"])
|
||||||
|
def update(text):
|
||||||
|
argument["state"] = text
|
||||||
|
self.textEdited.connect(update)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def state_to_value(state):
|
||||||
|
return state
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def default_state(procdesc):
|
||||||
|
return procdesc.get("default", "")
|
||||||
|
|
||||||
|
|
||||||
|
class _BooleanEntry(QtGui.QCheckBox):
|
||||||
|
def __init__(self, argument):
|
||||||
|
QtGui.QCheckBox.__init__(self)
|
||||||
|
self.setChecked(argument["state"])
|
||||||
|
def update(checked):
|
||||||
|
argument["state"] = bool(checked)
|
||||||
|
self.stateChanged.connect(update)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def state_to_value(state):
|
||||||
|
return state
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def default_state(procdesc):
|
||||||
|
return procdesc.get("default", False)
|
||||||
|
|
||||||
|
|
||||||
|
class _EnumerationEntry(QtGui.QComboBox):
|
||||||
|
def __init__(self, argument):
|
||||||
|
QtGui.QComboBox.__init__(self)
|
||||||
|
disable_scroll_wheel(self)
|
||||||
|
choices = argument["desc"]["choices"]
|
||||||
|
self.addItems(choices)
|
||||||
|
idx = choices.index(argument["state"])
|
||||||
|
self.setCurrentIndex(idx)
|
||||||
|
def update(index):
|
||||||
|
argument["state"] = choices[index]
|
||||||
|
self.currentIndexChanged.connect(update)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def state_to_value(state):
|
||||||
|
return state
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def default_state(procdesc):
|
||||||
|
if "default" in procdesc:
|
||||||
|
return procdesc["default"]
|
||||||
|
else:
|
||||||
|
return procdesc["choices"][0]
|
||||||
|
|
||||||
|
|
||||||
|
class _NumberEntry(QtGui.QDoubleSpinBox):
|
||||||
|
def __init__(self, argument):
|
||||||
|
QtGui.QDoubleSpinBox.__init__(self)
|
||||||
|
disable_scroll_wheel(self)
|
||||||
|
procdesc = argument["desc"]
|
||||||
|
scale = procdesc["scale"]
|
||||||
|
self.setDecimals(procdesc["ndecimals"])
|
||||||
|
self.setSingleStep(procdesc["step"]/scale)
|
||||||
|
if procdesc["min"] is not None:
|
||||||
|
self.setMinimum(procdesc["min"]/scale)
|
||||||
|
else:
|
||||||
|
self.setMinimum(float("-inf"))
|
||||||
|
if procdesc["max"] is not None:
|
||||||
|
self.setMaximum(procdesc["max"]/scale)
|
||||||
|
else:
|
||||||
|
self.setMaximum(float("inf"))
|
||||||
|
if procdesc["unit"]:
|
||||||
|
self.setSuffix(" " + procdesc["unit"])
|
||||||
|
|
||||||
|
self.setValue(argument["state"]/scale)
|
||||||
|
def update(value):
|
||||||
|
argument["state"] = value*scale
|
||||||
|
self.valueChanged.connect(update)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def state_to_value(state):
|
||||||
|
return state
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def default_state(procdesc):
|
||||||
|
if "default" in procdesc:
|
||||||
|
return procdesc["default"]
|
||||||
|
else:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
class _NoScan(LayoutWidget):
|
class _NoScan(LayoutWidget):
|
||||||
def __init__(self, procdesc, state):
|
def __init__(self, procdesc, state):
|
||||||
LayoutWidget.__init__(self)
|
LayoutWidget.__init__(self)
|
||||||
|
@ -38,7 +132,7 @@ class _NoScan(LayoutWidget):
|
||||||
self.value.valueChanged.connect(update)
|
self.value.valueChanged.connect(update)
|
||||||
|
|
||||||
|
|
||||||
class _Range(LayoutWidget):
|
class _RangeScan(LayoutWidget):
|
||||||
def __init__(self, procdesc, state):
|
def __init__(self, procdesc, state):
|
||||||
LayoutWidget.__init__(self)
|
LayoutWidget.__init__(self)
|
||||||
|
|
||||||
|
@ -90,7 +184,8 @@ class _Range(LayoutWidget):
|
||||||
self.max.valueChanged.connect(update_max)
|
self.max.valueChanged.connect(update_max)
|
||||||
self.npoints.valueChanged.connect(update_npoints)
|
self.npoints.valueChanged.connect(update_npoints)
|
||||||
|
|
||||||
class _Explicit(LayoutWidget):
|
|
||||||
|
class _ExplicitScan(LayoutWidget):
|
||||||
def __init__(self, state):
|
def __init__(self, state):
|
||||||
LayoutWidget.__init__(self)
|
LayoutWidget.__init__(self)
|
||||||
|
|
||||||
|
@ -109,7 +204,7 @@ class _Explicit(LayoutWidget):
|
||||||
self.value.textEdited.connect(update)
|
self.value.textEdited.connect(update)
|
||||||
|
|
||||||
|
|
||||||
class ScanController(LayoutWidget):
|
class _ScanEntry(LayoutWidget):
|
||||||
def __init__(self, argument):
|
def __init__(self, argument):
|
||||||
LayoutWidget.__init__(self)
|
LayoutWidget.__init__(self)
|
||||||
self.argument = argument
|
self.argument = argument
|
||||||
|
@ -121,9 +216,9 @@ class ScanController(LayoutWidget):
|
||||||
state = argument["state"]
|
state = argument["state"]
|
||||||
self.widgets = OrderedDict()
|
self.widgets = OrderedDict()
|
||||||
self.widgets["NoScan"] = _NoScan(procdesc, state["NoScan"])
|
self.widgets["NoScan"] = _NoScan(procdesc, state["NoScan"])
|
||||||
self.widgets["LinearScan"] = _Range(procdesc, state["LinearScan"])
|
self.widgets["LinearScan"] = _RangeScan(procdesc, state["LinearScan"])
|
||||||
self.widgets["RandomScan"] = _Range(procdesc, state["RandomScan"])
|
self.widgets["RandomScan"] = _RangeScan(procdesc, state["RandomScan"])
|
||||||
self.widgets["ExplicitScan"] = _Explicit(state["ExplicitScan"])
|
self.widgets["ExplicitScan"] = _ExplicitScan(state["ExplicitScan"])
|
||||||
for widget in self.widgets.values():
|
for widget in self.widgets.values():
|
||||||
self.stack.addWidget(widget)
|
self.stack.addWidget(widget)
|
||||||
|
|
||||||
|
@ -181,3 +276,13 @@ class ScanController(LayoutWidget):
|
||||||
self.stack.setCurrentWidget(self.widgets[ty])
|
self.stack.setCurrentWidget(self.widgets[ty])
|
||||||
self.argument["state"]["selected"] = ty
|
self.argument["state"]["selected"] = ty
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
argty_to_entry = {
|
||||||
|
"PYONValue": _StringEntry,
|
||||||
|
"BooleanValue": _BooleanEntry,
|
||||||
|
"EnumerationValue": _EnumerationEntry,
|
||||||
|
"NumberValue": _NumberEntry,
|
||||||
|
"StringValue": _StringEntry,
|
||||||
|
"Scannable": _ScanEntry
|
||||||
|
}
|
|
@ -7,117 +7,13 @@ from quamash import QtGui, QtCore
|
||||||
|
|
||||||
from pyqtgraph import dockarea, LayoutWidget
|
from pyqtgraph import dockarea, LayoutWidget
|
||||||
|
|
||||||
from artiq.gui.tools import log_level_to_name, disable_scroll_wheel
|
from artiq.gui.tools import log_level_to_name
|
||||||
from artiq.gui.scan import ScanController
|
from artiq.gui.entries import argty_to_entry
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class _StringEntry(QtGui.QLineEdit):
|
|
||||||
def __init__(self, argument):
|
|
||||||
QtGui.QLineEdit.__init__(self)
|
|
||||||
self.setText(argument["state"])
|
|
||||||
def update(text):
|
|
||||||
argument["state"] = text
|
|
||||||
self.textEdited.connect(update)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_to_value(state):
|
|
||||||
return state
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def default_state(procdesc):
|
|
||||||
return procdesc.get("default", "")
|
|
||||||
|
|
||||||
|
|
||||||
class _BooleanEntry(QtGui.QCheckBox):
|
|
||||||
def __init__(self, argument):
|
|
||||||
QtGui.QCheckBox.__init__(self)
|
|
||||||
self.setChecked(argument["state"])
|
|
||||||
def update(checked):
|
|
||||||
argument["state"] = bool(checked)
|
|
||||||
self.stateChanged.connect(update)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_to_value(state):
|
|
||||||
return state
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def default_state(procdesc):
|
|
||||||
return procdesc.get("default", False)
|
|
||||||
|
|
||||||
|
|
||||||
class _EnumerationEntry(QtGui.QComboBox):
|
|
||||||
def __init__(self, argument):
|
|
||||||
QtGui.QComboBox.__init__(self)
|
|
||||||
disable_scroll_wheel(self)
|
|
||||||
choices = argument["desc"]["choices"]
|
|
||||||
self.addItems(choices)
|
|
||||||
idx = choices.index(argument["state"])
|
|
||||||
self.setCurrentIndex(idx)
|
|
||||||
def update(index):
|
|
||||||
argument["state"] = choices[index]
|
|
||||||
self.currentIndexChanged.connect(update)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_to_value(state):
|
|
||||||
return state
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def default_state(procdesc):
|
|
||||||
if "default" in procdesc:
|
|
||||||
return procdesc["default"]
|
|
||||||
else:
|
|
||||||
return procdesc["choices"][0]
|
|
||||||
|
|
||||||
|
|
||||||
class _NumberEntry(QtGui.QDoubleSpinBox):
|
|
||||||
def __init__(self, argument):
|
|
||||||
QtGui.QDoubleSpinBox.__init__(self)
|
|
||||||
disable_scroll_wheel(self)
|
|
||||||
procdesc = argument["desc"]
|
|
||||||
scale = procdesc["scale"]
|
|
||||||
self.setDecimals(procdesc["ndecimals"])
|
|
||||||
self.setSingleStep(procdesc["step"]/scale)
|
|
||||||
if procdesc["min"] is not None:
|
|
||||||
self.setMinimum(procdesc["min"]/scale)
|
|
||||||
else:
|
|
||||||
self.setMinimum(float("-inf"))
|
|
||||||
if procdesc["max"] is not None:
|
|
||||||
self.setMaximum(procdesc["max"]/scale)
|
|
||||||
else:
|
|
||||||
self.setMaximum(float("inf"))
|
|
||||||
if procdesc["unit"]:
|
|
||||||
self.setSuffix(" " + procdesc["unit"])
|
|
||||||
|
|
||||||
self.setValue(argument["state"]/scale)
|
|
||||||
def update(value):
|
|
||||||
argument["state"] = value*scale
|
|
||||||
self.valueChanged.connect(update)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_to_value(state):
|
|
||||||
return state
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def default_state(procdesc):
|
|
||||||
if "default" in procdesc:
|
|
||||||
return procdesc["default"]
|
|
||||||
else:
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
|
|
||||||
_argty_to_entry = {
|
|
||||||
"PYONValue": _StringEntry,
|
|
||||||
"BooleanValue": _BooleanEntry,
|
|
||||||
"EnumerationValue": _EnumerationEntry,
|
|
||||||
"NumberValue": _NumberEntry,
|
|
||||||
"StringValue": _StringEntry,
|
|
||||||
"Scannable": ScanController
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Experiment URLs come in two forms:
|
# Experiment URLs come in two forms:
|
||||||
# 1. repo:<experiment name>
|
# 1. repo:<experiment name>
|
||||||
# (file name and class name to be retrieved from explist)
|
# (file name and class name to be retrieved from explist)
|
||||||
|
@ -153,7 +49,7 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
||||||
self.addTopLevelItem(QtGui.QTreeWidgetItem(["No arguments"]))
|
self.addTopLevelItem(QtGui.QTreeWidgetItem(["No arguments"]))
|
||||||
|
|
||||||
for name, argument in arguments.items():
|
for name, argument in arguments.items():
|
||||||
entry = _argty_to_entry[argument["desc"]["ty"]](argument)
|
entry = argty_to_entry[argument["desc"]["ty"]](argument)
|
||||||
widget_item = QtGui.QTreeWidgetItem([name])
|
widget_item = QtGui.QTreeWidgetItem([name])
|
||||||
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
||||||
|
|
||||||
|
@ -211,14 +107,14 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
||||||
argument = self.manager.get_submission_arguments(self.expurl)[name]
|
argument = self.manager.get_submission_arguments(self.expurl)[name]
|
||||||
|
|
||||||
procdesc = arginfo[name][0]
|
procdesc = arginfo[name][0]
|
||||||
state = _argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
state = argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
||||||
argument["desc"] = procdesc
|
argument["desc"] = procdesc
|
||||||
argument["state"] = state
|
argument["state"] = state
|
||||||
|
|
||||||
old_entry, widget_item = self._arg_to_entry_widgetitem[name]
|
old_entry, widget_item = self._arg_to_entry_widgetitem[name]
|
||||||
old_entry.deleteLater()
|
old_entry.deleteLater()
|
||||||
|
|
||||||
entry = _argty_to_entry[procdesc["ty"]](argument)
|
entry = argty_to_entry[procdesc["ty"]](argument)
|
||||||
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
||||||
self.setItemWidget(widget_item, 1, entry)
|
self.setItemWidget(widget_item, 1, entry)
|
||||||
|
|
||||||
|
@ -466,7 +362,7 @@ class ExperimentManager:
|
||||||
def initialize_submission_arguments(self, expurl, arginfo):
|
def initialize_submission_arguments(self, expurl, arginfo):
|
||||||
arguments = OrderedDict()
|
arguments = OrderedDict()
|
||||||
for name, (procdesc, group) in arginfo.items():
|
for name, (procdesc, group) in arginfo.items():
|
||||||
state = _argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
state = argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
||||||
arguments[name] = {
|
arguments[name] = {
|
||||||
"desc": procdesc,
|
"desc": procdesc,
|
||||||
"group": group,
|
"group": group,
|
||||||
|
@ -510,7 +406,7 @@ class ExperimentManager:
|
||||||
|
|
||||||
argument_values = dict()
|
argument_values = dict()
|
||||||
for name, argument in arguments.items():
|
for name, argument in arguments.items():
|
||||||
entry_cls = _argty_to_entry[argument["desc"]["ty"]]
|
entry_cls = argty_to_entry[argument["desc"]["ty"]]
|
||||||
argument_values[name] = entry_cls.state_to_value(argument["state"])
|
argument_values[name] = entry_cls.state_to_value(argument["state"])
|
||||||
|
|
||||||
expid = {
|
expid = {
|
||||||
|
|
Loading…
Reference in New Issue