forked from M-Labs/artiq
moninj: user spawned docks
This commit is contained in:
parent
687c12033e
commit
2fe89fcac3
@ -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
|
||||||
|
|
||||||
|
|
||||||
@ -782,17 +783,26 @@ 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)
|
||||||
|
self.name = name
|
||||||
|
grid = LayoutWidget()
|
||||||
|
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)
|
||||||
|
self.setWidget(grid)
|
||||||
|
self.scroll_area = QtWidgets.QScrollArea()
|
||||||
|
grid.addWidget(self.scroll_area, 1, 0)
|
||||||
|
|
||||||
def layout_widgets(self, handlers):
|
def layout_widgets(self, handlers):
|
||||||
scroll_area = QtWidgets.QScrollArea()
|
|
||||||
self.setWidget(scroll_area)
|
|
||||||
|
|
||||||
grid = FlowLayout()
|
grid = FlowLayout()
|
||||||
grid_widget = QtWidgets.QWidget()
|
grid_widget = QtWidgets.QWidget()
|
||||||
grid_widget.setLayout(grid)
|
grid_widget.setLayout(grid)
|
||||||
@ -800,16 +810,56 @@ class _MonInjDock(QtWidgets.QDockWidget):
|
|||||||
for handler in sorted(handlers, key=lambda h: h.sort_key()):
|
for handler in sorted(handlers, key=lambda h: h.sort_key()):
|
||||||
grid.addWidget(handler.widget)
|
grid.addWidget(handler.widget)
|
||||||
|
|
||||||
scroll_area.setWidgetResizable(True)
|
self.scroll_area.setWidgetResizable(True)
|
||||||
scroll_area.setWidget(grid_widget)
|
self.scroll_area.setWidget(grid_widget)
|
||||||
|
|
||||||
|
|
||||||
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.handlers_by_uid.values())
|
self.dm.channels_cb = self.add_widgets
|
||||||
|
|
||||||
|
def add_widgets(self):
|
||||||
|
self.docks["moninj0"].layout_widgets(self.dm.handlers_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:
|
||||||
|
@ -226,8 +226,8 @@ 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"])
|
moninj_mgr = moninj.MonInj(rpc_clients["schedule"], main_window)
|
||||||
atexit_register_coroutine(d_ttl_dds.stop, loop=loop)
|
atexit_register_coroutine(moninj_mgr.stop, loop=loop)
|
||||||
|
|
||||||
d_waveform = waveform.WaveformDock(
|
d_waveform = waveform.WaveformDock(
|
||||||
args.analyzer_proxy_timeout,
|
args.analyzer_proxy_timeout,
|
||||||
@ -237,10 +237,10 @@ def main():
|
|||||||
atexit_register_coroutine(d_waveform.stop, loop=loop)
|
atexit_register_coroutine(d_waveform.stop, loop=loop)
|
||||||
|
|
||||||
def init_cbs(ddb):
|
def init_cbs(ddb):
|
||||||
d_ttl_dds.dm.init_ddb(ddb)
|
moninj_mgr.dm.init_ddb(ddb)
|
||||||
d_waveform.init_ddb(ddb)
|
d_waveform.init_ddb(ddb)
|
||||||
return ddb
|
return ddb
|
||||||
devices_sub = Subscriber("devices", init_cbs, [d_ttl_dds.dm.notify_ddb, d_waveform.notify_ddb])
|
devices_sub = Subscriber("devices", init_cbs, [moninj_mgr.dm.notify_ddb, d_waveform.notify_ddb])
|
||||||
loop.run_until_complete(devices_sub.connect(args.server, args.port_notify))
|
loop.run_until_complete(devices_sub.connect(args.server, args.port_notify))
|
||||||
atexit_register_coroutine(devices_sub.close, loop=loop)
|
atexit_register_coroutine(devices_sub.close, loop=loop)
|
||||||
|
|
||||||
@ -261,12 +261,15 @@ 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])
|
||||||
for d1, d2 in zip(right_docks, right_docks[1:]):
|
for d1, d2 in zip(right_docks, right_docks[1:]):
|
||||||
main_window.tabifyDockWidget(d1, d2)
|
main_window.tabifyDockWidget(d1, d2)
|
||||||
|
d_moninj0 = moninj_mgr.first_moninj_dock()
|
||||||
|
if d_moninj0 is not None:
|
||||||
|
main_window.tabifyDockWidget(right_docks[-1], d_moninj0)
|
||||||
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_schedule)
|
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_schedule)
|
||||||
|
|
||||||
# load/initialize state
|
# load/initialize state
|
||||||
@ -279,9 +282,6 @@ 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:
|
||||||
|
Loading…
Reference in New Issue
Block a user