forked from M-Labs/artiq
dashboard: basic dataset editing capabilities
This commit is contained in:
parent
c0e42bbfc8
commit
9a1cad5cec
|
@ -1,6 +1,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
from PyQt5 import QtCore, QtWidgets
|
from PyQt5 import QtCore, QtWidgets
|
||||||
|
|
||||||
from artiq.tools import short_format
|
from artiq.tools import short_format
|
||||||
|
@ -11,6 +12,77 @@ from artiq.gui.models import DictSyncTreeSepModel
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Editor(QtWidgets.QDialog):
|
||||||
|
def __init__(self, parent, dataset_ctl, key, value, persist):
|
||||||
|
QtWidgets.QDialog.__init__(self, parent=parent)
|
||||||
|
self.dataset_ctl = dataset_ctl
|
||||||
|
self.key = key
|
||||||
|
self.initial_type = type(value)
|
||||||
|
self.persist = persist
|
||||||
|
|
||||||
|
self.setWindowTitle("Edit dataset")
|
||||||
|
grid = QtWidgets.QGridLayout()
|
||||||
|
self.setLayout(grid)
|
||||||
|
|
||||||
|
grid.addWidget(QtWidgets.QLabel("Name:"), 0, 0)
|
||||||
|
grid.addWidget(QtWidgets.QLabel(key), 0, 1)
|
||||||
|
|
||||||
|
grid.addWidget(QtWidgets.QLabel("Value:"), 1, 0)
|
||||||
|
grid.addWidget(self.get_edit_widget(value), 1, 1)
|
||||||
|
|
||||||
|
buttons = QtWidgets.QDialogButtonBox(
|
||||||
|
QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
|
||||||
|
grid.setRowStretch(2, 1)
|
||||||
|
grid.addWidget(buttons, 3, 0, 1, 2)
|
||||||
|
buttons.accepted.connect(self.accept)
|
||||||
|
buttons.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
value = self.initial_type(self.get_edit_widget_value())
|
||||||
|
asyncio.ensure_future(self.dataset_ctl.set(
|
||||||
|
self.key, value, self.persist))
|
||||||
|
QtWidgets.QDialog.accept(self)
|
||||||
|
|
||||||
|
def get_edit_widget(self, initial_value):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def get_edit_widget_value(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class NumberEditor(Editor):
|
||||||
|
def get_edit_widget(self, initial_value):
|
||||||
|
self.edit_widget = QtWidgets.QDoubleSpinBox()
|
||||||
|
self.edit_widget.setMinimum(float("-inf"))
|
||||||
|
self.edit_widget.setMaximum(float("+inf"))
|
||||||
|
self.edit_widget.setDecimals(8)
|
||||||
|
self.edit_widget.setValue(float(initial_value))
|
||||||
|
return self.edit_widget
|
||||||
|
|
||||||
|
def get_edit_widget_value(self):
|
||||||
|
return self.edit_widget.value()
|
||||||
|
|
||||||
|
|
||||||
|
class BoolEditor(Editor):
|
||||||
|
def get_edit_widget(self, initial_value):
|
||||||
|
self.edit_widget = QtWidgets.QCheckBox()
|
||||||
|
self.edit_widget.setChecked(bool(initial_value))
|
||||||
|
return self.edit_widget
|
||||||
|
|
||||||
|
def get_edit_widget_value(self):
|
||||||
|
return self.edit_widget.isChecked()
|
||||||
|
|
||||||
|
|
||||||
|
class StringEditor(Editor):
|
||||||
|
def get_edit_widget(self, initial_value):
|
||||||
|
self.edit_widget = QtWidgets.QLineEdit()
|
||||||
|
self.edit_widget.setText(initial_value)
|
||||||
|
return self.edit_widget
|
||||||
|
|
||||||
|
def get_edit_widget_value(self):
|
||||||
|
return self.edit_widget.text()
|
||||||
|
|
||||||
|
|
||||||
class Model(DictSyncTreeSepModel):
|
class Model(DictSyncTreeSepModel):
|
||||||
def __init__(self, init):
|
def __init__(self, init):
|
||||||
DictSyncTreeSepModel.__init__(self, ".",
|
DictSyncTreeSepModel.__init__(self, ".",
|
||||||
|
@ -49,6 +121,12 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
grid.addWidget(self.table, 1, 0)
|
grid.addWidget(self.table, 1, 0)
|
||||||
|
|
||||||
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
|
edit_action = QtWidgets.QAction("Edit dataset", self.table)
|
||||||
|
edit_action.triggered.connect(self.edit_clicked)
|
||||||
|
edit_action.setShortcut("RETURN")
|
||||||
|
edit_action.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
||||||
|
self.table.doubleClicked.connect(self.edit_clicked)
|
||||||
|
self.table.addAction(edit_action)
|
||||||
delete_action = QtWidgets.QAction("Delete dataset", self.table)
|
delete_action = QtWidgets.QAction("Delete dataset", self.table)
|
||||||
delete_action.triggered.connect(self.delete_clicked)
|
delete_action.triggered.connect(self.delete_clicked)
|
||||||
delete_action.setShortcut("DELETE")
|
delete_action.setShortcut("DELETE")
|
||||||
|
@ -69,6 +147,26 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
self.table_model_filter.setSourceModel(self.table_model)
|
self.table_model_filter.setSourceModel(self.table_model)
|
||||||
self.table.setModel(self.table_model_filter)
|
self.table.setModel(self.table_model_filter)
|
||||||
|
|
||||||
|
def edit_clicked(self):
|
||||||
|
idx = self.table.selectedIndexes()
|
||||||
|
if idx:
|
||||||
|
idx = self.table_model_filter.mapToSource(idx[0])
|
||||||
|
key = self.table_model.index_to_key(idx)
|
||||||
|
if key is not None:
|
||||||
|
persist, value = self.table_model.backing_store[key]
|
||||||
|
t = type(value)
|
||||||
|
if np.issubdtype(t, np.number):
|
||||||
|
dialog_cls = NumberEditor
|
||||||
|
elif np.issubdtype(t, np.bool_):
|
||||||
|
dialog_cls = BoolEditor
|
||||||
|
elif np.issubdtype(t, np.unicode_):
|
||||||
|
dialog_cls = StringEditor
|
||||||
|
else:
|
||||||
|
logger.error("Cannot edit dataset %s: "
|
||||||
|
"type %s is not supported", key, t)
|
||||||
|
return
|
||||||
|
dialog_cls(self, self.dataset_ctl, key, value, persist).exec_()
|
||||||
|
|
||||||
def delete_clicked(self):
|
def delete_clicked(self):
|
||||||
idx = self.table.selectedIndexes()
|
idx = self.table.selectedIndexes()
|
||||||
if idx:
|
if idx:
|
||||||
|
|
Loading…
Reference in New Issue