forked from M-Labs/artiq
1
0
Fork 0
artiq/artiq/gui/datasets.py

170 lines
5.5 KiB
Python
Raw Normal View History

2015-07-14 23:31:18 +08:00
import asyncio
2015-07-17 02:52:53 +08:00
from collections import OrderedDict
from functools import partial
2015-08-01 19:37:16 +08:00
import logging
2015-07-14 23:31:18 +08:00
from quamash import QtGui, QtCore
from pyqtgraph import dockarea
from pyqtgraph import LayoutWidget
from artiq.protocols.sync_struct import Subscriber
from artiq.tools import short_format
from artiq.gui.tools import DictSyncModel
2015-07-17 02:52:53 +08:00
from artiq.gui.displays import *
2015-07-14 23:31:18 +08:00
try:
QSortFilterProxyModel = QtCore.QSortFilterProxyModel
except AttributeError:
QSortFilterProxyModel = QtGui.QSortFilterProxyModel
2015-07-14 23:31:18 +08:00
2015-08-01 19:37:16 +08:00
logger = logging.getLogger(__name__)
class DatasetsModel(DictSyncModel):
2015-07-14 23:31:18 +08:00
def __init__(self, parent, init):
DictSyncModel.__init__(self, ["Dataset", "Persistent", "Value"],
2015-07-14 23:31:18 +08:00
parent, init)
def sort_key(self, k, v):
return k
def convert(self, k, v, column):
if column == 0:
return k
elif column == 1:
return "Y" if v[0] else "N"
elif column == 2:
return short_format(v[1])
2015-07-14 23:31:18 +08:00
else:
raise ValueError
2015-08-01 19:37:16 +08:00
def _get_display_type_name(display_cls):
for name, (_, cls) in display_types.items():
if cls is display_cls:
return name
class DatasetsDock(dockarea.Dock):
2015-07-17 02:52:53 +08:00
def __init__(self, dialog_parent, dock_area):
dockarea.Dock.__init__(self, "Datasets", size=(1500, 500))
2015-07-17 02:52:53 +08:00
self.dialog_parent = dialog_parent
self.dock_area = dock_area
2015-07-14 23:31:18 +08:00
grid = LayoutWidget()
self.addWidget(grid)
2015-10-12 17:31:55 +08:00
self.search = QtGui.QLineEdit()
self.search.setPlaceholderText("search...")
self.search.editingFinished.connect(self._search_datasets)
2015-10-30 19:58:15 +08:00
grid.addWidget(self.search, 0, 0)
2015-10-12 17:31:55 +08:00
2015-07-14 23:31:18 +08:00
self.table = QtGui.QTableView()
2015-07-15 01:08:08 +08:00
self.table.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
2015-07-23 22:36:52 +08:00
self.table.horizontalHeader().setResizeMode(
QtGui.QHeaderView.ResizeToContents)
2015-10-12 17:31:55 +08:00
grid.addWidget(self.table, 1, 0)
2015-07-14 23:31:18 +08:00
add_display_box = QtGui.QGroupBox("Add display")
2015-10-12 17:31:55 +08:00
grid.addWidget(add_display_box, 1, 1)
2015-07-14 23:31:18 +08:00
display_grid = QtGui.QGridLayout()
add_display_box.setLayout(display_grid)
2015-07-17 02:52:53 +08:00
for n, name in enumerate(display_types.keys()):
2015-07-14 23:31:18 +08:00
btn = QtGui.QPushButton(name)
display_grid.addWidget(btn, n, 0)
2015-07-17 02:52:53 +08:00
btn.clicked.connect(partial(self.create_dialog, name))
self.displays = dict()
2015-07-14 23:31:18 +08:00
2015-10-12 17:31:55 +08:00
def _search_datasets(self):
self.table_model_filter.setFilterFixedString(self.search.displayText())
2015-10-12 17:31:55 +08:00
def get_dataset(self, key):
return self.table_model.backing_store[key][1]
2015-07-25 00:36:16 +08:00
2015-10-03 19:28:57 +08:00
async def sub_connect(self, host, port):
self.subscriber = Subscriber("datasets", self.init_datasets_model,
2015-07-17 02:52:53 +08:00
self.on_mod)
2015-10-03 19:28:57 +08:00
await self.subscriber.connect(host, port)
2015-07-14 23:31:18 +08:00
2015-10-03 19:28:57 +08:00
async def sub_close(self):
await self.subscriber.close()
2015-07-14 23:31:18 +08:00
def init_datasets_model(self, init):
self.table_model = DatasetsModel(self.table, init)
self.table_model_filter = QSortFilterProxyModel()
self.table_model_filter.setSourceModel(self.table_model)
self.table.setModel(self.table_model_filter)
2015-07-17 02:52:53 +08:00
return self.table_model
def update_display_data(self, dsp):
filtered_data = {k: self.table_model.backing_store[k][1]
for k in dsp.data_sources()
if k in self.table_model.backing_store}
dsp.update_data(filtered_data)
2015-07-17 02:52:53 +08:00
def on_mod(self, mod):
if mod["action"] == "init":
for display in self.displays.values():
display.update_data(self.table_model.backing_store)
return
2015-10-26 00:32:49 +08:00
if mod["path"]:
2015-07-17 02:52:53 +08:00
source = mod["path"][0]
2015-10-26 00:32:49 +08:00
elif mod["action"] == "setitem":
source = mod["key"]
2015-07-17 02:52:53 +08:00
else:
return
for display in self.displays.values():
if source in display.data_sources():
self.update_display_data(display)
2015-07-17 02:52:53 +08:00
def create_dialog(self, ty):
dlg_class = display_types[ty][0]
dlg = dlg_class(self.dialog_parent, None, dict(),
sorted(self.table_model.backing_store.keys()),
partial(self.create_display, ty, None))
dlg.open()
def create_display(self, ty, prev_name, name, settings):
if prev_name is not None and prev_name in self.displays:
raise NotImplementedError
dsp_class = display_types[ty][1]
dsp = dsp_class(name, settings)
self.displays[name] = dsp
self.update_display_data(dsp)
2015-07-17 02:52:53 +08:00
def on_close():
del self.displays[name]
dsp.sigClosed.connect(on_close)
self.dock_area.addDock(dsp)
self.dock_area.floatDock(dsp)
return dsp
2015-08-01 19:37:16 +08:00
def save_state(self):
r = dict()
for name, display in self.displays.items():
r[name] = {
"ty": _get_display_type_name(type(display)),
"settings": display.settings,
"state": display.save_state()
2015-08-01 19:37:16 +08:00
}
return r
def restore_state(self, state):
for name, desc in state.items():
try:
dsp = self.create_display(desc["ty"], None, name,
desc["settings"])
2015-08-01 19:37:16 +08:00
except:
logger.warning("Failed to create display '%s'", name,
exc_info=True)
try:
dsp.restore_state(desc["state"])
except:
logger.warning("Failed to restore display state of '%s'",
name, exc_info=True)