2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-25 03:08:27 +08:00

gui/shortcuts: integrate with experiment manager

This commit is contained in:
Sebastien Bourdeauducq 2015-12-01 17:10:44 +08:00
parent 741dfce38c
commit ff4c03014c
3 changed files with 89 additions and 94 deletions

View File

@ -13,7 +13,7 @@ from pyqtgraph import dockarea
from artiq.tools import *
from artiq.protocols.pc_rpc import AsyncioClient
from artiq.gui.models import ModelSubscriber
from artiq.gui import (state, experiments, explorer,
from artiq.gui import (state, experiments, shortcuts, explorer,
moninj, datasets, schedule, log, console)
@ -100,11 +100,12 @@ def main():
sub_clients["schedule"],
rpc_clients["schedule"])
smgr.register(expmgr)
d_explorer = explorer.ExplorerDock(win, status_bar, expmgr,
d_shortcuts = shortcuts.ShortcutsDock(win, status_bar, expmgr)
smgr.register(d_shortcuts)
d_explorer = explorer.ExplorerDock(status_bar, expmgr, d_shortcuts,
sub_clients["explist"],
rpc_clients["schedule"],
rpc_clients["repository"])
smgr.register(d_explorer)
d_datasets = datasets.DatasetsDock(win, dock_area, sub_clients["datasets"])
smgr.register(d_datasets)
@ -130,7 +131,8 @@ def main():
dock_area.addDock(d_datasets, "above", d_ttl_dds.ttl_dock)
else:
dock_area.addDock(d_datasets, "top")
dock_area.addDock(d_explorer, "above", d_datasets)
dock_area.addDock(d_shortcuts, "above", d_datasets)
dock_area.addDock(d_explorer, "above", d_shortcuts)
dock_area.addDock(d_console, "bottom")
dock_area.addDock(d_schedule, "above", d_console)

View File

@ -1,12 +1,12 @@
import asyncio
import logging
from functools import partial
from quamash import QtGui, QtCore
from pyqtgraph import dockarea
from pyqtgraph import LayoutWidget
from artiq.gui.models import DictSyncTreeSepModel
from artiq.gui.shortcuts import ShortcutManager
class Model(DictSyncTreeSepModel):
@ -22,13 +22,15 @@ class Model(DictSyncTreeSepModel):
class ExplorerDock(dockarea.Dock):
def __init__(self, main_window, status_bar, exp_manager,
def __init__(self, status_bar, exp_manager, d_shortcuts,
explist_sub, schedule_ctl, repository_ctl):
dockarea.Dock.__init__(self, "Explorer", size=(1500, 500))
self.layout.setSpacing(5)
self.layout.setContentsMargins(5, 5, 5, 5)
self.main_window = main_window
self.status_bar = status_bar
self.exp_manager = exp_manager
self.d_shortcuts = d_shortcuts
self.schedule_ctl = schedule_ctl
self.el = QtGui.QTreeView()
@ -38,18 +40,21 @@ class ExplorerDock(dockarea.Dock):
self.el.doubleClicked.connect(self.open_clicked)
open = QtGui.QPushButton("Open")
open.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOpenButton))
open.setToolTip("Open the selected experiment (Return)")
self.addWidget(open, 1, 0)
open.clicked.connect(self.open_clicked)
submit = QtGui.QPushButton("Submit")
submit.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOkButton))
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
self.addWidget(submit, 1, 1)
submit.clicked.connect(self.submit_clicked)
self.explist_model = Model(dict())
explist_sub.add_setmodel_callback(self.set_model)
self.shortcuts = ShortcutManager(self.main_window, self)
self.el.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
open_action = QtGui.QAction("Open", self.el)
@ -69,9 +74,15 @@ class ExplorerDock(dockarea.Dock):
sep.setSeparator(True)
self.el.addAction(sep)
edit_shortcuts_action = QtGui.QAction("Edit shortcuts", self.el)
edit_shortcuts_action.triggered.connect(self.edit_shortcuts)
self.el.addAction(edit_shortcuts_action)
set_shortcut_menu = QtGui.QMenu()
for i in range(12):
action = QtGui.QAction("F" + str(i+1), self.el)
action.triggered.connect(partial(self.set_shortcut, i))
set_shortcut_menu.addAction(action)
set_shortcut_action = QtGui.QAction("Set shortcut", self.el)
set_shortcut_action.setMenu(set_shortcut_menu)
self.el.addAction(set_shortcut_action)
scan_repository_action = QtGui.QAction("(Re)scan repository HEAD",
self.el)
def scan_repository():
@ -107,18 +118,7 @@ class ExplorerDock(dockarea.Dock):
if expname is not None:
self.exp_manager.request_inst_term(expname)
def save_state(self):
return {
"shortcuts": self.shortcuts.save_state()
}
def restore_state(self, state):
try:
shortcuts_state = state["shortcuts"]
except KeyError:
return
self.shortcuts.restore_state(shortcuts_state)
def edit_shortcuts(self):
experiments = sorted(self.explist_model.backing_store.keys())
self.shortcuts.edit(experiments)
def set_shortcut(self, nr):
expname = self._get_selected_expname()
if expname is not None:
self.d_shortcuts.set_shortcut(nr, expname)

