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: 84b07607adfd
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: d5f2f5c062e7
Choose a head ref
  • 9 commits
  • 11 files changed
  • 1 contributor

Commits on Aug 24, 2015

  1. Copy the full SHA
    45a90bf View commit details
  2. Copy the full SHA
    7d4d92e View commit details
  3. Copy the full SHA
    bb228b0 View commit details
  4. Copy the full SHA
    1ad8e65 View commit details
  5. Copy the full SHA
    b7120aa View commit details
  6. Copy the full SHA
    1c96f25 View commit details
  7. Copy the full SHA
    718de98 View commit details
  8. Copy the full SHA
    e043179 View commit details
  9. gui: fix spinbox bounds

    sbourdeauducq committed Aug 24, 2015
    Copy the full SHA
    d5f2f5c View commit details
6 changes: 3 additions & 3 deletions artiq/frontend/artiq_gui.py
Original file line number Diff line number Diff line change
@@ -45,10 +45,10 @@ def get_argparser():


class MainWindow(QtGui.QMainWindow):
def __init__(self, app):
def __init__(self, app, server):
QtGui.QMainWindow.__init__(self)
self.setWindowIcon(QtGui.QIcon(os.path.join(data_dir, "icon.png")))
self.setWindowTitle("ARTIQ")
self.setWindowTitle("ARTIQ - {}".format(server))
self.exit_request = asyncio.Event()

def closeEvent(self, *args):
@@ -77,7 +77,7 @@ def main():
args.server, args.port_control, "master_schedule"))
atexit.register(lambda: schedule_ctl.close_rpc())

win = MainWindow(app)
win = MainWindow(app, args.server)
area = dockarea.DockArea()
smgr.register(area)
smgr.register(win)
97 changes: 74 additions & 23 deletions artiq/gui/explorer.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@

from artiq.protocols.sync_struct import Subscriber
from artiq.protocols import pyon
from artiq.gui.tools import DictSyncModel, force_spinbox_value
from artiq.gui.tools import DictSyncModel
from artiq.gui.scan import ScanController


@@ -74,12 +74,17 @@ def set_argument_value(self, value):
class _NumberEntry(QtGui.QDoubleSpinBox):
def __init__(self, procdesc):
QtGui.QDoubleSpinBox.__init__(self)
self.setDecimals(procdesc["ndecimals"])
if procdesc["step"] is not None:
self.setSingleStep(procdesc["step"])
if procdesc["min"] is not None:
self.setMinimum(procdesc["min"])
else:
self.setMinimum(float("-inf"))
if procdesc["max"] is not None:
self.setMaximum(procdesc["max"])
else:
self.setMaximum(float("inf"))
if procdesc["unit"]:
self.setSuffix(" " + procdesc["unit"])
if "default" in procdesc:
@@ -89,7 +94,7 @@ def get_argument_value(self):
return self.value()

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


class _StringEntry(QtGui.QLineEdit):
@@ -115,21 +120,54 @@ def set_argument_value(self, value):
}


class _ArgumentSetter(LayoutWidget):
def __init__(self, dialog_parent, arguments):
LayoutWidget.__init__(self)
class _ArgumentEditor(QtGui.QTreeWidget):
def __init__(self, dialog_parent):
QtGui.QTreeWidget.__init__(self)
self.setColumnCount(2)
self.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.header().setVisible(False)
self.setSelectionMode(QtGui.QAbstractItemView.NoSelection)

self.dialog_parent = dialog_parent
self._groups = dict()
self.set_arguments([])

def clear(self):
QtGui.QTreeWidget.clear(self)
self._groups.clear()

def _get_group(self, name):
if name in self._groups:
return self._groups[name]
group = QtGui.QTreeWidgetItem([name, ""])
for c in 0, 1:
group.setBackground(c, QtGui.QBrush(QtGui.QColor(100, 100, 100)))
group.setForeground(c, QtGui.QBrush(QtGui.QColor(220, 220, 255)))
font = group.font(c)
font.setBold(True)
group.setFont(c, font)
self.addTopLevelItem(group)
self._groups[name] = group
return group

