From c4e775aa49af4c2434e091c08fcb3fbcc7a62e4d Mon Sep 17 00:00:00 2001 From: Simon Renblad Date: Wed, 24 Apr 2024 13:58:30 +0800 Subject: [PATCH] moninj: _AddChannelDialog --- artiq/dashboard/moninj.py | 106 +++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 20 deletions(-) diff --git a/artiq/dashboard/moninj.py b/artiq/dashboard/moninj.py index 2d048a4bf..7113139a9 100644 --- a/artiq/dashboard/moninj.py +++ b/artiq/dashboard/moninj.py @@ -9,6 +9,7 @@ from PyQt5 import QtCore, QtWidgets from artiq.coredevice.comm_moninj import CommMonInj, TTLOverride, TTLProbe from artiq.coredevice.ad9912_reg import AD9912_SER_CONF from artiq.gui.tools import LayoutWidget, QDockWidgetCloseDetect +from artiq.gui.models import DictSyncTreeSepModel from artiq.gui.flowlayout import FlowLayout @@ -370,13 +371,12 @@ class _DACWidget(QtWidgets.QFrame): self.setFrameShape(QtWidgets.QFrame.Box) self.setFrameShadow(QtWidgets.QFrame.Raised) - self.title = "{} ch{}".format(title, channel) grid = QtWidgets.QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setHorizontalSpacing(0) grid.setVerticalSpacing(0) self.setLayout(grid) - label = QtWidgets.QLabel(self.title) + label = QtWidgets.QLabel("{} ch{}".format(title, channel)) label.setAlignment(QtCore.Qt.AlignCenter) grid.addWidget(label, 1, 1) @@ -392,9 +392,6 @@ class _DACWidget(QtWidgets.QFrame): self.value.setText("{:.3f} %" .format(value)) - def to_model_path(self): - return "dac/{}".format(self.title) - class _DACHandler: def __init__(self, dm, spi_channel, channel, title): @@ -419,6 +416,61 @@ class _DACHandler: def sort_key(self): return (2, self.spi_channel, self.channel) + def to_model_path(self): + return "dac/{} ch{}".format(self.title, self.channel) + + +class Model(DictSyncTreeSepModel): + def __init__(self, init): + DictSyncTreeSepModel.__init__(self, "/", ["Channels"], init) + + def clear(self): + for k in self.backing_store: + self._del_item(self, k.split(self.separator)) + self.backing_store.clear() + + def update(self, d): + for k, v in d.items(): + self[v.to_model_path()] = v + + +class _AddChannelDialog(QtWidgets.QDialog): + def __init__(self, parent, model): + QtWidgets.QDialog.__init__(self, parent=parent) + self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) + self.setWindowTitle("Add channels") + + layout = QtWidgets.QVBoxLayout() + self.setLayout(layout) + + self._model = model + self._tree_view = QtWidgets.QTreeView() + self._tree_view.setHeaderHidden(True) + self._tree_view.setSelectionBehavior( + QtWidgets.QAbstractItemView.SelectItems) + self._tree_view.setSelectionMode( + QtWidgets.QAbstractItemView.ExtendedSelection) + self._tree_view.setModel(self._model) + layout.addWidget(self._tree_view) + + self._button_box = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel + ) + self._button_box.setCenterButtons(True) + self._button_box.accepted.connect(self.add_channels) + self._button_box.rejected.connect(self.reject) + layout.addWidget(self._button_box) + + def add_channels(self): + selection = self._tree_view.selectedIndexes() + channels = [] + for select in selection: + key = self._model.index_to_key(select) + if key is not None: + channels.append(self._model[key].ref) + self.channels = channels + self.accept() + _HandlerDesc = namedtuple("_HandlerDesc", "uid comment cls arguments") @@ -799,28 +851,40 @@ class _MonInjDock(QDockWidgetCloseDetect): self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | QtWidgets.QDockWidget.DockWidgetFloatable) self.name = name + self.manager = manager grid = LayoutWidget() + self._channel_dialog = _AddChannelDialog(self, self.manager.channel_model) + + self._channel_dialog.accepted.connect(self.add_channels) + add_channel_btn = QtWidgets.QToolButton() + add_channel_btn.setToolTip("Add channels...") + add_channel_btn.setIcon( + QtWidgets.QApplication.style().standardIcon( + QtWidgets.QStyle.SP_FileDialogListView)) + add_channel_btn.clicked.connect(self._channel_dialog.open) + grid.addWidget(add_channel_btn, 0, 0) newdock = QtWidgets.QToolButton() newdock.setToolTip("Create new moninj dock") newdock.setIcon(QtWidgets.QApplication.style().standardIcon( QtWidgets.QStyle.SP_FileDialogNewFolder)) - # note the lambda, the default parameter is overriden otherwise newdock.clicked.connect(lambda: manager.create_new_dock()) - grid.addWidget(newdock, 0, 0) + grid.addWidget(newdock, 0, 1) self.setWidget(grid) - self.scroll_area = QtWidgets.QScrollArea() - grid.addWidget(self.scroll_area, 1, 0) + scroll_area = QtWidgets.QScrollArea() + grid.addWidget(scroll_area, 1, 0, 1, 10) + self.flow = FlowLayout() + grid_widget = QtWidgets.QWidget() + grid_widget.setLayout(self.flow) + scroll_area.setWidgetResizable(True) + scroll_area.setWidget(grid_widget) + + def add_channels(self): + handlers = self._channel_dialog.channels + self.layout_widgets(handlers) def layout_widgets(self, handlers): - grid = FlowLayout() - grid_widget = QtWidgets.QWidget() - grid_widget.setLayout(grid) - for handler in sorted(handlers, key=lambda h: h.sort_key()): - grid.addWidget(handler.widget) - - self.scroll_area.setWidgetResizable(True) - self.scroll_area.setWidget(grid_widget) + self.flow.addWidget(handler.widget) class MonInj: @@ -829,10 +893,12 @@ class MonInj: self.main_window = main_window self.dm = _DeviceManager(schedule_ctl) - self.dm.channels_cb = self.add_widgets + self.dm.channels_cb = self.add_channels + self.channel_model = Model({}) - def add_widgets(self): - self.docks["moninj0"].layout_widgets(self.dm.handlers_by_uid.values()) + def add_channels(self): + self.channel_model.clear() + self.channel_model.update(self.dm.handlers_by_uid) def create_new_dock(self, add_to_area=True): n = 0