mirror of https://github.com/m-labs/artiq.git
gui: basic applet dock editing
This commit is contained in:
parent
adbb217d55
commit
e106ee3f90
|
@ -11,10 +11,10 @@ from quamash import QEventLoop, QtGui, QtCore
|
||||||
from pyqtgraph import dockarea
|
from pyqtgraph import dockarea
|
||||||
|
|
||||||
from artiq.tools import *
|
from artiq.tools import *
|
||||||
from artiq.protocols.pc_rpc import AsyncioClient
|
from artiq.protocols.pc_rpc import AsyncioClient, Server
|
||||||
from artiq.gui.models import ModelSubscriber
|
from artiq.gui.models import ModelSubscriber
|
||||||
from artiq.gui import (state, experiments, shortcuts, explorer,
|
from artiq.gui import (state, experiments, shortcuts, explorer,
|
||||||
moninj, datasets, schedule, log, console)
|
moninj, datasets, applets, schedule, log, console)
|
||||||
|
|
||||||
|
|
||||||
def get_argparser():
|
def get_argparser():
|
||||||
|
@ -111,6 +111,9 @@ def main():
|
||||||
d_datasets = datasets.DatasetsDock(win, dock_area, sub_clients["datasets"])
|
d_datasets = datasets.DatasetsDock(win, dock_area, sub_clients["datasets"])
|
||||||
smgr.register(d_datasets)
|
smgr.register(d_datasets)
|
||||||
|
|
||||||
|
appletmgr = applets.AppletManager(dock_area)
|
||||||
|
smgr.register(appletmgr)
|
||||||
|
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
d_ttl_dds = moninj.MonInj()
|
d_ttl_dds = moninj.MonInj()
|
||||||
loop.run_until_complete(d_ttl_dds.start(args.server, args.port_notify))
|
loop.run_until_complete(d_ttl_dds.start(args.server, args.port_notify))
|
||||||
|
@ -129,9 +132,11 @@ def main():
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
dock_area.addDock(d_ttl_dds.dds_dock, "top")
|
dock_area.addDock(d_ttl_dds.dds_dock, "top")
|
||||||
dock_area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
|
dock_area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
|
||||||
dock_area.addDock(d_datasets, "above", d_ttl_dds.ttl_dock)
|
dock_area.addDock(appletmgr.main_dock, "above", d_ttl_dds.ttl_dock)
|
||||||
|
dock_area.addDock(d_datasets, "above", appletmgr.main_dock)
|
||||||
else:
|
else:
|
||||||
dock_area.addDock(d_datasets, "top")
|
dock_area.addDock(appletmgr.main_dock, "top")
|
||||||
|
dock_area.addDock(d_datasets, "above", appletmgr.main_dock)
|
||||||
dock_area.addDock(d_shortcuts, "above", d_datasets)
|
dock_area.addDock(d_shortcuts, "above", d_datasets)
|
||||||
dock_area.addDock(d_explorer, "above", d_shortcuts)
|
dock_area.addDock(d_explorer, "above", d_shortcuts)
|
||||||
dock_area.addDock(d_console, "bottom")
|
dock_area.addDock(d_console, "bottom")
|
||||||
|
@ -147,6 +152,11 @@ def main():
|
||||||
if d_log0 is not None:
|
if d_log0 is not None:
|
||||||
dock_area.addDock(d_log0, "right", d_explorer)
|
dock_area.addDock(d_log0, "right", d_explorer)
|
||||||
|
|
||||||
|
# start RPC server
|
||||||
|
rpc_server = Server({"applets": appletmgr.rpc})
|
||||||
|
loop.run_until_complete(rpc_server.start("::1", 6501))
|
||||||
|
atexit_register_coroutine(rpc_server.stop)
|
||||||
|
|
||||||
# run
|
# run
|
||||||
win.show()
|
win.show()
|
||||||
loop.run_until_complete(win.exit_request.wait())
|
loop.run_until_complete(win.exit_request.wait())
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from quamash import QtCore, QtGui, QtWidgets
|
||||||
|
from pyqtgraph import dockarea
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AppletDock(dockarea.Dock):
|
||||||
|
def __init__(self, token, name):
|
||||||
|
dockarea.Dock.__init__(self, "applet" + str(token),
|
||||||
|
label="Applet: " + name,
|
||||||
|
closable=True)
|
||||||
|
self.setMinimumSize(QtCore.QSize(500, 400))
|
||||||
|
|
||||||
|
def capture(self, win_id):
|
||||||
|
self.captured_window = QtGui.QWindow.fromWinId(win_id)
|
||||||
|
self.captured_widget = QtWidgets.QWidget.createWindowContainer(captured_window)
|
||||||
|
self.addWidget(captured_widget)
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
if hasattr(self, "captured_window"):
|
||||||
|
self.captured_window.close()
|
||||||
|
self.captured_widget.deleteLater()
|
||||||
|
del self.captured_window
|
||||||
|
del self.captured_widget
|
||||||
|
|
||||||
|
|
||||||
|
class AppletsDock(dockarea.Dock):
|
||||||
|
def __init__(self, manager):
|
||||||
|
self.manager = manager
|
||||||
|
|
||||||
|
dockarea.Dock.__init__(self, "Applets")
|
||||||
|
self.setMinimumSize(QtCore.QSize(850, 450))
|
||||||
|
|
||||||
|
self.table = QtWidgets.QTableWidget(0, 3)
|
||||||
|
self.table.setHorizontalHeaderLabels(["Enable", "Name", "Command"])
|
||||||
|
self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
||||||
|
self.table.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
|
||||||
|
self.table.horizontalHeader().setStretchLastSection(True)
|
||||||
|
self.table.horizontalHeader().setResizeMode(
|
||||||
|
QtGui.QHeaderView.ResizeToContents)
|
||||||
|
self.table.verticalHeader().setResizeMode(
|
||||||
|
QtGui.QHeaderView.ResizeToContents)
|
||||||
|
self.table.verticalHeader().hide()
|
||||||
|
self.table.setTextElideMode(QtCore.Qt.ElideNone)
|
||||||
|
self.addWidget(self.table)
|
||||||
|
|
||||||
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
|
new_action = QtGui.QAction("New applet", self.table)
|
||||||
|
new_action.triggered.connect(self.new)
|
||||||
|
self.table.addAction(new_action)
|
||||||
|
restart_action = QtGui.QAction("Restart selected applet", self.table)
|
||||||
|
self.table.addAction(restart_action)
|
||||||
|
delete_action = QtGui.QAction("Delete selected applet", self.table)
|
||||||
|
delete_action.triggered.connect(self.delete)
|
||||||
|
self.table.addAction(delete_action)
|
||||||
|
|
||||||
|
self.table.cellChanged.connect(self.cell_changed)
|
||||||
|
|
||||||
|
def cell_changed(self, row, column):
|
||||||
|
if column == 0:
|
||||||
|
item = self.table.item(row, column)
|
||||||
|
if item.checkState() == QtCore.Qt.Checked:
|
||||||
|
command = self.table.item(row, 2)
|
||||||
|
if command:
|
||||||
|
command = command.text()
|
||||||
|
name = self.table.item(row, 1)
|
||||||
|
if name is None:
|
||||||
|
name = ""
|
||||||
|
else:
|
||||||
|
name = name.text()
|
||||||
|
token = self.manager.create(name, command)
|
||||||
|
item.applet_token = token
|
||||||
|
else:
|
||||||
|
token = getattr(item, "applet_token", None)
|
||||||
|
if token is not None:
|
||||||
|
# cell_changed is emitted at row creation
|
||||||
|
self.manager.delete(token)
|
||||||
|
item.applet_token = None
|
||||||
|
|
||||||
|
def new(self):
|
||||||
|
row = self.table.rowCount()
|
||||||
|
self.table.insertRow(row)
|
||||||
|
checkbox = QtWidgets.QTableWidgetItem()
|
||||||
|
checkbox.setFlags(QtCore.Qt.ItemIsSelectable |
|
||||||
|
QtCore.Qt.ItemIsUserCheckable |
|
||||||
|
QtCore.Qt.ItemIsEnabled)
|
||||||
|
checkbox.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
self.table.setItem(row, 0, checkbox)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
selection = self.table.selectedRanges()
|
||||||
|
if selection:
|
||||||
|
self.table.deleteRow(selection[0].topRow())
|
||||||
|
|
||||||
|
|
||||||
|
class AppletManagerRPC:
|
||||||
|
def __init__(self, parent):
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
def embed(self, token, win_id):
|
||||||
|
self.parent.embed(token, win_id)
|
||||||
|
|
||||||
|
|
||||||
|
class AppletManager:
|
||||||
|
def __init__(self, dock_area):
|
||||||
|
self.dock_area = dock_area
|
||||||
|
self.main_dock = AppletsDock(self)
|
||||||
|
self.rpc = AppletManagerRPC(self)
|
||||||
|
self.applet_docks = dict()
|
||||||
|
|
||||||
|
def embed(self, token, win_id):
|
||||||
|
if token not in self.applet_docks:
|
||||||
|
logger.warning("Ignored incorrect embed token %d for winid 0x%x",
|
||||||
|
token, win_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
def create(self, name, command):
|
||||||
|
token = next(iter(set(range(len(self.applet_docks) + 1))
|
||||||
|
- self.applet_docks.keys()))
|
||||||
|
dock = AppletDock(token, name)
|
||||||
|
self.applet_docks[token] = dock
|
||||||
|
self.dock_area.floatDock(dock)
|
||||||
|
return token
|
||||||
|
|
||||||
|
def delete(self, token):
|
||||||
|
del self.applet_docks[token]
|
||||||
|
|
||||||
|
def save_state(self):
|
||||||
|
return dict()
|
||||||
|
|
||||||
|
def restore_state(self, state):
|
||||||
|
pass
|
Loading…
Reference in New Issue