def set_arguments(self, arguments):
self.clear()

if not arguments:
self.addWidget(QtGui.QLabel("No arguments"), 0, 0)
self.addTopLevelItem(QtGui.QTreeWidgetItem(["No arguments", ""]))

self._args_to_entries = dict()
for n, (name, procdesc) in enumerate(arguments):
self.addWidget(QtGui.QLabel(name), n, 0)
for n, (name, (procdesc, group)) in enumerate(arguments):
entry = _procty_to_entry[procdesc["ty"]](procdesc)
self.addWidget(entry, n, 1)
self._args_to_entries[name] = entry

widget_item = QtGui.QTreeWidgetItem([name, ""])
if group is None:
self.addTopLevelItem(widget_item)
else:
self._get_group(group).addChild(widget_item)
self.setItemWidget(widget_item, 1, entry)

def get_argument_values(self, show_error_message):
r = dict()
for arg, entry in self._args_to_entries.items():
@@ -155,6 +193,25 @@ def set_argument_values(self, arguments, ignore_errors):
if not ignore_errors:
raise

def save_state(self):
expanded = []
for k, v in self._groups.items():
if v.isExpanded():
expanded.append(k)
argument_values = self.get_argument_values(False)
return {
"expanded": expanded,
"argument_values": argument_values
}

def restore_state(self, state):
self.set_argument_values(state["argument_values"], True)
for e in state["expanded"]:
try:
self._groups[e].setExpanded(True)
except KeyError:
pass


class ExplorerDock(dockarea.Dock):
def __init__(self, dialog_parent, status_bar, schedule_ctl):
@@ -201,27 +258,21 @@ def __init__(self, dialog_parent, status_bar, schedule_ctl):
grid.addWidget(submit, 3, 0, colspan=4)
submit.clicked.connect(self.submit_clicked)

self.argsetter = _ArgumentSetter(self.dialog_parent, [])
self.splitter.addWidget(self.argsetter)
self.argeditor = _ArgumentEditor(self.dialog_parent)
self.splitter.addWidget(self.argeditor)
self.splitter.setSizes([grid.minimumSizeHint().width(), 1000])
self.state = dict()

def update_selection(self, selected, deselected):
if deselected:
self.state[deselected] = self.argsetter.get_argument_values(False)
self.state[deselected] = self.argeditor.save_state()

if selected:
expinfo = self.explist_model.backing_store[selected]
arguments = expinfo["arguments"]
sizes = self.splitter.sizes()
self.argsetter.deleteLater()
self.argsetter = _ArgumentSetter(self.dialog_parent, arguments)
self.argeditor.set_arguments(expinfo["arguments"])
if selected in self.state:
arguments = self.state[selected]
if arguments is not None:
self.argsetter.set_argument_values(arguments, True)
self.splitter.insertWidget(1, self.argsetter)
self.splitter.setSizes(sizes)
self.argeditor.restore_state(self.state[selected])
self.splitter.insertWidget(1, self.argeditor)
self.selected_key = selected

def _sel_to_key(self, selection):
@@ -241,7 +292,7 @@ def save_state(self):
if idx:
row = idx[0].row()
key = self.explist_model.row_to_key[row]
self.state[key] = self.argsetter.get_argument_values(False)
self.state[key] = self.argeditor.save_state()
return self.state

