Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8f2dfcd08e6c
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: cddb5b9ae4f8
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Aug 5, 2015

  1. Copy the full SHA
    c8db83b View commit details
  2. Copy the full SHA
    cddb5b9 View commit details
Showing with 86 additions and 34 deletions.
  1. +6 −1 artiq/frontend/artiq_gui.py
  2. +62 −19 artiq/gui/explorer.py
  3. +18 −14 artiq/gui/scan.py
7 changes: 6 additions & 1 deletion artiq/frontend/artiq_gui.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
from quamash import QEventLoop, QtGui
from pyqtgraph import dockarea

from artiq.tools import verbosity_args, init_logger
from artiq.protocols.pc_rpc import AsyncioClient
from artiq.gui.state import StateManager
from artiq.gui.explorer import ExplorerDock
@@ -39,6 +40,7 @@ def get_argparser():
parser.add_argument(
"--db-file", default="artiq_gui.pyon",
help="database file for local GUI settings")
verbosity_args(parser)
return parser


@@ -55,12 +57,14 @@ def closeEvent(self, *args):


def main():
args = get_argparser().parse_args()
init_logger(args)

app = QtGui.QApplication([])
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
atexit.register(lambda: loop.close())

args = get_argparser().parse_args()
smgr = StateManager(args.db_file)

schedule_ctl = AsyncioClient()
@@ -77,6 +81,7 @@ def main():
win.setStatusBar(status_bar)

d_explorer = ExplorerDock(win, status_bar, schedule_ctl)
smgr.register(d_explorer)
loop.run_until_complete(d_explorer.sub_connect(
args.server, args.port_notify))
atexit.register(lambda: loop.run_until_complete(d_explorer.sub_close()))
81 changes: 62 additions & 19 deletions artiq/gui/explorer.py
Original file line number Diff line number Diff line change
@@ -28,38 +28,43 @@ class _FreeValueEntry(QtGui.QLineEdit):
def __init__(self, procdesc):
QtGui.QLineEdit.__init__(self)
if "default" in procdesc:
self.insert(pyon.encode(procdesc["default"]))
self.set_argument_value(procdesc["default"])

def get_argument_value(self):
return pyon.decode(self.text())

def set_argument_value(self, value):
self.setText(pyon.encode(value))


class _BooleanEntry(QtGui.QCheckBox):
def __init__(self, procdesc):
QtGui.QCheckBox.__init__(self)
if "default" in procdesc:
self.setChecked(procdesc["default"])
self.set_argument_value(procdesc["default"])

def get_argument_value(self):
return self.isChecked()

def set_argument_value(self, value):
self.setChecked(value)


class _EnumerationEntry(QtGui.QComboBox):
def __init__(self, procdesc):
QtGui.QComboBox.__init__(self)
self.choices = procdesc["choices"]
self.addItems(self.choices)
if "default" in procdesc:
try:
idx = self.choices.index(procdesc["default"])
except:
pass
else:
self.setCurrentIndex(idx)
self.set_argument_value(procdesc["default"])

def get_argument_value(self):
return self.choices[self.currentIndex()]

def set_argument_value(self, value):
idx = self.choices.index(value)
self.setCurrentIndex(idx)


class _NumberEntry(QtGui.QDoubleSpinBox):
def __init__(self, procdesc):
@@ -73,21 +78,27 @@ def __init__(self, procdesc):
if procdesc["unit"]:
self.setSuffix(" " + procdesc["unit"])
if "default" in procdesc:
force_spinbox_value(self, procdesc["default"])
self.set_argument_value(procdesc["default"])

def get_argument_value(self):
return self.value()

def set_argument_value(self, value):
force_spinbox_value(self, value)


class _StringEntry(QtGui.QLineEdit):
def __init__(self, procdesc):
QtGui.QLineEdit.__init__(self)
if "default" in procdesc:
self.insert(procdesc["default"])
self.set_argument_value(procdesc["default"])

def get_argument_value(self):
return self.text()

def set_argument_value(self, value):
self.setText(value)


