forked from M-Labs/artiq
browser: permanently show results' metadata, closes #471
This commit is contained in:
parent
48a42cdb34
commit
7ce9fc714a
|
@ -43,8 +43,20 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
QtWidgets.QAbstractItemView.SingleSelection)
|
QtWidgets.QAbstractItemView.SingleSelection)
|
||||||
grid.addWidget(self.table, 1, 0)
|
grid.addWidget(self.table, 1, 0)
|
||||||
|
|
||||||
|
metadata_grid = LayoutWidget()
|
||||||
|
self.metadata = {}
|
||||||
|
for i, label in enumerate("artiq_version repo_rev file class_name "
|
||||||
|
"rid start_time".split()):
|
||||||
|
metadata_grid.addWidget(QtWidgets.QLabel(label), i, 0)
|
||||||
|
v = QtWidgets.QLabel()
|
||||||
|
v.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
|
||||||
|
metadata_grid.addWidget(v, i, 1)
|
||||||
|
self.metadata[label] = v
|
||||||
|
grid.addWidget(metadata_grid, 2, 0)
|
||||||
|
|
||||||
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
upload_action = QtWidgets.QAction("Upload dataset to master", self.table)
|
upload_action = QtWidgets.QAction("Upload dataset to master",
|
||||||
|
self.table)
|
||||||
upload_action.triggered.connect(self.upload_clicked)
|
upload_action.triggered.connect(self.upload_clicked)
|
||||||
self.table.addAction(upload_action)
|
self.table.addAction(upload_action)
|
||||||
|
|
||||||
|
@ -59,6 +71,10 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
self.table_model_filter.setFilterFixedString(
|
self.table_model_filter.setFilterFixedString(
|
||||||
self.search.displayText())
|
self.search.displayText())
|
||||||
|
|
||||||
|
def metadata_changed(self, new):
|
||||||
|
for k, v in new.items():
|
||||||
|
self.metadata[k].setText("{}".format(v))
|
||||||
|
|
||||||
def set_model(self, model):
|
def set_model(self, model):
|
||||||
self.table_model = model
|
self.table_model = model
|
||||||
self.table_model_filter = QtCore.QSortFilterProxyModel()
|
self.table_model_filter = QtCore.QSortFilterProxyModel()
|
||||||
|
|
|
@ -118,8 +118,9 @@ class Hdf5FileSystemModel(QtWidgets.QFileSystemModel):
|
||||||
class FilesDock(QtWidgets.QDockWidget):
|
class FilesDock(QtWidgets.QDockWidget):
|
||||||
dataset_activated = QtCore.pyqtSignal(str)
|
dataset_activated = QtCore.pyqtSignal(str)
|
||||||
dataset_changed = QtCore.pyqtSignal(str)
|
dataset_changed = QtCore.pyqtSignal(str)
|
||||||
|
metadata_changed = QtCore.pyqtSignal(dict)
|
||||||
|
|
||||||
def __init__(self, datasets, browse_root="", select=None):
|
def __init__(self, datasets, browse_root="", restore_selection=True):
|
||||||
QtWidgets.QDockWidget.__init__(self, "Files")
|
QtWidgets.QDockWidget.__init__(self, "Files")
|
||||||
self.setObjectName("Files")
|
self.setObjectName("Files")
|
||||||
self.setFeatures(self.DockWidgetMovable | self.DockWidgetFloatable)
|
self.setFeatures(self.DockWidgetMovable | self.DockWidgetFloatable)
|
||||||
|
@ -168,13 +169,7 @@ class FilesDock(QtWidgets.QDockWidget):
|
||||||
rev_copy.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
rev_copy.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
||||||
self.rl.addAction(rev_copy)
|
self.rl.addAction(rev_copy)
|
||||||
|
|
||||||
self.restore_selected = select is None
|
self.restore_selection = restore_selection
|
||||||
if select is not None:
|
|
||||||
f = os.path.abspath(select)
|
|
||||||
if os.path.isdir(f):
|
|
||||||
self.select_dir(f)
|
|
||||||
else:
|
|
||||||
self.select_file(f)
|
|
||||||
|
|
||||||
def _copy_repo_rev(self):
|
def _copy_repo_rev(self):
|
||||||
pass
|
pass
|
||||||
|
@ -190,8 +185,22 @@ class FilesDock(QtWidgets.QDockWidget):
|
||||||
return
|
return
|
||||||
logger.debug("loading datasets from %s", info.filePath())
|
logger.debug("loading datasets from %s", info.filePath())
|
||||||
with f:
|
with f:
|
||||||
if "datasets" not in f:
|
try:
|
||||||
return
|
expid = pyon.decode(f["expid"].value)
|
||||||
|
start_time = datetime.fromtimestamp(f["start_time"].value)
|
||||||
|
v = {
|
||||||
|
"artiq_version": f["artiq_version"].value,
|
||||||
|
"repo_rev": expid["repo_rev"],
|
||||||
|
"file": expid["file"],
|
||||||
|
"class_name": expid["class_name"],
|
||||||
|
"rid": f["rid"].value,
|
||||||
|
"start_time": start_time,
|
||||||
|
}
|
||||||
|
self.metadata_changed.emit(v)
|
||||||
|
except:
|
||||||
|
logger.warning("unable to read metadata from %s",
|
||||||
|
info.filePath(), exc_info=True)
|
||||||
|
if "datasets" in f:
|
||||||
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())
|
self.dataset_changed.emit(info.filePath())
|
||||||
|
@ -206,6 +215,13 @@ class FilesDock(QtWidgets.QDockWidget):
|
||||||
self.rt.expand(idx)
|
self.rt.expand(idx)
|
||||||
self.rt.setCurrentIndex(idx)
|
self.rt.setCurrentIndex(idx)
|
||||||
|
|
||||||
|
def select(self, path):
|
||||||
|
f = os.path.abspath(path)
|
||||||
|
if os.path.isdir(f):
|
||||||
|
self.select_dir(f)
|
||||||
|
else:
|
||||||
|
self.select_file(f)
|
||||||
|
|
||||||
def select_dir(self, path):
|
def select_dir(self, path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
return
|
return
|
||||||
|
@ -247,7 +263,7 @@ class FilesDock(QtWidgets.QDockWidget):
|
||||||
}
|
}
|
||||||
|
|
||||||
def restore_state(self, state):
|
def restore_state(self, state):
|
||||||
if self.restore_selected:
|
if self.restore_selection:
|
||||||
self.select_dir(state["dir"])
|
self.select_dir(state["dir"])
|
||||||
self.select_file(state["file"])
|
self.select_file(state["file"])
|
||||||
self.splitter.restoreState(QtCore.QByteArray(state["splitter"]))
|
self.splitter.restoreState(QtCore.QByteArray(state["splitter"]))
|
||||||
|
|
|
@ -45,7 +45,7 @@ def get_argparser():
|
||||||
|
|
||||||
|
|
||||||
class Browser(QtWidgets.QMainWindow):
|
class Browser(QtWidgets.QMainWindow):
|
||||||
def __init__(self, smgr, datasets_sub, browse_root, select,
|
def __init__(self, smgr, datasets_sub, browse_root, restore_selection,
|
||||||
master_host, master_port):
|
master_host, master_port):
|
||||||
QtWidgets.QMainWindow.__init__(self)
|
QtWidgets.QMainWindow.__init__(self)
|
||||||
smgr.register(self)
|
smgr.register(self)
|
||||||
|
@ -70,7 +70,8 @@ class Browser(QtWidgets.QMainWindow):
|
||||||
QtCore.Qt.ScrollBarAsNeeded)
|
QtCore.Qt.ScrollBarAsNeeded)
|
||||||
self.setCentralWidget(self.experiments)
|
self.setCentralWidget(self.experiments)
|
||||||
|
|
||||||
self.files = files.FilesDock(datasets_sub, browse_root, select=select)
|
self.files = files.FilesDock(datasets_sub, browse_root,
|
||||||
|
restore_selection)
|
||||||
smgr.register(self.files)
|
smgr.register(self.files)
|
||||||
|
|
||||||
self.files.dataset_activated.connect(
|
self.files.dataset_activated.connect(
|
||||||
|
@ -85,6 +86,7 @@ class Browser(QtWidgets.QMainWindow):
|
||||||
self.datasets = datasets.DatasetsDock(
|
self.datasets = datasets.DatasetsDock(
|
||||||
datasets_sub, master_host, master_port)
|
datasets_sub, master_host, master_port)
|
||||||
smgr.register(self.datasets)
|
smgr.register(self.datasets)
|
||||||
|
self.files.metadata_changed.connect(self.datasets.metadata_changed)
|
||||||
|
|
||||||
self.log = log.LogDock(None, "log")
|
self.log = log.LogDock(None, "log")
|
||||||
smgr.register(self.log)
|
smgr.register(self.log)
|
||||||
|
@ -145,20 +147,24 @@ def main():
|
||||||
|
|
||||||
smgr = state.StateManager(args.db_file)
|
smgr = state.StateManager(args.db_file)
|
||||||
|
|
||||||
main_window = Browser(smgr, datasets_sub, args.browse_root,
|
browser = Browser(smgr, datasets_sub, args.browse_root,
|
||||||
args.select, args.server, args.port)
|
args.select is not None, args.server,
|
||||||
widget_log_handler.callback = main_window.log.append_message
|
args.port)
|
||||||
|
widget_log_handler.callback = browser.log.append_message
|
||||||
|
|
||||||
|
if args.select is not None:
|
||||||
|
browser.files.select(args.select)
|
||||||
|
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
# HACK: show the main window before creating applets.
|
# HACK: show the main window before creating applets.
|
||||||
# Otherwise, the windows of those applets that are in detached
|
# Otherwise, the windows of those applets that are in detached
|
||||||
# QDockWidgets fail to be embedded.
|
# QDockWidgets fail to be embedded.
|
||||||
main_window.show()
|
browser.show()
|
||||||
smgr.load()
|
smgr.load()
|
||||||
smgr.start()
|
smgr.start()
|
||||||
atexit_register_coroutine(smgr.stop)
|
atexit_register_coroutine(smgr.stop)
|
||||||
main_window.show()
|
browser.show()
|
||||||
loop.run_until_complete(main_window.exit_request.wait())
|
loop.run_until_complete(browser.exit_request.wait())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in New Issue