def restore_state(self, state):
@@ -285,7 +336,7 @@ def submit_clicked(self):
due_date = self.datetime.dateTime().toMSecsSinceEpoch()/1000
else:
due_date = None
arguments = self.argsetter.get_argument_values(True)
arguments = self.argeditor.get_argument_values(True)
if arguments is None:
return
asyncio.async(self.submit(self.pipeline.text(),
2 changes: 1 addition & 1 deletion artiq/gui/parameters.py
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ def __init__(self):
grid.addWidget(self.search, 0, 0)

self.table = QtGui.QTableView()
self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.table.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
self.table.horizontalHeader().setResizeMode(
QtGui.QHeaderView.ResizeToContents)
grid.addWidget(self.table, 1, 0)
27 changes: 18 additions & 9 deletions artiq/gui/scan.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
from quamash import QtGui
from pyqtgraph import LayoutWidget

from artiq.gui.tools import force_spinbox_value


class _Range(LayoutWidget):
def __init__(self, global_min, global_max, global_step, unit):
def __init__(self, global_min, global_max, global_step, unit, ndecimals):
LayoutWidget.__init__(self)

def apply_properties(spinbox):
spinbox.setDecimals(ndecimals)
if global_min is not None:
spinbox.setMinimum(global_min)
else:
spinbox.setMinimum(float("-inf"))
if global_max is not None:
spinbox.setMaximum(global_max)
else:
spinbox.setMaximum(float("inf"))
if global_step is not None:
spinbox.setSingleStep(global_step)
if unit:
@@ -35,9 +38,9 @@ def apply_properties(spinbox):
self.addWidget(self.npoints, 0, 5)

def set_values(self, min, max, npoints):
force_spinbox_value(self.min, min)
force_spinbox_value(self.max, max)
force_spinbox_value(self.npoints, npoints)
self.min.setValue(min)
self.max.setValue(max)
self.npoints.setValue(npoints)

def get_values(self):
min = self.min.value()
@@ -61,12 +64,18 @@ def __init__(self, procdesc):
gmin, gmax = procdesc["global_min"], procdesc["global_max"]
gstep = procdesc["global_step"]
unit = procdesc["unit"]
ndecimals = procdesc["ndecimals"]

self.v_noscan = QtGui.QDoubleSpinBox()
self.v_noscan.setDecimals(ndecimals)
if gmin is not None:
self.v_noscan.setMinimum(gmin)
else:
self.v_noscan.setMinimum(float("-inf"))
if gmax is not None:
self.v_noscan.setMaximum(gmax)
else:
self.v_noscan.setMaximum(float("inf"))
if gstep is not None:
self.v_noscan.setSingleStep(gstep)
if unit:
@@ -76,10 +85,10 @@ def __init__(self, procdesc):
self.v_noscan_gr.addWidget(self.v_noscan, 0, 1)
self.stack.addWidget(self.v_noscan_gr)

self.v_linear = _Range(gmin, gmax, gstep, unit)
self.v_linear = _Range(gmin, gmax, gstep, unit, ndecimals)
self.stack.addWidget(self.v_linear)

self.v_random = _Range(gmin, gmax, gstep, unit)
self.v_random = _Range(gmin, gmax, gstep, unit, ndecimals)
self.stack.addWidget(self.v_random)

self.v_explicit = QtGui.QLineEdit()
@@ -132,7 +141,7 @@ def get_argument_value(self):
def set_argument_value(self, d):
if d["ty"] == "NoScan":
self.noscan.setChecked(True)
force_spinbox_value(self.v_noscan, d["value"])
self.v_noscan.setValue(d["value"])
elif d["ty"] == "LinearScan":
self.linear.setChecked(True)
self.v_linear.set_values(d["min"], d["max"], d["npoints"])
8 changes: 0 additions & 8 deletions artiq/gui/tools.py
Original file line number Diff line number Diff line change
@@ -37,14 +37,6 @@ def short_format(v):
return r


def force_spinbox_value(spinbox, value):
if spinbox.minimum() > value:
spinbox.setMinimum(value)
if spinbox.maximum() < value:
spinbox.setMaximum(value)
spinbox.setValue(value)


class _SyncSubstruct:
def __init__(self, update_cb, ref):
self.update_cb = update_cb
Loading