forked from M-Labs/artiq
browser: move exp mgmt to mdi area
This commit is contained in:
parent
9ef282636a
commit
77b84a7979
|
@ -585,120 +585,3 @@ class ExperimentManager:
|
||||||
for expurl, dock_state in state["docks"].items():
|
for expurl, dock_state in state["docks"].items():
|
||||||
dock = self.open_experiment(expurl)
|
dock = self.open_experiment(expurl)
|
||||||
dock.restore_state(dock_state)
|
dock.restore_state(dock_state)
|
||||||
|
|
||||||
|
|
||||||
class SimpleExperimentManager:
|
|
||||||
def __init__(self, main_window):
|
|
||||||
self.main_window = main_window
|
|
||||||
|
|
||||||
self.submission_options = dict()
|
|
||||||
self.submission_arguments = dict()
|
|
||||||
|
|
||||||
self.open_experiments = dict()
|
|
||||||
|
|
||||||
def get_submission_options(self, expurl):
|
|
||||||
if expurl in self.submission_options:
|
|
||||||
return self.submission_options[expurl]
|
|
||||||
else:
|
|
||||||
# mutated by _ExperimentDock
|
|
||||||
options = {
|
|
||||||
"log_level": logging.WARNING
|
|
||||||
}
|
|
||||||
if expurl[:5] == "repo:":
|
|
||||||
options["repo_rev"] = None
|
|
||||||
self.submission_options[expurl] = options
|
|
||||||
return options
|
|
||||||
|
|
||||||
def initialize_submission_arguments(self, expurl, arginfo):
|
|
||||||
arguments = OrderedDict()
|
|
||||||
for name, (procdesc, group) in arginfo.items():
|
|
||||||
state = argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
|
||||||
arguments[name] = {
|
|
||||||
"desc": procdesc,
|
|
||||||
"group": group,
|
|
||||||
"state": state # mutated by entries
|
|
||||||
}
|
|
||||||
self.submission_arguments[expurl] = arguments
|
|
||||||
return arguments
|
|
||||||
|
|
||||||
def get_submission_arguments(self, expurl):
|
|
||||||
if expurl in self.submission_arguments:
|
|
||||||
return self.submission_arguments[expurl]
|
|
||||||
else:
|
|
||||||
if expurl[:5] != "repo:":
|
|
||||||
raise ValueError("Submission arguments must be preinitialized "
|
|
||||||
"when not using repository")
|
|
||||||
arginfo = self.explist[expurl[5:]]["arginfo"]
|
|
||||||
arguments = self.initialize_submission_arguments(expurl, arginfo)
|
|
||||||
return arguments
|
|
||||||
|
|
||||||
def open_experiment(self, expurl):
|
|
||||||
if expurl in self.open_experiments:
|
|
||||||
dock = self.open_experiments[expurl]
|
|
||||||
self.main_window.centralWidget().setActiveSubWindow(dock)
|
|
||||||
return dock
|
|
||||||
try:
|
|
||||||
dock = _ExperimentDock(self, expurl)
|
|
||||||
except:
|
|
||||||
logger.warning("Failed to create experiment dock for %s, "
|
|
||||||
"attempting to reset arguments", expurl,
|
|
||||||
exc_info=True)
|
|
||||||
del self.submission_arguments[expurl]
|
|
||||||
dock = _ExperimentDock(self, expurl)
|
|
||||||
self.open_experiments[expurl] = dock
|
|
||||||
self.main_window.centralWidget().addSubWindow(dock)
|
|
||||||
dock.show()
|
|
||||||
dock.sigClosed.connect(partial(self.on_dock_closed, expurl))
|
|
||||||
return dock
|
|
||||||
|
|
||||||
def on_dock_closed(self, expurl):
|
|
||||||
del self.open_experiments[expurl]
|
|
||||||
|
|
||||||
async def _submit_task(self, *args):
|
|
||||||
rid = await self.schedule_ctl.submit(*args)
|
|
||||||
self.main_window.statusBar().showMessage(
|
|
||||||
"Submitted RID {}".format(rid))
|
|
||||||
|
|
||||||
def submit(self, expurl):
|
|
||||||
file, class_name, _ = self.resolve_expurl(expurl)
|
|
||||||
options = self.get_submission_options(expurl)
|
|
||||||
arguments = self.get_submission_arguments(expurl)
|
|
||||||
|
|
||||||
argument_values = dict()
|
|
||||||
for name, argument in arguments.items():
|
|
||||||
entry_cls = argty_to_entry[argument["desc"]["ty"]]
|
|
||||||
argument_values[name] = entry_cls.state_to_value(argument["state"])
|
|
||||||
|
|
||||||
expid = {
|
|
||||||
"log_level": options["log_level"],
|
|
||||||
"file": file,
|
|
||||||
"class_name": class_name,
|
|
||||||
"arguments": argument_values,
|
|
||||||
}
|
|
||||||
if "repo_rev" in options:
|
|
||||||
expid["repo_rev"] = options["repo_rev"]
|
|
||||||
asyncio.ensure_future(self._submit_task(expid))
|
|
||||||
|
|
||||||
async def compute_arginfo(self, expurl):
|
|
||||||
file, class_name, use_repository = self.resolve_expurl(expurl)
|
|
||||||
description = await self.experiment_db_ctl.examine(file,
|
|
||||||
use_repository)
|
|
||||||
return description[class_name]["arginfo"]
|
|
||||||
|
|
||||||
def save_state(self):
|
|
||||||
docks = {expurl: dock.save_state()
|
|
||||||
for expurl, dock in self.open_experiments.items()}
|
|
||||||
return {
|
|
||||||
"options": self.submission_options,
|
|
||||||
"arguments": self.submission_arguments,
|
|
||||||
"docks": docks
|
|
||||||
}
|
|
||||||
|
|
||||||
def restore_state(self, state):
|
|
||||||
if self.open_experiments:
|
|
||||||
raise NotImplementedError
|
|
||||||
self.submission_options = state["options"]
|
|
||||||
self.submission_arguments = state["arguments"]
|
|
||||||
for expurl, dock_state in state["docks"].items():
|
|
||||||
dock = self.open_experiment(expurl)
|
|
||||||
dock.restore_state(dock_state)
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import asyncio
|
||||||
import atexit
|
import atexit
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
from quamash import QEventLoop
|
from quamash import QEventLoop
|
||||||
|
@ -65,19 +66,23 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.restoreState(QtCore.QByteArray(state["state"]))
|
self.restoreState(QtCore.QByteArray(state["state"]))
|
||||||
|
|
||||||
|
|
||||||
class MdiArea(QtWidgets.QMdiArea):
|
class ExperimentsArea(QtWidgets.QMdiArea):
|
||||||
def __init__(self, root):
|
def __init__(self, root):
|
||||||
QtWidgets.QMdiArea.__init__(self)
|
QtWidgets.QMdiArea.__init__(self)
|
||||||
self.pixmap = QtGui.QPixmap(os.path.join(
|
self.pixmap = QtGui.QPixmap(os.path.join(
|
||||||
artiq_dir, "gui", "logo20.svg"))
|
artiq_dir, "gui", "logo20.svg"))
|
||||||
self.current_dir = root
|
self.current_dir = root
|
||||||
self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
|
self.setFocusPolicy(QtCore.Qt.StrongFocus)
|
||||||
|
|
||||||
action = QtWidgets.QAction("&Open experiment", self)
|
action = QtWidgets.QAction("&Open experiment", self)
|
||||||
# action.setShortcut(QtGui.QKeySequence("CTRL+o"))
|
action.setShortcut(QtGui.QKeySequence("CTRL+o"))
|
||||||
action.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
action.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
||||||
action.triggered.connect(self.open_experiment)
|
action.triggered.connect(self.open_experiment)
|
||||||
self.addAction(action)
|
self.addAction(action)
|
||||||
|
|
||||||
|
self.open_experiments = []
|
||||||
|
|
||||||
def paintEvent(self, event):
|
def paintEvent(self, event):
|
||||||
QtWidgets.QMdiArea.paintEvent(self, event)
|
QtWidgets.QMdiArea.paintEvent(self, event)
|
||||||
painter = QtGui.QPainter(self.viewport())
|
painter = QtGui.QPainter(self.viewport())
|
||||||
|
@ -86,12 +91,42 @@ class MdiArea(QtWidgets.QMdiArea):
|
||||||
painter.setOpacity(0.5)
|
painter.setOpacity(0.5)
|
||||||
painter.drawPixmap(x, y, self.pixmap)
|
painter.drawPixmap(x, y, self.pixmap)
|
||||||
|
|
||||||
|
def save_state(self):
|
||||||
|
return {"experiments": [experiment.save_state()
|
||||||
|
for experiment in self.open_experiments]}
|
||||||
|
|
||||||
|
def restore_state(self, state):
|
||||||
|
if self.open_experiments:
|
||||||
|
raise NotImplementedError
|
||||||
|
for ex_state in state["experiments"]:
|
||||||
|
ex = self.load_experiment(ex_state["file"])
|
||||||
|
ex.restore_state(ex_state)
|
||||||
|
|
||||||
def open_experiment(self):
|
def open_experiment(self):
|
||||||
file, filter = QtWidgets.QFileDialog.getOpenFileName(
|
file, filter = QtWidgets.QFileDialog.getOpenFileName(
|
||||||
self, "Open experiment", self.current_dir, "Experiments (*.py)")
|
self, "Open experiment", self.current_dir, "Experiments (*.py)")
|
||||||
if not file:
|
if not file:
|
||||||
return
|
return
|
||||||
print(file)
|
logger.info("opening experiment %s", file)
|
||||||
|
self.load_experiment(file)
|
||||||
|
|
||||||
|
def load_experiment(self, expurl):
|
||||||
|
try:
|
||||||
|
dock = _ExperimentDock(self, expurl)
|
||||||
|
except:
|
||||||
|
logger.warning("Failed to create experiment dock for %s, "
|
||||||
|
"attempting to reset arguments", expurl,
|
||||||
|
exc_info=True)
|
||||||
|
del self.submission_arguments[expurl]
|
||||||
|
dock = _ExperimentDock(self, expurl)
|
||||||
|
self.open_experiments.append(dock)
|
||||||
|
self.addSubWindow(dock)
|
||||||
|
dock.show()
|
||||||
|
dock.sigClosed.connect(partial(self.on_dock_closed, expurl))
|
||||||
|
return dock
|
||||||
|
|
||||||
|
def on_dock_closed(self, expurl):
|
||||||
|
del self.open_experiments[expurl]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -114,7 +149,11 @@ def main():
|
||||||
status_bar = QtWidgets.QStatusBar()
|
status_bar = QtWidgets.QStatusBar()
|
||||||
main_window.setStatusBar(status_bar)
|
main_window.setStatusBar(status_bar)
|
||||||
|
|
||||||
exp_manager = experiments.SimpleExperimentManager(main_window)
|
mdi_area = ExperimentsArea(args.browse_root)
|
||||||
|
mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||||
|
mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||||
|
main_window.setCentralWidget(mdi_area)
|
||||||
|
smgr.register(mdi_area)
|
||||||
|
|
||||||
d_files = files.FilesDock(datasets_sub, args.browse_root,
|
d_files = files.FilesDock(datasets_sub, args.browse_root,
|
||||||
select=args.select)
|
select=args.select)
|
||||||
|
@ -127,11 +166,6 @@ def main():
|
||||||
d_datasets = datasets.DatasetsDock(datasets_sub)
|
d_datasets = datasets.DatasetsDock(datasets_sub)
|
||||||
smgr.register(d_datasets)
|
smgr.register(d_datasets)
|
||||||
|
|
||||||
mdi_area = MdiArea(args.browse_root)
|
|
||||||
mdi_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
||||||
mdi_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
|
||||||
main_window.setCentralWidget(mdi_area)
|
|
||||||
|
|
||||||
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, d_files)
|
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, d_files)
|
||||||
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_applets)
|
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_applets)
|
||||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_datasets)
|
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_datasets)
|
||||||
|
|
Loading…
Reference in New Issue