mirror of https://github.com/m-labs/artiq.git
browser: also support loading arguments by button and activation, closes #479
This commit is contained in:
parent
cae6e8639e
commit
88d6d0db06
|
@ -167,16 +167,15 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
self.layout.setContentsMargins(5, 5, 5, 5)
|
self.layout.setContentsMargins(5, 5, 5, 5)
|
||||||
|
|
||||||
self._area = area
|
self._area = area
|
||||||
|
self._run_task = None
|
||||||
self.expurl = expurl
|
self.expurl = expurl
|
||||||
self.arguments = arguments
|
self.arguments = arguments
|
||||||
|
self.options = {"log_level": logging.WARNING}
|
||||||
|
|
||||||
self.argeditor = _ArgumentEditor(self)
|
self.argeditor = _ArgumentEditor(self)
|
||||||
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
||||||
self.layout.setRowStretch(0, 1)
|
self.layout.setRowStretch(0, 1)
|
||||||
|
|
||||||
self.options = {"log_level": logging.WARNING}
|
|
||||||
self._run_task = None
|
|
||||||
|
|
||||||
log_level = QtWidgets.QComboBox()
|
log_level = QtWidgets.QComboBox()
|
||||||
log_level.addItems(log_levels)
|
log_level.addItems(log_levels)
|
||||||
log_level.setCurrentIndex(1)
|
log_level.setCurrentIndex(1)
|
||||||
|
@ -195,6 +194,15 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
log_level.currentIndexChanged.connect(update_log_level)
|
log_level.currentIndexChanged.connect(update_log_level)
|
||||||
self.log_level = log_level
|
self.log_level = log_level
|
||||||
|
|
||||||
|
load = QtWidgets.QPushButton("Set arguments")
|
||||||
|
load.setToolTip("Set arguments from currently selected HDF5 "
|
||||||
|
"file (Ctrl+Space)")
|
||||||
|
load.setIcon(QtWidgets.QApplication.style().standardIcon(
|
||||||
|
QtWidgets.QStyle.SP_DialogApplyButton))
|
||||||
|
load.setShortcut("CTRL+SPACE")
|
||||||
|
load.clicked.connect(self._load_clicked)
|
||||||
|
self.layout.addWidget(load, 1, 4)
|
||||||
|
|
||||||
run = QtWidgets.QPushButton("Analyze")
|
run = QtWidgets.QPushButton("Analyze")
|
||||||
run.setIcon(QtWidgets.QApplication.style().standardIcon(
|
run.setIcon(QtWidgets.QApplication.style().standardIcon(
|
||||||
QtWidgets.QStyle.SP_DialogOkButton))
|
QtWidgets.QStyle.SP_DialogOkButton))
|
||||||
|
@ -202,8 +210,8 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
run.setShortcut("CTRL+RETURN")
|
run.setShortcut("CTRL+RETURN")
|
||||||
run.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
|
run.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
|
||||||
QtWidgets.QSizePolicy.Expanding)
|
QtWidgets.QSizePolicy.Expanding)
|
||||||
self.layout.addWidget(run, 1, 4, 2, 1)
|
self.layout.addWidget(run, 2, 4)
|
||||||
run.clicked.connect(self.run_clicked)
|
run.clicked.connect(self._run_clicked)
|
||||||
self._run = run
|
self._run = run
|
||||||
|
|
||||||
terminate = QtWidgets.QPushButton("Terminate")
|
terminate = QtWidgets.QPushButton("Terminate")
|
||||||
|
@ -214,7 +222,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
terminate.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
|
terminate.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
|
||||||
QtWidgets.QSizePolicy.Expanding)
|
QtWidgets.QSizePolicy.Expanding)
|
||||||
self.layout.addWidget(terminate, 3, 4)
|
self.layout.addWidget(terminate, 3, 4)
|
||||||
terminate.clicked.connect(self.terminate_clicked)
|
terminate.clicked.connect(self._terminate_clicked)
|
||||||
terminate.setEnabled(False)
|
terminate.setEnabled(False)
|
||||||
self._terminate = terminate
|
self._terminate = terminate
|
||||||
|
|
||||||
|
@ -226,7 +234,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
for uri in ev.mimeData().urls():
|
for uri in ev.mimeData().urls():
|
||||||
if uri.scheme() == "file":
|
if uri.scheme() == "file":
|
||||||
logger.debug("Loading HDF5 arguments from %s", uri.path())
|
logger.debug("Loading HDF5 arguments from %s", uri.path())
|
||||||
asyncio.ensure_future(self._load_hdf5_task(uri.path()))
|
asyncio.ensure_future(self.load_hdf5_task(uri.path()))
|
||||||
break
|
break
|
||||||
|
|
||||||
async def compute_arginfo(self):
|
async def compute_arginfo(self):
|
||||||
|
@ -251,7 +259,7 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
self.argeditor = _ArgumentEditor(self)
|
self.argeditor = _ArgumentEditor(self)
|
||||||
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
||||||
|
|
||||||
async def _load_hdf5_task(self, filename):
|
async def load_hdf5_task(self, filename):
|
||||||
try:
|
try:
|
||||||
with h5py.File(filename, "r") as f:
|
with h5py.File(filename, "r") as f:
|
||||||
expid = f["expid"][()]
|
expid = f["expid"][()]
|
||||||
|
@ -272,7 +280,12 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
|
|
||||||
await self._recompute_arguments(arguments)
|
await self._recompute_arguments(arguments)
|
||||||
|
|
||||||
def run_clicked(self):
|
def _load_clicked(self):
|
||||||
|
if self._area.dataset is None:
|
||||||
|
return
|
||||||
|
asyncio.ensure_future(self.load_hdf5_task(self._area.dataset))
|
||||||
|
|
||||||
|
def _run_clicked(self):
|
||||||
class_name, file = self.expurl.split("@", maxsplit=1)
|
class_name, file = self.expurl.split("@", maxsplit=1)
|
||||||
expid = {
|
expid = {
|
||||||
"repo_rev": "N/A",
|
"repo_rev": "N/A",
|
||||||
|
@ -308,13 +321,11 @@ class _ExperimentDock(QtWidgets.QMdiSubWindow):
|
||||||
finally:
|
finally:
|
||||||
await worker.close()
|
await worker.close()
|
||||||
|
|
||||||
def terminate_clicked(self):
|
def _terminate_clicked(self):
|
||||||
try:
|
try:
|
||||||
self._run_task.cancel()
|
self._run_task.cancel()
|
||||||
except:
|
except:
|
||||||
# May happen when experiment has been removed
|
logger.error("Unexpected failure terminating '%s'",
|
||||||
# from repository/explist
|
|
||||||
logger.error("Failed to request termination of instances of '%s'",
|
|
||||||
self.expurl, exc_info=True)
|
self.expurl, exc_info=True)
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
|
@ -355,6 +366,7 @@ class ExperimentsArea(QtWidgets.QMdiArea):
|
||||||
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.dataset = None
|
||||||
|
|
||||||
self.open_experiments = []
|
self.open_experiments = []
|
||||||
|
|
||||||
|
@ -367,6 +379,15 @@ class ExperimentsArea(QtWidgets.QMdiArea):
|
||||||
"update_dataset": self._ddb.update,
|
"update_dataset": self._ddb.update,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def dataset_changed(self, path):
|
||||||
|
self.dataset = path
|
||||||
|
|
||||||
|
def dataset_activated(self, path):
|
||||||
|
sub = self.currentSubWindow()
|
||||||
|
if sub is None:
|
||||||
|
return
|
||||||
|
asyncio.ensure_future(sub.load_hdf5_task(path))
|
||||||
|
|
||||||
def mousePressEvent(self, ev):
|
def mousePressEvent(self, ev):
|
||||||
if ev.button() == QtCore.Qt.LeftButton:
|
if ev.button() == QtCore.Qt.LeftButton:
|
||||||
self.select_experiment()
|
self.select_experiment()
|
||||||
|
|
|
@ -116,6 +116,9 @@ class Hdf5FileSystemModel(QtWidgets.QFileSystemModel):
|
||||||
|
|
||||||
|
|
||||||
class FilesDock(QtWidgets.QDockWidget):
|
class FilesDock(QtWidgets.QDockWidget):
|
||||||
|
dataset_activated = QtCore.pyqtSignal(str)
|
||||||
|
dataset_changed = QtCore.pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, datasets, browse_root="", select=None):
|
def __init__(self, datasets, browse_root="", select=None):
|
||||||
QtWidgets.QDockWidget.__init__(self, "Files")
|
QtWidgets.QDockWidget.__init__(self, "Files")
|
||||||
self.setObjectName("Files")
|
self.setObjectName("Files")
|
||||||
|
@ -180,9 +183,12 @@ class FilesDock(QtWidgets.QDockWidget):
|
||||||
return
|
return
|
||||||
rd = {k: (True, v.value) for k, v in f["datasets"].items()}
|
rd = {k: (True, v.value) for k, v in f["datasets"].items()}
|
||||||
self.datasets.init(rd)
|
self.datasets.init(rd)
|
||||||
|
self.dataset_changed.emit(info.filePath())
|
||||||
|
|
||||||
def list_activated(self, idx):
|
def list_activated(self, idx):
|
||||||
if not self.model.fileInfo(idx).isDir():
|
info = self.model.fileInfo(idx)
|
||||||
|
if not info.isDir():
|
||||||
|
self.dataset_activated.emit(info.filePath())
|
||||||
return
|
return
|
||||||
self.rl.setRootIndex(idx)
|
self.rl.setRootIndex(idx)
|
||||||
idx = self.rt.model().mapFromSource(idx)
|
idx = self.rt.model().mapFromSource(idx)
|
||||||
|
|
|
@ -61,6 +61,11 @@ class Browser(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
self.files = files.FilesDock(datasets_sub, browse_root, select=select)
|
self.files = files.FilesDock(datasets_sub, browse_root, select=select)
|
||||||
|
|
||||||
|
self.files.dataset_activated.connect(
|
||||||
|
self.experiments.dataset_activated)
|
||||||
|
self.files.dataset_changed.connect(
|
||||||
|
self.experiments.dataset_changed)
|
||||||
|
|
||||||
self.applets = applets.AppletsDock(self, datasets_sub)
|
self.applets = applets.AppletsDock(self, datasets_sub)
|
||||||
atexit_register_coroutine(self.applets.stop)
|
atexit_register_coroutine(self.applets.stop)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue