moninj: multiple docks

This commit is contained in:
Simon Renblad 2024-05-02 14:35:59 +08:00 committed by Sébastien Bourdeauducq
parent 9fc4cdea6b
commit ad170b469c
2 changed files with 59 additions and 14 deletions

View File

@ -2,12 +2,13 @@ import asyncio
import logging import logging
import textwrap import textwrap
from collections import namedtuple from collections import namedtuple
from functools import partial
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from artiq.coredevice.comm_moninj import CommMonInj, TTLOverride, TTLProbe from artiq.coredevice.comm_moninj import CommMonInj, TTLOverride, TTLProbe
from artiq.coredevice.ad9912_reg import AD9912_SER_CONF from artiq.coredevice.ad9912_reg import AD9912_SER_CONF
from artiq.gui.tools import LayoutWidget from artiq.gui.tools import LayoutWidget, QDockWidgetCloseDetect
from artiq.gui.flowlayout import FlowLayout from artiq.gui.flowlayout import FlowLayout
@ -735,17 +736,24 @@ class _DeviceManager:
await self.mi_connection.close() await self.mi_connection.close()
class _MonInjDock(QtWidgets.QDockWidget): class _MonInjDock(QDockWidgetCloseDetect):
def __init__(self, name): def __init__(self, name, manager):
QtWidgets.QDockWidget.__init__(self, name) QtWidgets.QDockWidget.__init__(self, "MonInj")
self.setObjectName(name) self.setObjectName(name)
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable | self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
QtWidgets.QDockWidget.DockWidgetFloatable) QtWidgets.QDockWidget.DockWidgetFloatable)
grid = LayoutWidget() grid = LayoutWidget()
self.setWidget(grid) self.setWidget(grid)
newdock = QtWidgets.QToolButton()
newdock.setToolTip("Create new moninj dock")
newdock.setIcon(QtWidgets.QApplication.style().standardIcon(
QtWidgets.QStyle.SP_FileDialogNewFolder))
newdock.clicked.connect(lambda: manager.create_new_dock())
grid.addWidget(newdock, 0, 0)
scroll_area = QtWidgets.QScrollArea() scroll_area = QtWidgets.QScrollArea()
grid.addWidget(scroll_area, 0, 0) grid.addWidget(scroll_area, 1, 0, 1, 10)
self.flow = FlowLayout() self.flow = FlowLayout()
grid_widget = QtWidgets.QWidget() grid_widget = QtWidgets.QWidget()
grid_widget.setLayout(self.flow) grid_widget.setLayout(self.flow)
@ -758,11 +766,48 @@ class _MonInjDock(QtWidgets.QDockWidget):
class MonInj: class MonInj:
def __init__(self, schedule_ctl): def __init__(self, schedule_ctl, main_window):
self.dock = _MonInjDock("MonInj") self.docks = dict()
self.main_window = main_window
self.dm = _DeviceManager(schedule_ctl) self.dm = _DeviceManager(schedule_ctl)
self.dm.channels_cb = lambda: self.dock.layout_widgets(self.dm.widgets_by_uid.values()) self.dm.channels_cb = \
lambda: self.docks["moninj0"].layout_widgets(self.dm.widgets_by_uid.values())
def create_new_dock(self, add_to_area=True):
n = 0
name = "moninj0"
while name in self.docks:
n += 1
name = "moninj" + str(n)
dock = _MonInjDock(name, self)
self.docks[name] = dock
if add_to_area:
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
dock.setFloating(True)
dock.sigClosed.connect(partial(self.on_dock_closed, name))
self.update_closable()
return dock
def on_dock_closed(self, name):
dock = self.docks[name]
dock.deleteLater()
del self.docks[name]
self.update_closable()
def update_closable(self):
flags = (QtWidgets.QDockWidget.DockWidgetMovable |
QtWidgets.QDockWidget.DockWidgetFloatable)
if len(self.docks) > 1:
flags |= QtWidgets.QDockWidget.DockWidgetClosable
for dock in self.docks.values():
dock.setFeatures(flags)
def first_moninj_dock(self):
if self.docks:
return None
dock = self.create_new_dock(False)
return dock
async def stop(self): async def stop(self):
if self.dm is not None: if self.dm is not None:

View File

@ -226,7 +226,7 @@ def main():
smgr.register(d_applets) smgr.register(d_applets)
broadcast_clients["ccb"].notify_cbs.append(d_applets.ccb_notify) broadcast_clients["ccb"].notify_cbs.append(d_applets.ccb_notify)
d_ttl_dds = moninj.MonInj(rpc_clients["schedule"]) d_ttl_dds = moninj.MonInj(rpc_clients["schedule"], main_window)
atexit_register_coroutine(d_ttl_dds.stop, loop=loop) atexit_register_coroutine(d_ttl_dds.stop, loop=loop)
d_waveform = waveform.WaveformDock( d_waveform = waveform.WaveformDock(
@ -261,7 +261,7 @@ def main():
# lay out docks # lay out docks
right_docks = [ right_docks = [
d_explorer, d_shortcuts, d_explorer, d_shortcuts,
d_ttl_dds.dock, d_datasets, d_applets, d_datasets, d_applets,
d_waveform, d_interactive_args d_waveform, d_interactive_args
] ]
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0]) main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0])
@ -279,13 +279,13 @@ def main():
smgr.start(loop=loop) smgr.start(loop=loop)
atexit_register_coroutine(smgr.stop, loop=loop) atexit_register_coroutine(smgr.stop, loop=loop)
# work around for https://github.com/m-labs/artiq/issues/1307
d_ttl_dds.dock.show()
# create first log dock if not already in state # create first log dock if not already in state
d_log0 = logmgr.first_log_dock() d_log0 = logmgr.first_log_dock()
if d_log0 is not None: if d_log0 is not None:
main_window.tabifyDockWidget(d_schedule, d_log0) main_window.tabifyDockWidget(d_schedule, d_log0)
d_moninj0 = d_ttl_dds.first_moninj_dock()
if d_moninj0 is not None:
main_window.tabifyDockWidget(right_docks[-1], d_moninj0)
if server_name is not None: if server_name is not None:
server_description = server_name + " ({})".format(args.server) server_description = server_name + " ({})".format(args.server)