mirror of https://github.com/m-labs/artiq.git
Merge branch 'qtdocks'
This commit is contained in:
commit
b24146e680
|
@ -6,10 +6,8 @@ import atexit
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import PyQt5
|
import PyQt5
|
||||||
from quamash import QEventLoop, QtGui, QtCore
|
from quamash import QEventLoop, QtGui, QtCore, QtWidgets
|
||||||
# pyqtgraph will pick up any already imported Qt binding.
|
assert QtGui is PyQt5.QtGui
|
||||||
from pyqtgraph import dockarea
|
|
||||||
|
|
||||||
|
|
||||||
from artiq import __artiq_dir__ as artiq_dir
|
from artiq import __artiq_dir__ as artiq_dir
|
||||||
from artiq.tools import *
|
from artiq.tools import *
|
||||||
|
@ -49,10 +47,14 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
self.exit_request.set()
|
self.exit_request.set()
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return bytes(self.saveGeometry())
|
return {
|
||||||
|
"state": bytes(self.saveState()),
|
||||||
|
"geometry": bytes(self.saveGeometry())
|
||||||
|
}
|
||||||
|
|
||||||
def restore_state(self, state):
|
def restore_state(self, state):
|
||||||
self.restoreGeometry(QtCore.QByteArray(state))
|
self.restoreGeometry(QtCore.QByteArray(state["geometry"]))
|
||||||
|
self.restoreState(QtCore.QByteArray(state["state"]))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -87,33 +89,30 @@ def main():
|
||||||
sub_clients[notifier_name] = subscriber
|
sub_clients[notifier_name] = subscriber
|
||||||
|
|
||||||
# initialize main window
|
# initialize main window
|
||||||
win = MainWindow(args.server)
|
main_window = MainWindow(args.server)
|
||||||
dock_area = dockarea.DockArea()
|
smgr.register(main_window)
|
||||||
smgr.register(dock_area)
|
|
||||||
smgr.register(win)
|
|
||||||
win.setCentralWidget(dock_area)
|
|
||||||
status_bar = QtGui.QStatusBar()
|
status_bar = QtGui.QStatusBar()
|
||||||
status_bar.showMessage("Connected to {}".format(args.server))
|
status_bar.showMessage("Connected to {}".format(args.server))
|
||||||
win.setStatusBar(status_bar)
|
main_window.setStatusBar(status_bar)
|
||||||
|
|
||||||
# create UI components
|
# create UI components
|
||||||
expmgr = experiments.ExperimentManager(status_bar, dock_area,
|
expmgr = experiments.ExperimentManager(main_window,
|
||||||
sub_clients["explist"],
|
sub_clients["explist"],
|
||||||
sub_clients["schedule"],
|
sub_clients["schedule"],
|
||||||
rpc_clients["schedule"],
|
rpc_clients["schedule"],
|
||||||
rpc_clients["experiment_db"])
|
rpc_clients["experiment_db"])
|
||||||
smgr.register(expmgr)
|
smgr.register(expmgr)
|
||||||
d_shortcuts = shortcuts.ShortcutsDock(win, expmgr)
|
d_shortcuts = shortcuts.ShortcutsDock(main_window, expmgr)
|
||||||
smgr.register(d_shortcuts)
|
smgr.register(d_shortcuts)
|
||||||
d_explorer = explorer.ExplorerDock(status_bar, expmgr, d_shortcuts,
|
d_explorer = explorer.Explorer(status_bar, expmgr, d_shortcuts,
|
||||||
sub_clients["explist"],
|
sub_clients["explist"],
|
||||||
rpc_clients["schedule"],
|
rpc_clients["schedule"],
|
||||||
rpc_clients["experiment_db"])
|
rpc_clients["experiment_db"])
|
||||||
|
|
||||||
d_datasets = datasets.DatasetsDock(win, sub_clients["datasets"],
|
d_datasets = datasets.DatasetsDock(sub_clients["datasets"],
|
||||||
rpc_clients["dataset_db"])
|
rpc_clients["dataset_db"])
|
||||||
|
|
||||||
d_applets = applets.AppletsDock(dock_area, sub_clients["datasets"])
|
d_applets = applets.AppletsDock(main_window, sub_clients["datasets"])
|
||||||
atexit_register_coroutine(d_applets.stop)
|
atexit_register_coroutine(d_applets.stop)
|
||||||
smgr.register(d_applets)
|
smgr.register(d_applets)
|
||||||
|
|
||||||
|
@ -125,21 +124,21 @@ def main():
|
||||||
d_schedule = schedule.ScheduleDock(
|
d_schedule = schedule.ScheduleDock(
|
||||||
status_bar, rpc_clients["schedule"], sub_clients["schedule"])
|
status_bar, rpc_clients["schedule"], sub_clients["schedule"])
|
||||||
|
|
||||||
logmgr = log.LogDockManager(dock_area, sub_clients["log"])
|
logmgr = log.LogDockManager(main_window, sub_clients["log"])
|
||||||
smgr.register(logmgr)
|
smgr.register(logmgr)
|
||||||
|
|
||||||
# lay out docks
|
# lay out docks
|
||||||
|
main_window.setCentralWidget(d_explorer)
|
||||||
if os.name != "nt":
|
if os.name != "nt":
|
||||||
dock_area.addDock(d_ttl_dds.dds_dock, "top")
|
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_ttl_dds.dds_dock)
|
||||||
dock_area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
|
main_window.tabifyDockWidget(d_ttl_dds.dds_dock, d_ttl_dds.ttl_dock)
|
||||||
dock_area.addDock(d_applets, "above", d_ttl_dds.ttl_dock)
|
main_window.tabifyDockWidget(d_ttl_dds.ttl_dock, d_applets)
|
||||||
dock_area.addDock(d_datasets, "above", d_applets)
|
main_window.tabifyDockWidget(d_applets, d_datasets)
|
||||||
else:
|
else:
|
||||||
dock_area.addDock(d_applets, "top")
|
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_applets)
|
||||||
dock_area.addDock(d_datasets, "above", d_applets)
|
main_window.tabifyDockWidget(d_applets, d_datasets)
|
||||||
dock_area.addDock(d_shortcuts, "above", d_datasets)
|
main_window.tabifyDockWidget(d_datasets, d_shortcuts)
|
||||||
dock_area.addDock(d_explorer, "above", d_shortcuts)
|
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_schedule)
|
||||||
dock_area.addDock(d_schedule, "bottom")
|
|
||||||
|
|
||||||
# load/initialize state
|
# load/initialize state
|
||||||
smgr.load()
|
smgr.load()
|
||||||
|
@ -149,11 +148,11 @@ def main():
|
||||||
# create first log dock if not already in state
|
# create first log dock if not already in state
|
||||||
d_log0 = logmgr.first_log_dock()
|
d_log0 = logmgr.first_log_dock()
|
||||||
if d_log0 is not None:
|
if d_log0 is not None:
|
||||||
dock_area.addDock(d_log0, "right", d_explorer)
|
main_window.tabifyDockWidget(d_shortcuts, d_log0)
|
||||||
|
|
||||||
# run
|
# run
|
||||||
win.show()
|
main_window.show()
|
||||||
loop.run_until_complete(win.exit_request.wait())
|
loop.run_until_complete(main_window.exit_request.wait())
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -5,10 +5,10 @@ import shlex
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from quamash import QtCore, QtGui, QtWidgets
|
from quamash import QtCore, QtGui, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
|
||||||
|
|
||||||
from artiq.protocols.pipe_ipc import AsyncioParentComm
|
from artiq.protocols.pipe_ipc import AsyncioParentComm
|
||||||
from artiq.protocols import pyon
|
from artiq.protocols import pyon
|
||||||
|
from artiq.gui.tools import QDockWidgetCloseDetect
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -85,12 +85,12 @@ class AppletIPCServer(AsyncioParentComm):
|
||||||
await asyncio.wait([self.server_task])
|
await asyncio.wait([self.server_task])
|
||||||
|
|
||||||
|
|
||||||
class AppletDock(dockarea.Dock):
|
class AppletDock(QDockWidgetCloseDetect):
|
||||||
def __init__(self, datasets_sub, uid, name, command):
|
def __init__(self, datasets_sub, uid, name, command):
|
||||||
dockarea.Dock.__init__(self, "applet" + str(uid),
|
QDockWidgetCloseDetect.__init__(self, "Applet: " + name)
|
||||||
label="Applet: " + name,
|
self.setObjectName("applet" + str(uid))
|
||||||
closable=True)
|
self.setMinimumSize(QtCore.QSize(100, 100))
|
||||||
self.setMinimumSize(QtCore.QSize(500, 400))
|
|
||||||
self.datasets_sub = datasets_sub
|
self.datasets_sub = datasets_sub
|
||||||
self.applet_name = name
|
self.applet_name = name
|
||||||
self.command = command
|
self.command = command
|
||||||
|
@ -99,7 +99,7 @@ class AppletDock(dockarea.Dock):
|
||||||
|
|
||||||
def rename(self, name):
|
def rename(self, name):
|
||||||
self.applet_name = name
|
self.applet_name = name
|
||||||
self.label.setText("Applet: " + name)
|
self.setWindowTitle("Applet: " + name)
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
if self.starting_stopping:
|
if self.starting_stopping:
|
||||||
|
@ -127,7 +127,7 @@ class AppletDock(dockarea.Dock):
|
||||||
self.embed_window = QtGui.QWindow.fromWinId(win_id)
|
self.embed_window = QtGui.QWindow.fromWinId(win_id)
|
||||||
self.embed_widget = QtWidgets.QWidget.createWindowContainer(
|
self.embed_widget = QtWidgets.QWidget.createWindowContainer(
|
||||||
self.embed_window)
|
self.embed_window)
|
||||||
self.addWidget(self.embed_widget)
|
self.setWidget(self.embed_widget)
|
||||||
|
|
||||||
# HACK: This function would not be needed if Qt window embedding
|
# HACK: This function would not be needed if Qt window embedding
|
||||||
# worked correctly.
|
# worked correctly.
|
||||||
|
@ -181,16 +181,17 @@ _templates = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class AppletsDock(dockarea.Dock):
|
class AppletsDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, dock_area, datasets_sub):
|
def __init__(self, main_window, datasets_sub):
|
||||||
self.dock_area = dock_area
|
QtWidgets.QDockWidget.__init__(self, "Applets")
|
||||||
|
self.setObjectName("Applets")
|
||||||
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
|
||||||
|
self.main_window = main_window
|
||||||
self.datasets_sub = datasets_sub
|
self.datasets_sub = datasets_sub
|
||||||
self.dock_to_checkbox = dict()
|
self.dock_to_checkbox = dict()
|
||||||
self.applet_uids = set()
|
self.applet_uids = set()
|
||||||
self.workaround_pyqtgraph_bug = False
|
|
||||||
|
|
||||||
dockarea.Dock.__init__(self, "Applets")
|
|
||||||
self.setMinimumSize(QtCore.QSize(850, 450))
|
|
||||||
|
|
||||||
self.table = QtWidgets.QTableWidget(0, 3)
|
self.table = QtWidgets.QTableWidget(0, 3)
|
||||||
self.table.setHorizontalHeaderLabels(["Enable", "Name", "Command"])
|
self.table.setHorizontalHeaderLabels(["Enable", "Name", "Command"])
|
||||||
|
@ -203,7 +204,7 @@ class AppletsDock(dockarea.Dock):
|
||||||
QtGui.QHeaderView.ResizeToContents)
|
QtGui.QHeaderView.ResizeToContents)
|
||||||
self.table.verticalHeader().hide()
|
self.table.verticalHeader().hide()
|
||||||
self.table.setTextElideMode(QtCore.Qt.ElideNone)
|
self.table.setTextElideMode(QtCore.Qt.ElideNone)
|
||||||
self.addWidget(self.table)
|
self.setWidget(self.table)
|
||||||
|
|
||||||
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
new_action = QtGui.QAction("New applet", self.table)
|
new_action = QtGui.QAction("New applet", self.table)
|
||||||
|
@ -232,12 +233,8 @@ class AppletsDock(dockarea.Dock):
|
||||||
|
|
||||||
def create(self, uid, name, command):
|
def create(self, uid, name, command):
|
||||||
dock = AppletDock(self.datasets_sub, uid, name, command)
|
dock = AppletDock(self.datasets_sub, uid, name, command)
|
||||||
# If a dock is floated and then dock state is restored, pyqtgraph
|
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
|
||||||
# leaves a "phantom" window open.
|
dock.setFloating(True)
|
||||||
if self.workaround_pyqtgraph_bug:
|
|
||||||
self.dock_area.addDock(dock)
|
|
||||||
else:
|
|
||||||
self.dock_area.floatDock(dock)
|
|
||||||
asyncio.ensure_future(dock.start())
|
asyncio.ensure_future(dock.start())
|
||||||
dock.sigClosed.connect(partial(self.on_dock_closed, dock))
|
dock.sigClosed.connect(partial(self.on_dock_closed, dock))
|
||||||
return dock
|
return dock
|
||||||
|
@ -340,7 +337,6 @@ class AppletsDock(dockarea.Dock):
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def restore_state(self, state):
|
def restore_state(self, state):
|
||||||
self.workaround_pyqtgraph_bug = True
|
|
||||||
for uid, enabled, name, command in state:
|
for uid, enabled, name, command in state:
|
||||||
row = self.new(uid)
|
row = self.new(uid)
|
||||||
item = QtWidgets.QTableWidgetItem()
|
item = QtWidgets.QTableWidgetItem()
|
||||||
|
@ -351,4 +347,3 @@ class AppletsDock(dockarea.Dock):
|
||||||
self.table.setItem(row, 2, item)
|
self.table.setItem(row, 2, item)
|
||||||
if enabled:
|
if enabled:
|
||||||
self.table.item(row, 0).setCheckState(QtCore.Qt.Checked)
|
self.table.item(row, 0).setCheckState(QtCore.Qt.Checked)
|
||||||
self.workaround_pyqtgraph_bug = False
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ from collections import OrderedDict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
|
||||||
from pyqtgraph import LayoutWidget
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
from artiq.tools import short_format
|
from artiq.tools import short_format
|
||||||
|
@ -29,14 +28,16 @@ class Model(DictSyncTreeSepModel):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
|
||||||
class DatasetsDock(dockarea.Dock):
|
class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, dialog_parent, datasets_sub, dataset_ctl):
|
def __init__(self, datasets_sub, dataset_ctl):
|
||||||
dockarea.Dock.__init__(self, "Datasets")
|
QtWidgets.QDockWidget.__init__(self, "Datasets")
|
||||||
self.dialog_parent = dialog_parent
|
self.setObjectName("Datasets")
|
||||||
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
self.dataset_ctl = dataset_ctl
|
self.dataset_ctl = dataset_ctl
|
||||||
|
|
||||||
grid = LayoutWidget()
|
grid = LayoutWidget()
|
||||||
self.addWidget(grid)
|
self.setWidget(grid)
|
||||||
|
|
||||||
self.search = QtGui.QLineEdit()
|
self.search = QtGui.QLineEdit()
|
||||||
self.search.setPlaceholderText("search...")
|
self.search.setPlaceholderText("search...")
|
||||||
|
|
|
@ -3,11 +3,11 @@ import asyncio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
|
|
||||||
from pyqtgraph import dockarea, LayoutWidget
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
from artiq.gui.tools import log_level_to_name
|
from artiq.gui.tools import log_level_to_name, QDockWidgetCloseDetect
|
||||||
from artiq.gui.entries import argty_to_entry
|
from artiq.gui.entries import argty_to_entry
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,10 +133,16 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class _ExperimentDock(dockarea.Dock):
|
class _ExperimentDock(QDockWidgetCloseDetect):
|
||||||
def __init__(self, manager, expurl):
|
def __init__(self, manager, expurl):
|
||||||
dockarea.Dock.__init__(self, "Exp: " + expurl, closable=True)
|
name = "Exp: " + expurl
|
||||||
self.setMinimumSize(QtCore.QSize(740, 470))
|
QDockWidgetCloseDetect.__init__(self, name)
|
||||||
|
self.setObjectName(name)
|
||||||
|
|
||||||
|
self.layout = QtWidgets.QGridLayout()
|
||||||
|
top_widget = QtWidgets.QWidget()
|
||||||
|
top_widget.setLayout(self.layout)
|
||||||
|
self.setWidget(top_widget)
|
||||||
self.layout.setSpacing(5)
|
self.layout.setSpacing(5)
|
||||||
self.layout.setContentsMargins(5, 5, 5, 5)
|
self.layout.setContentsMargins(5, 5, 5, 5)
|
||||||
|
|
||||||
|
@ -144,7 +150,7 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
self.expurl = expurl
|
self.expurl = expurl
|
||||||
|
|
||||||
self.argeditor = _ArgumentEditor(self.manager, self, self.expurl)
|
self.argeditor = _ArgumentEditor(self.manager, self, self.expurl)
|
||||||
self.addWidget(self.argeditor, 0, 0, colspan=5)
|
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
||||||
self.layout.setRowStretch(0, 1)
|
self.layout.setRowStretch(0, 1)
|
||||||
|
|
||||||
scheduling = manager.get_submission_scheduling(expurl)
|
scheduling = manager.get_submission_scheduling(expurl)
|
||||||
|
@ -153,8 +159,8 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
datetime = QtGui.QDateTimeEdit()
|
datetime = QtGui.QDateTimeEdit()
|
||||||
datetime.setDisplayFormat("MMM d yyyy hh:mm:ss")
|
datetime.setDisplayFormat("MMM d yyyy hh:mm:ss")
|
||||||
datetime_en = QtGui.QCheckBox("Due date:")
|
datetime_en = QtGui.QCheckBox("Due date:")
|
||||||
self.addWidget(datetime_en, 1, 0)
|
self.layout.addWidget(datetime_en, 1, 0)
|
||||||
self.addWidget(datetime, 1, 1)
|
self.layout.addWidget(datetime, 1, 1)
|
||||||
|
|
||||||
if scheduling["due_date"] is None:
|
if scheduling["due_date"] is None:
|
||||||
datetime.setDate(QtCore.QDate.currentDate())
|
datetime.setDate(QtCore.QDate.currentDate())
|
||||||
|
@ -175,8 +181,8 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
datetime_en.stateChanged.connect(update_datetime_en)
|
datetime_en.stateChanged.connect(update_datetime_en)
|
||||||
|
|
||||||
pipeline_name = QtGui.QLineEdit()
|
pipeline_name = QtGui.QLineEdit()
|
||||||
self.addWidget(QtGui.QLabel("Pipeline:"), 1, 2)
|
self.layout.addWidget(QtGui.QLabel("Pipeline:"), 1, 2)
|
||||||
self.addWidget(pipeline_name, 1, 3)
|
self.layout.addWidget(pipeline_name, 1, 3)
|
||||||
|
|
||||||
pipeline_name.setText(scheduling["pipeline_name"])
|
pipeline_name.setText(scheduling["pipeline_name"])
|
||||||
def update_pipeline_name(text):
|
def update_pipeline_name(text):
|
||||||
|
@ -185,8 +191,8 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
|
|
||||||
priority = QtGui.QSpinBox()
|
priority = QtGui.QSpinBox()
|
||||||
priority.setRange(-99, 99)
|
priority.setRange(-99, 99)
|
||||||
self.addWidget(QtGui.QLabel("Priority:"), 2, 0)
|
self.layout.addWidget(QtGui.QLabel("Priority:"), 2, 0)
|
||||||
self.addWidget(priority, 2, 1)
|
self.layout.addWidget(priority, 2, 1)
|
||||||
|
|
||||||
priority.setValue(scheduling["priority"])
|
priority.setValue(scheduling["priority"])
|
||||||
def update_priority(value):
|
def update_priority(value):
|
||||||
|
@ -195,7 +201,7 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
|
|
||||||
flush = QtGui.QCheckBox("Flush")
|
flush = QtGui.QCheckBox("Flush")
|
||||||
flush.setToolTip("Flush the pipeline before starting the experiment")
|
flush.setToolTip("Flush the pipeline before starting the experiment")
|
||||||
self.addWidget(flush, 2, 2, colspan=2)
|
self.layout.addWidget(flush, 2, 2, 1, 2)
|
||||||
|
|
||||||
flush.setChecked(scheduling["flush"])
|
flush.setChecked(scheduling["flush"])
|
||||||
def update_flush(checked):
|
def update_flush(checked):
|
||||||
|
@ -209,8 +215,8 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
log_level.setToolTip("Minimum level for log entry production")
|
log_level.setToolTip("Minimum level for log entry production")
|
||||||
log_level_label = QtGui.QLabel("Logging level:")
|
log_level_label = QtGui.QLabel("Logging level:")
|
||||||
log_level_label.setToolTip("Minimum level for log message production")
|
log_level_label.setToolTip("Minimum level for log message production")
|
||||||
self.addWidget(log_level_label, 3, 0)
|
self.layout.addWidget(log_level_label, 3, 0)
|
||||||
self.addWidget(log_level, 3, 1)
|
self.layout.addWidget(log_level, 3, 1)
|
||||||
|
|
||||||
log_level.setCurrentIndex(log_levels.index(
|
log_level.setCurrentIndex(log_levels.index(
|
||||||
log_level_to_name(options["log_level"])))
|
log_level_to_name(options["log_level"])))
|
||||||
|
@ -224,8 +230,8 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
repo_rev_label = QtGui.QLabel("Revision:")
|
repo_rev_label = QtGui.QLabel("Revision:")
|
||||||
repo_rev_label.setToolTip("Experiment repository revision "
|
repo_rev_label.setToolTip("Experiment repository revision "
|
||||||
"(commit ID) to use")
|
"(commit ID) to use")
|
||||||
self.addWidget(repo_rev_label, 3, 2)
|
self.layout.addWidget(repo_rev_label, 3, 2)
|
||||||
self.addWidget(repo_rev, 3, 3)
|
self.layout.addWidget(repo_rev, 3, 3)
|
||||||
|
|
||||||
if options["repo_rev"] is not None:
|
if options["repo_rev"] is not None:
|
||||||
repo_rev.setText(options["repo_rev"])
|
repo_rev.setText(options["repo_rev"])
|
||||||
|
@ -243,7 +249,7 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
submit.setShortcut("CTRL+RETURN")
|
submit.setShortcut("CTRL+RETURN")
|
||||||
submit.setSizePolicy(QtGui.QSizePolicy.Expanding,
|
submit.setSizePolicy(QtGui.QSizePolicy.Expanding,
|
||||||
QtGui.QSizePolicy.Expanding)
|
QtGui.QSizePolicy.Expanding)
|
||||||
self.addWidget(submit, 1, 4, rowspan=2)
|
self.layout.addWidget(submit, 1, 4, 2, 1)
|
||||||
submit.clicked.connect(self.submit_clicked)
|
submit.clicked.connect(self.submit_clicked)
|
||||||
|
|
||||||
reqterm = QtGui.QPushButton("Terminate instances")
|
reqterm = QtGui.QPushButton("Terminate instances")
|
||||||
|
@ -253,7 +259,7 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
reqterm.setShortcut("CTRL+BACKSPACE")
|
reqterm.setShortcut("CTRL+BACKSPACE")
|
||||||
reqterm.setSizePolicy(QtGui.QSizePolicy.Expanding,
|
reqterm.setSizePolicy(QtGui.QSizePolicy.Expanding,
|
||||||
QtGui.QSizePolicy.Expanding)
|
QtGui.QSizePolicy.Expanding)
|
||||||
self.addWidget(reqterm, 3, 4)
|
self.layout.addWidget(reqterm, 3, 4)
|
||||||
reqterm.clicked.connect(self.reqterm_clicked)
|
reqterm.clicked.connect(self.reqterm_clicked)
|
||||||
|
|
||||||
def submit_clicked(self):
|
def submit_clicked(self):
|
||||||
|
@ -287,7 +293,7 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
|
|
||||||
self.argeditor.deleteLater()
|
self.argeditor.deleteLater()
|
||||||
self.argeditor = _ArgumentEditor(self.manager, self, self.expurl)
|
self.argeditor = _ArgumentEditor(self.manager, self, self.expurl)
|
||||||
self.addWidget(self.argeditor, 0, 0, colspan=5)
|
self.layout.addWidget(self.argeditor, 0, 0, 1, 5)
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return self.argeditor.save_state()
|
return self.argeditor.save_state()
|
||||||
|
@ -297,11 +303,10 @@ class _ExperimentDock(dockarea.Dock):
|
||||||
|
|
||||||
|
|
||||||
class ExperimentManager:
|
class ExperimentManager:
|
||||||
def __init__(self, status_bar, dock_area,
|
def __init__(self, main_window,
|
||||||
explist_sub, schedule_sub,
|
explist_sub, schedule_sub,
|
||||||
schedule_ctl, experiment_db_ctl):
|
schedule_ctl, experiment_db_ctl):
|
||||||
self.status_bar = status_bar
|
self.main_window = main_window
|
||||||
self.dock_area = dock_area
|
|
||||||
self.schedule_ctl = schedule_ctl
|
self.schedule_ctl = schedule_ctl
|
||||||
self.experiment_db_ctl = experiment_db_ctl
|
self.experiment_db_ctl = experiment_db_ctl
|
||||||
|
|
||||||
|
@ -385,11 +390,12 @@ class ExperimentManager:
|
||||||
def open_experiment(self, expurl):
|
def open_experiment(self, expurl):
|
||||||
if expurl in self.open_experiments:
|
if expurl in self.open_experiments:
|
||||||
dock = self.open_experiments[expurl]
|
dock = self.open_experiments[expurl]
|
||||||
self.dock_area.floatDock(dock)
|
dock.setFloating(True)
|
||||||
return dock
|
return dock
|
||||||
dock = _ExperimentDock(self, expurl)
|
dock = _ExperimentDock(self, expurl)
|
||||||
self.open_experiments[expurl] = dock
|
self.open_experiments[expurl] = dock
|
||||||
self.dock_area.floatDock(dock)
|
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
|
||||||
|
dock.setFloating(True)
|
||||||
dock.sigClosed.connect(partial(self.on_dock_closed, expurl))
|
dock.sigClosed.connect(partial(self.on_dock_closed, expurl))
|
||||||
return dock
|
return dock
|
||||||
|
|
||||||
|
@ -398,7 +404,8 @@ class ExperimentManager:
|
||||||
|
|
||||||
async def _submit_task(self, *args):
|
async def _submit_task(self, *args):
|
||||||
rid = await self.schedule_ctl.submit(*args)
|
rid = await self.schedule_ctl.submit(*args)
|
||||||
self.status_bar.showMessage("Submitted RID {}".format(rid))
|
self.main_window.statusBar().showMessage(
|
||||||
|
"Submitted RID {}".format(rid))
|
||||||
|
|
||||||
def submit(self, expurl):
|
def submit(self, expurl):
|
||||||
file, class_name, _ = self.resolve_expurl(expurl)
|
file, class_name, _ = self.resolve_expurl(expurl)
|
||||||
|
@ -436,7 +443,8 @@ class ExperimentManager:
|
||||||
rid, exc_info=True)
|
rid, exc_info=True)
|
||||||
|
|
||||||
def request_inst_term(self, expurl):
|
def request_inst_term(self, expurl):
|
||||||
self.status_bar.showMessage("Requesting termination of all instances "
|
self.main_window.statusBar().showMessage(
|
||||||
|
"Requesting termination of all instances "
|
||||||
"of '{}'".format(expurl))
|
"of '{}'".format(expurl))
|
||||||
file, class_name, use_repository = self.resolve_expurl(expurl)
|
file, class_name, use_repository = self.resolve_expurl(expurl)
|
||||||
rids = []
|
rids = []
|
||||||
|
|
|
@ -2,8 +2,7 @@ import asyncio
|
||||||
import logging
|
import logging
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
|
||||||
from pyqtgraph import LayoutWidget
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
from artiq.gui.models import DictSyncTreeSepModel
|
from artiq.gui.models import DictSyncTreeSepModel
|
||||||
|
@ -116,13 +115,15 @@ class Model(DictSyncTreeSepModel):
|
||||||
DictSyncTreeSepModel.__init__(self, "/", ["Experiment"], init)
|
DictSyncTreeSepModel.__init__(self, "/", ["Experiment"], init)
|
||||||
|
|
||||||
|
|
||||||
class ExplorerDock(dockarea.Dock):
|
class Explorer(QtWidgets.QWidget):
|
||||||
def __init__(self, status_bar, exp_manager, d_shortcuts,
|
def __init__(self, status_bar, exp_manager, d_shortcuts,
|
||||||
explist_sub, schedule_ctl, experiment_db_ctl):
|
explist_sub, schedule_ctl, experiment_db_ctl):
|
||||||
dockarea.Dock.__init__(self, "Explorer")
|
QtWidgets.QWidget.__init__(self)
|
||||||
self.setMinimumSize(QtCore.QSize(300, 300))
|
|
||||||
self.layout.setSpacing(5)
|
layout = QtWidgets.QGridLayout()
|
||||||
self.layout.setContentsMargins(5, 5, 5, 5)
|
self.setLayout(layout)
|
||||||
|
layout.setSpacing(5)
|
||||||
|
layout.setContentsMargins(5, 5, 5, 5)
|
||||||
|
|
||||||
self.status_bar = status_bar
|
self.status_bar = status_bar
|
||||||
self.exp_manager = exp_manager
|
self.exp_manager = exp_manager
|
||||||
|
@ -132,7 +133,7 @@ class ExplorerDock(dockarea.Dock):
|
||||||
self.el = QtGui.QTreeView()
|
self.el = QtGui.QTreeView()
|
||||||
self.el.setHeaderHidden(True)
|
self.el.setHeaderHidden(True)
|
||||||
self.el.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems)
|
self.el.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems)
|
||||||
self.addWidget(self.el, 0, 0, colspan=2)
|
layout.addWidget(self.el, 0, 0, 1, 2)
|
||||||
self.el.doubleClicked.connect(
|
self.el.doubleClicked.connect(
|
||||||
partial(self.expname_action, "open_experiment"))
|
partial(self.expname_action, "open_experiment"))
|
||||||
|
|
||||||
|
@ -140,7 +141,7 @@ class ExplorerDock(dockarea.Dock):
|
||||||
open.setIcon(QtGui.QApplication.style().standardIcon(
|
open.setIcon(QtGui.QApplication.style().standardIcon(
|
||||||
QtGui.QStyle.SP_DialogOpenButton))
|
QtGui.QStyle.SP_DialogOpenButton))
|
||||||
open.setToolTip("Open the selected experiment (Return)")
|
open.setToolTip("Open the selected experiment (Return)")
|
||||||
self.addWidget(open, 1, 0)
|
layout.addWidget(open, 1, 0)
|
||||||
open.clicked.connect(
|
open.clicked.connect(
|
||||||
partial(self.expname_action, "open_experiment"))
|
partial(self.expname_action, "open_experiment"))
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ class ExplorerDock(dockarea.Dock):
|
||||||
submit.setIcon(QtGui.QApplication.style().standardIcon(
|
submit.setIcon(QtGui.QApplication.style().standardIcon(
|
||||||
QtGui.QStyle.SP_DialogOkButton))
|
QtGui.QStyle.SP_DialogOkButton))
|
||||||
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
|
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
|
||||||
self.addWidget(submit, 1, 1)
|
layout.addWidget(submit, 1, 1)
|
||||||
submit.clicked.connect(
|
submit.clicked.connect(
|
||||||
partial(self.expname_action, "submit"))
|
partial(self.expname_action, "submit"))
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import time
|
||||||
import re
|
import re
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea, LayoutWidget
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
from artiq.gui.tools import log_level_to_name
|
from artiq.gui.tools import log_level_to_name, QDockWidgetCloseDetect
|
||||||
|
|
||||||
|
|
||||||
def _make_wrappable(row, width=30):
|
def _make_wrappable(row, width=30):
|
||||||
|
@ -140,13 +140,13 @@ class _LogFilterProxyModel(QtCore.QSortFilterProxyModel):
|
||||||
self.invalidateFilter()
|
self.invalidateFilter()
|
||||||
|
|
||||||
|
|
||||||
class _LogDock(dockarea.Dock):
|
class _LogDock(QDockWidgetCloseDetect):
|
||||||
def __init__(self, manager, name, log_sub):
|
def __init__(self, manager, name, log_sub):
|
||||||
dockarea.Dock.__init__(self, name, label="Log")
|
QDockWidgetCloseDetect.__init__(self, "Log")
|
||||||
self.setMinimumSize(QtCore.QSize(720, 250))
|
self.setObjectName(name)
|
||||||
|
|
||||||
grid = LayoutWidget()
|
grid = LayoutWidget()
|
||||||
self.addWidget(grid)
|
self.setWidget(grid)
|
||||||
|
|
||||||
grid.addWidget(QtGui.QLabel("Minimum level: "), 0, 0)
|
grid.addWidget(QtGui.QLabel("Minimum level: "), 0, 0)
|
||||||
self.filter_level = QtGui.QComboBox()
|
self.filter_level = QtGui.QComboBox()
|
||||||
|
@ -279,8 +279,8 @@ class _LogDock(dockarea.Dock):
|
||||||
|
|
||||||
|
|
||||||
class LogDockManager:
|
class LogDockManager:
|
||||||
def __init__(self, dock_area, log_sub):
|
def __init__(self, main_window, log_sub):
|
||||||
self.dock_area = dock_area
|
self.main_window = main_window
|
||||||
self.log_sub = log_sub
|
self.log_sub = log_sub
|
||||||
self.docks = dict()
|
self.docks = dict()
|
||||||
|
|
||||||
|
@ -294,7 +294,8 @@ class LogDockManager:
|
||||||
dock = _LogDock(self, name, self.log_sub)
|
dock = _LogDock(self, name, self.log_sub)
|
||||||
self.docks[name] = dock
|
self.docks[name] = dock
|
||||||
if add_to_area:
|
if add_to_area:
|
||||||
self.dock_area.floatDock(dock)
|
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
|
||||||
|
dock.setFloating(True)
|
||||||
dock.sigClosed.connect(partial(self.on_dock_closed, name))
|
dock.sigClosed.connect(partial(self.on_dock_closed, name))
|
||||||
self.update_closable()
|
self.update_closable()
|
||||||
return dock
|
return dock
|
||||||
|
@ -304,9 +305,12 @@ class LogDockManager:
|
||||||
self.update_closable()
|
self.update_closable()
|
||||||
|
|
||||||
def update_closable(self):
|
def update_closable(self):
|
||||||
closable = len(self.docks) > 1
|
flags = (QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
if len(self.docks) > 1:
|
||||||
|
flags |= QtWidgets.QDockWidget.DockWidgetClosable
|
||||||
for dock in self.docks.values():
|
for dock in self.docks.values():
|
||||||
dock.setClosable(closable)
|
dock.setFeatures(flags)
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return {name: dock.save_state() for name, dock in self.docks.items()}
|
return {name: dock.save_state() for name, dock in self.docks.items()}
|
||||||
|
@ -317,8 +321,9 @@ class LogDockManager:
|
||||||
for name, dock_state in state.items():
|
for name, dock_state in state.items():
|
||||||
dock = _LogDock(self, name, self.log_sub)
|
dock = _LogDock(self, name, self.log_sub)
|
||||||
dock.restore_state(dock_state)
|
dock.restore_state(dock_state)
|
||||||
self.dock_area.addDock(dock)
|
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
|
||||||
self.docks[name] = dock
|
self.docks[name] = dock
|
||||||
|
self.update_closable()
|
||||||
|
|
||||||
def first_log_dock(self):
|
def first_log_dock(self):
|
||||||
if self.docks:
|
if self.docks:
|
||||||
|
|
|
@ -4,8 +4,7 @@ import socket
|
||||||
import struct
|
import struct
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
|
||||||
|
|
||||||
from artiq.tools import TaskObject
|
from artiq.tools import TaskObject
|
||||||
from artiq.protocols.sync_struct import Subscriber
|
from artiq.protocols.sync_struct import Subscriber
|
||||||
|
@ -213,14 +212,17 @@ class _DeviceManager:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class _MonInjDock(dockarea.Dock):
|
class _MonInjDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
dockarea.Dock.__init__(self, name)
|
QtWidgets.QDockWidget.__init__(self, name)
|
||||||
|
self.setObjectName(name)
|
||||||
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
|
||||||
self.grid = QtGui.QGridLayout()
|
self.grid = QtGui.QGridLayout()
|
||||||
gridw = QtGui.QWidget()
|
gridw = QtGui.QWidget()
|
||||||
gridw.setLayout(self.grid)
|
gridw.setLayout(self.grid)
|
||||||
self.addWidget(gridw)
|
self.setWidget(gridw)
|
||||||
|
|
||||||
def layout_widgets(self, widgets):
|
def layout_widgets(self, widgets):
|
||||||
w = self.grid.itemAt(0)
|
w = self.grid.itemAt(0)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import asyncio
|
||||||
import time
|
import time
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from quamash import QtGui, QtCore
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
from pyqtgraph import dockarea
|
||||||
|
|
||||||
from artiq.gui.models import DictSyncModel
|
from artiq.gui.models import DictSyncModel
|
||||||
|
@ -55,10 +55,12 @@ class Model(DictSyncModel):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
|
||||||
class ScheduleDock(dockarea.Dock):
|
class ScheduleDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, status_bar, schedule_ctl, schedule_sub):
|
def __init__(self, status_bar, schedule_ctl, schedule_sub):
|
||||||
dockarea.Dock.__init__(self, "Schedule")
|
QtWidgets.QDockWidget.__init__(self, "Schedule")
|
||||||
self.setMinimumSize(QtCore.QSize(740, 200))
|
self.setObjectName("Schedule")
|
||||||
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
|
||||||
self.status_bar = status_bar
|
self.status_bar = status_bar
|
||||||
self.schedule_ctl = schedule_ctl
|
self.schedule_ctl = schedule_ctl
|
||||||
|
@ -71,7 +73,7 @@ class ScheduleDock(dockarea.Dock):
|
||||||
self.table.verticalHeader().setResizeMode(
|
self.table.verticalHeader().setResizeMode(
|
||||||
QtGui.QHeaderView.ResizeToContents)
|
QtGui.QHeaderView.ResizeToContents)
|
||||||
self.table.verticalHeader().hide()
|
self.table.verticalHeader().hide()
|
||||||
self.addWidget(self.table)
|
self.setWidget(self.table)
|
||||||
|
|
||||||
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
request_termination_action = QtGui.QAction("Request termination", self.table)
|
request_termination_action = QtGui.QAction("Request termination", self.table)
|
||||||
|
|
|
@ -2,53 +2,61 @@ import logging
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from quamash import QtGui, QtCore, QtWidgets
|
from quamash import QtGui, QtCore, QtWidgets
|
||||||
from pyqtgraph import dockarea
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ShortcutsDock(dockarea.Dock):
|
class ShortcutsDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, main_window, exp_manager):
|
def __init__(self, main_window, exp_manager):
|
||||||
dockarea.Dock.__init__(self, "Shortcuts")
|
QtWidgets.QDockWidget.__init__(self, "Shortcuts")
|
||||||
self.layout.setSpacing(5)
|
self.setObjectName("Shortcuts")
|
||||||
self.layout.setContentsMargins(5, 5, 5, 5)
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
|
||||||
|
layout = QtWidgets.QGridLayout()
|
||||||
|
top_widget = QtWidgets.QWidget()
|
||||||
|
top_widget.setLayout(layout)
|
||||||
|
self.setWidget(top_widget)
|
||||||
|
layout.setSpacing(5)
|
||||||
|
layout.setContentsMargins(5, 5, 5, 5)
|
||||||
|
|
||||||
self.exp_manager = exp_manager
|
self.exp_manager = exp_manager
|
||||||
self.shortcut_widgets = dict()
|
self.shortcut_widgets = dict()
|
||||||
|
|
||||||
for n, title in enumerate(["Key", "Experiment"]):
|
for n, title in enumerate(["Key", "Experiment"]):
|
||||||
label = QtGui.QLabel("<b>" + title + "</b>")
|
label = QtGui.QLabel("<b>" + title + "</b>")
|
||||||
self.addWidget(label, 0, n)
|
layout.addWidget(label, 0, n)
|
||||||
label.setMaximumHeight(label.sizeHint().height())
|
label.setMaximumHeight(label.sizeHint().height())
|
||||||
self.layout.setColumnStretch(1, 1)
|
layout.setColumnStretch(1, 1)
|
||||||
|
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
row = i + 1
|
row = i + 1
|
||||||
|
|
||||||
self.addWidget(QtGui.QLabel("F" + str(i+1)), row, 0)
|
layout.addWidget(QtGui.QLabel("F" + str(i+1)), row, 0)
|
||||||
|
|
||||||
label = QtGui.QLabel()
|
label = QtGui.QLabel()
|
||||||
label.setSizePolicy(QtGui.QSizePolicy.Ignored,
|
label.setSizePolicy(QtGui.QSizePolicy.Ignored,
|
||||||
QtGui.QSizePolicy.Ignored)
|
QtGui.QSizePolicy.Ignored)
|
||||||
self.addWidget(label, row, 1)
|
layout.addWidget(label, row, 1)
|
||||||
|
|
||||||
clear = QtGui.QToolButton()
|
clear = QtGui.QToolButton()
|
||||||
clear.setIcon(QtGui.QApplication.style().standardIcon(
|
clear.setIcon(QtGui.QApplication.style().standardIcon(
|
||||||
QtGui.QStyle.SP_DialogResetButton))
|
QtGui.QStyle.SP_DialogResetButton))
|
||||||
self.addWidget(clear, row, 2)
|
layout.addWidget(clear, row, 2)
|
||||||
clear.clicked.connect(partial(self.set_shortcut, i, ""))
|
clear.clicked.connect(partial(self.set_shortcut, i, ""))
|
||||||
|
|
||||||
open = QtGui.QToolButton()
|
open = QtGui.QToolButton()
|
||||||
open.setIcon(QtGui.QApplication.style().standardIcon(
|
open.setIcon(QtGui.QApplication.style().standardIcon(
|
||||||
QtGui.QStyle.SP_DialogOpenButton))
|
QtGui.QStyle.SP_DialogOpenButton))
|
||||||
self.addWidget(open, row, 3)
|
layout.addWidget(open, row, 3)
|
||||||
open.clicked.connect(partial(self._open_experiment, i))
|
open.clicked.connect(partial(self._open_experiment, i))
|
||||||
|
|
||||||
submit = QtGui.QPushButton("Submit")
|
submit = QtGui.QPushButton("Submit")
|
||||||
submit.setIcon(QtGui.QApplication.style().standardIcon(
|
submit.setIcon(QtGui.QApplication.style().standardIcon(
|
||||||
QtGui.QStyle.SP_DialogOkButton))
|
QtGui.QStyle.SP_DialogOkButton))
|
||||||
self.addWidget(submit, row, 4)
|
layout.addWidget(submit, row, 4)
|
||||||
submit.clicked.connect(partial(self._activated, i))
|
submit.clicked.connect(partial(self._activated, i))
|
||||||
|
|
||||||
clear.hide()
|
clear.hide()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from quamash import QtCore
|
from PyQt5 import QtCore, QtWidgets, QtGui
|
||||||
|
|
||||||
|
|
||||||
def log_level_to_name(level):
|
def log_level_to_name(level):
|
||||||
|
@ -27,3 +27,11 @@ class _WheelFilter(QtCore.QObject):
|
||||||
def disable_scroll_wheel(widget):
|
def disable_scroll_wheel(widget):
|
||||||
widget.setFocusPolicy(QtCore.Qt.StrongFocus)
|
widget.setFocusPolicy(QtCore.Qt.StrongFocus)
|
||||||
widget.installEventFilter(_WheelFilter(widget))
|
widget.installEventFilter(_WheelFilter(widget))
|
||||||
|
|
||||||
|
|
||||||
|
class QDockWidgetCloseDetect(QtWidgets.QDockWidget):
|
||||||
|
sigClosed = QtCore.pyqtSignal()
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.sigClosed.emit()
|
||||||
|
QtWidgets.QDockWidget.closeEvent(self, event)
|
||||||
|
|
Loading…
Reference in New Issue