View File

@ -1,6 +1,8 @@
import logging
from functools import partial
from quamash import QtGui
from pyqtgraph import dockarea
try:
from quamash import QtWidgets
QShortcut = QtWidgets.QShortcut
@ -8,91 +10,82 @@ except:
QShortcut = QtGui.QShortcut
class _ShortcutEditor(QtGui.QDialog):
def __init__(self, parent, experiments, shortcuts):
QtGui.QDialog.__init__(self, parent=parent)
self.setWindowTitle("Shortcuts")
logger = logging.getLogger(__name__)
self.shortcuts = shortcuts
self.edit_widgets = dict()
grid = QtGui.QGridLayout()
self.setLayout(grid)
class ShortcutsDock(dockarea.Dock):
def __init__(self, main_window, status_bar, exp_manager):
dockarea.Dock.__init__(self, "Shortcuts", size=(1000, 300))
self.layout.setSpacing(5)
self.layout.setContentsMargins(5, 5, 5, 5)
for n, title in enumerate(["Key", "Experiment", "Priority", "Pipeline"]):
label = QtGui.QLabel("<b>" + title + "</b")
grid.addWidget(label, 0, n)
self.status_bar = status_bar
self.exp_manager = exp_manager
self.shortcut_widgets = dict()
for n, title in enumerate(["Key", "Experiment"]):
label = QtGui.QLabel("<b>" + title + "</b>")
self.addWidget(label, 0, n)
label.setMaximumHeight(label.sizeHint().height())
grid.setColumnStretch(1, 1)
grid.setColumnStretch(3, 1)
self.layout.setColumnStretch(1, 1)
for i in range(12):
row = i + 1
existing_shortcut = self.shortcuts.get(i, dict())
grid.addWidget(QtGui.QLabel("F" + str(i+1)), row, 0)
self.addWidget(QtGui.QLabel("F" + str(i+1)), row, 0)
experiment = QtGui.QComboBox()
grid.addWidget(experiment, row, 1)
experiment.addItem("<None>")
experiment.addItems(experiments)
experiment.setEditable(True)
experiment.setEditText(
existing_shortcut.get("experiment", "<None>"))
priority = QtGui.QSpinBox()
grid.addWidget(priority, row, 2)
priority.setRange(-99, 99)
priority.setValue(existing_shortcut.get("priority", 0))
label = QtGui.QLabel()
self.addWidget(label, row, 1)
pipeline = QtGui.QLineEdit()
grid.addWidget(pipeline, row, 3)
pipeline.setText(existing_shortcut.get("pipeline", "main"))
clear = QtGui.QToolButton()
clear.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogResetButton))
self.addWidget(clear, row, 2)
clear.clicked.connect(partial(self.set_shortcut, i, ""))
self.edit_widgets[i] = {
"experiment": experiment,
"priority": priority,
"pipeline": pipeline
submit = QtGui.QPushButton("Submit")
submit.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOkButton))
self.addWidget(submit, row, 3)
submit.clicked.connect(partial(self._activated, i))
self.shortcut_widgets[i] = {
"label": label,
"clear": clear,
"submit": submit
}
buttons = QtGui.QDialogButtonBox(
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
grid.addWidget(buttons, 14, 0, 1, 4)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
self.accepted.connect(self.on_accept)
def on_accept(self):
for n, widgets in self.edit_widgets.items():
self.shortcuts[n] = {
"experiment": widgets["experiment"].currentText(),
"priority": widgets["priority"].value(),
"pipeline": widgets["pipeline"].text()
}
class ShortcutManager:
def __init__(self, main_window, explorer):
for i in range(12):
shortcut = QShortcut("F" + str(i+1), main_window)
shortcut.activated.connect(partial(self._activated, i))
self.main_window = main_window
self.explorer = explorer
self.shortcuts = dict()
def edit(self, experiments):
dlg = _ShortcutEditor(self.main_window, experiments, self.shortcuts)
dlg.open()
def _activated(self, nr):
info = self.shortcuts.get(nr, dict())
experiment = info.get("experiment", "")
if experiment and experiment != "<None>":
self.explorer.submit(info["pipeline"], experiment,
info["priority"], None, False)
expname = self.shortcut_widgets[nr]["label"].text()
if expname:
try:
rid = self.exp_manager.submit(expname)
except:
self.status_bar.showMessage("Could not submit experiment '{}'"
.format(expname))
logger.warning("failed to submit experiment %s",
expname, exc_info=True)
else:
self.status_bar.showMessage("Submitted RID {} "
"(from global shortcut)"
.format(rid))
def set_shortcut(self, nr, expname):
widgets = self.shortcut_widgets[nr]
widgets["label"].setText(expname)
if expname:
widgets["clear"].show()
widgets["submit"].show()
else:
widgets["clear"].hide()
widgets["submit"].hide()
def save_state(self):
return self.shortcuts
return {nr: widgets["label"].text()
for nr, widgets in self.shortcut_widgets.items()}
def restore_state(self, state):
self.shortcuts = state
for nr, expname in state.items():
self.set_shortcut(nr, expname)