_procty_to_entry = {
"FreeValue": _FreeValueEntry,
@@ -114,21 +125,31 @@ def __init__(self, dialog_parent, arguments):
self.addWidget(entry, n, 1)
self._args_to_entries[name] = entry

def get_argument_values(self):
def get_argument_values(self, show_error_message):
r = dict()
for arg, entry in self._args_to_entries.items():
try:
r[arg] = entry.get_argument_value()
except:
msgbox = QtGui.QMessageBox(self.dialog_parent)
msgbox.setWindowTitle("Error")
msgbox.setText("Failed to obtain value for argument '{}'.\n{}"
.format(arg, traceback.format_exc()))
msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
msgbox.show()
if show_error_message:
msgbox = QtGui.QMessageBox(self.dialog_parent)
msgbox.setWindowTitle("Error")
msgbox.setText("Failed to obtain value for argument '{}'.\n{}"
.format(arg, traceback.format_exc()))
msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
msgbox.show()
return None
return r

def set_argument_values(self, arguments, ignore_errors):
for arg, value in arguments.items():
try:
entry = self._args_to_entries[arg]
entry.set_argument_value(value)
except:
if not ignore_errors:
raise


class ExplorerDock(dockarea.Dock):
def __init__(self, dialog_parent, status_bar, schedule_ctl):
@@ -163,7 +184,7 @@ def __init__(self, dialog_parent, status_bar, schedule_ctl):
grid.addWidget(self.priority, 1, 3)

self.pipeline = QtGui.QLineEdit()
self.pipeline.insert("main")
self.pipeline.setText("main")
grid.addWidget(QtGui.QLabel("Pipeline:"), 2, 0)
grid.addWidget(self.pipeline, 2, 1)

@@ -177,8 +198,15 @@ def __init__(self, dialog_parent, status_bar, schedule_ctl):
self.argsetter = _ArgumentSetter(self.dialog_parent, [])
self.splitter.addWidget(self.argsetter)
self.splitter.setSizes([grid.minimumSizeHint().width(), 1000])
self.state = dict()

def update_argsetter(self, selected, deselected):
deselected = deselected.indexes()
if deselected:
row = deselected[0].row()
key = self.explist_model.row_to_key[row]
self.state[key] = self.argsetter.get_argument_values(False)

selected = selected.indexes()
if selected:
row = selected[0].row()
@@ -188,9 +216,24 @@ def update_argsetter(self, selected, deselected):
sizes = self.splitter.sizes()
self.argsetter.deleteLater()
self.argsetter = _ArgumentSetter(self.dialog_parent, arguments)
if key in self.state:
arguments = self.state[key]
if arguments is not None:
self.argsetter.set_argument_values(arguments, True)
self.splitter.insertWidget(1, self.argsetter)
self.splitter.setSizes(sizes)

def save_state(self):
idx = self.el.selectedIndexes()
if idx:
row = idx[0].row()
key = self.explist_model.row_to_key[row]
self.state[key] = self.argsetter.get_argument_values(False)
return self.state

def restore_state(self, state):
self.state = state

def enable_duedate(self):
self.datetime_en.setChecked(True)

@@ -231,7 +274,7 @@ def submit_clicked(self):
due_date = self.datetime.dateTime().toMSecsSinceEpoch()/1000
else:
due_date = None
arguments = self.argsetter.get_argument_values()
arguments = self.argsetter.get_argument_values(True)
if arguments is None:
return
asyncio.async(self.submit(self.pipeline.text(),
32 changes: 18 additions & 14 deletions artiq/gui/scan.py
Original file line number Diff line number Diff line change
@@ -96,20 +96,7 @@ def __init__(self, procdesc):
b.toggled.connect(self.select_page)

if "default" in procdesc:
d = procdesc["default"]
if d["ty"] == "NoScan":
self.noscan.setChecked(True)
force_spinbox_value(self.v_noscan, d["value"])
elif d["ty"] == "LinearScan":
self.linear.setChecked(True)
self.v_linear.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "RandomScan":
self.random.setChecked(True)
self.v_random.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "ExplicitScan":
self.explicit.setChecked(True)
self.v_explicit.insert(" ".join(
[str(x) for x in d["sequence"]]))
self.set_argument_value(procdesc["default"])
else:
self.noscan.setChecked(True)

@@ -137,3 +124,20 @@ def get_argument_value(self):
elif self.explicit.isChecked():
sequence = [float(x) for x in self.v_explicit.text().split()]
return {"ty": "ExplicitScan", "sequence": sequence}

def set_argument_value(self, d):
if d["ty"] == "NoScan":
self.noscan.setChecked(True)
force_spinbox_value(self.v_noscan, d["value"])
elif d["ty"] == "LinearScan":
self.linear.setChecked(True)
self.v_linear.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "RandomScan":
self.random.setChecked(True)
self.v_random.set_values(d["min"], d["max"], d["npoints"])
elif d["ty"] == "ExplicitScan":
self.explicit.setChecked(True)
self.v_explicit.insert(" ".join(
[str(x) for x in d["sequence"]]))
else:
raise ValueError("Unknown scan type '{}'".format(d["ty"]))