gui: basic applet dock editing

This commit is contained in:
Sebastien Bourdeauducq 2016-01-07 20:23:17 +08:00
parent adbb217d55
commit e106ee3f90
2 changed files with 149 additions and 4 deletions

View File

@ -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())

135
artiq/gui/applets.py Normal file
View File

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