dashboard: basic dataset editing capabilities

This commit is contained in:
Sebastien Bourdeauducq 2016-06-17 16:45:26 +08:00
parent c0e42bbfc8
commit 9a1cad5cec
1 changed files with 98 additions and 0 deletions

View File

@ -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: