Merge branch 'qtdocks'

This commit is contained in:
Sebastien Bourdeauducq 2016-02-14 23:28:44 +01:00
commit b24146e680
10 changed files with 168 additions and 139 deletions

View File

@ -6,10 +6,8 @@ import atexit
import os
import PyQt5
from quamash import QEventLoop, QtGui, QtCore
# pyqtgraph will pick up any already imported Qt binding.
from pyqtgraph import dockarea
from quamash import QEventLoop, QtGui, QtCore, QtWidgets
assert QtGui is PyQt5.QtGui
from artiq import __artiq_dir__ as artiq_dir
from artiq.tools import *
@ -49,10 +47,14 @@ class MainWindow(QtGui.QMainWindow):
self.exit_request.set()
def save_state(self):
return bytes(self.saveGeometry())
return {
"state": bytes(self.saveState()),
"geometry": bytes(self.saveGeometry())
}
def restore_state(self, state):
self.restoreGeometry(QtCore.QByteArray(state))
self.restoreGeometry(QtCore.QByteArray(state["geometry"]))
self.restoreState(QtCore.QByteArray(state["state"]))
def main():
@ -87,33 +89,30 @@ def main():
sub_clients[notifier_name] = subscriber
# initialize main window
win = MainWindow(args.server)
dock_area = dockarea.DockArea()
smgr.register(dock_area)
smgr.register(win)
win.setCentralWidget(dock_area)
main_window = MainWindow(args.server)
smgr.register(main_window)
status_bar = QtGui.QStatusBar()
status_bar.showMessage("Connected to {}".format(args.server))
win.setStatusBar(status_bar)
main_window.setStatusBar(status_bar)
# create UI components
expmgr = experiments.ExperimentManager(status_bar, dock_area,
expmgr = experiments.ExperimentManager(main_window,
sub_clients["explist"],
sub_clients["schedule"],
rpc_clients["schedule"],
rpc_clients["experiment_db"])
smgr.register(expmgr)
d_shortcuts = shortcuts.ShortcutsDock(win, expmgr)
d_shortcuts = shortcuts.ShortcutsDock(main_window, expmgr)
smgr.register(d_shortcuts)
d_explorer = explorer.ExplorerDock(status_bar, expmgr, d_shortcuts,
sub_clients["explist"],
rpc_clients["schedule"],
rpc_clients["experiment_db"])
d_explorer = explorer.Explorer(status_bar, expmgr, d_shortcuts,
sub_clients["explist"],
rpc_clients["schedule"],
rpc_clients["experiment_db"])
d_datasets = datasets.DatasetsDock(win, sub_clients["datasets"],
d_datasets = datasets.DatasetsDock(sub_clients["datasets"],
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)
smgr.register(d_applets)
@ -125,21 +124,21 @@ def main():
d_schedule = schedule.ScheduleDock(
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)
# lay out docks
main_window.setCentralWidget(d_explorer)
if os.name != "nt":
dock_area.addDock(d_ttl_dds.dds_dock, "top")
dock_area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
dock_area.addDock(d_applets, "above", d_ttl_dds.ttl_dock)
dock_area.addDock(d_datasets, "above", d_applets)
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_ttl_dds.dds_dock)
main_window.tabifyDockWidget(d_ttl_dds.dds_dock, d_ttl_dds.ttl_dock)
main_window.tabifyDockWidget(d_ttl_dds.ttl_dock, d_applets)
main_window.tabifyDockWidget(d_applets, d_datasets)
else:
dock_area.addDock(d_applets, "top")
dock_area.addDock(d_datasets, "above", d_applets)
dock_area.addDock(d_shortcuts, "above", d_datasets)
dock_area.addDock(d_explorer, "above", d_shortcuts)
dock_area.addDock(d_schedule, "bottom")
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_applets)
main_window.tabifyDockWidget(d_applets, d_datasets)
main_window.tabifyDockWidget(d_datasets, d_shortcuts)
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_schedule)
# load/initialize state
smgr.load()
@ -149,11 +148,11 @@ def main():
# create first log dock if not already in state
d_log0 = logmgr.first_log_dock()
if d_log0 is not None:
dock_area.addDock(d_log0, "right", d_explorer)
main_window.tabifyDockWidget(d_shortcuts, d_log0)
# run
win.show()
loop.run_until_complete(win.exit_request.wait())
main_window.show()
loop.run_until_complete(main_window.exit_request.wait())
if __name__ == "__main__":
main()

View File

@ -5,10 +5,10 @@ import shlex
from functools import partial
from quamash import QtCore, QtGui, QtWidgets
from pyqtgraph import dockarea
from artiq.protocols.pipe_ipc import AsyncioParentComm
from artiq.protocols import pyon
from artiq.gui.tools import QDockWidgetCloseDetect
logger = logging.getLogger(__name__)
@ -85,12 +85,12 @@ class AppletIPCServer(AsyncioParentComm):
await asyncio.wait([self.server_task])
class AppletDock(dockarea.Dock):
class AppletDock(QDockWidgetCloseDetect):
def __init__(self, datasets_sub, uid, name, command):
dockarea.Dock.__init__(self, "applet" + str(uid),
label="Applet: " + name,
closable=True)
self.setMinimumSize(QtCore.QSize(500, 400))
QDockWidgetCloseDetect.__init__(self, "Applet: " + name)
self.setObjectName("applet" + str(uid))
self.setMinimumSize(QtCore.QSize(100, 100))
self.datasets_sub = datasets_sub
self.applet_name = name
self.command = command
@ -99,7 +99,7 @@ class AppletDock(dockarea.Dock):
def rename(self, name):
self.applet_name = name
self.label.setText("Applet: " + name)
self.setWindowTitle("Applet: " + name)
async def start(self):
if self.starting_stopping:
@ -127,7 +127,7 @@ class AppletDock(dockarea.Dock):
self.embed_window = QtGui.QWindow.fromWinId(win_id)
self.embed_widget = QtWidgets.QWidget.createWindowContainer(
self.embed_window)
self.addWidget(self.embed_widget)
self.setWidget(self.embed_widget)
# HACK: This function would not be needed if Qt window embedding
# worked correctly.
@ -181,16 +181,17 @@ _templates = [
]
class AppletsDock(dockarea.Dock):
def __init__(self, dock_area, datasets_sub):
self.dock_area = dock_area
class AppletsDock(QtWidgets.QDockWidget):
def __init__(self, main_window, datasets_sub):
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.dock_to_checkbox = dict()
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.setHorizontalHeaderLabels(["Enable", "Name", "Command"])
@ -203,7 +204,7 @@ class AppletsDock(dockarea.Dock):
QtGui.QHeaderView.ResizeToContents)
self.table.verticalHeader().hide()
self.table.setTextElideMode(QtCore.Qt.ElideNone)
self.addWidget(self.table)
self.setWidget(self.table)
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
new_action = QtGui.QAction("New applet", self.table)
@ -232,12 +233,8 @@ class AppletsDock(dockarea.Dock):
def create(self, uid, name, command):
dock = AppletDock(self.datasets_sub, uid, name, command)
# If a dock is floated and then dock state is restored, pyqtgraph
# leaves a "phantom" window open.
if self.workaround_pyqtgraph_bug:
self.dock_area.addDock(dock)
else:
self.dock_area.floatDock(dock)
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
dock.setFloating(True)
asyncio.ensure_future(dock.start())
dock.sigClosed.connect(partial(self.on_dock_closed, dock))
return dock
@ -340,7 +337,6 @@ class AppletsDock(dockarea.Dock):
return state
def restore_state(self, state):
self.workaround_pyqtgraph_bug = True
for uid, enabled, name, command in state:
row = self.new(uid)
item = QtWidgets.QTableWidgetItem()
@ -351,4 +347,3 @@ class AppletsDock(dockarea.Dock):
self.table.setItem(row, 2, item)
if enabled:
self.table.item(row, 0).setCheckState(QtCore.Qt.Checked)
self.workaround_pyqtgraph_bug = False

View File

@ -3,8 +3,7 @@ from collections import OrderedDict
from functools import partial
import logging
from quamash import QtGui, QtCore
from pyqtgraph import dockarea
from quamash import QtGui, QtCore, QtWidgets
from pyqtgraph import LayoutWidget
from artiq.tools import short_format
@ -29,14 +28,16 @@ class Model(DictSyncTreeSepModel):
raise ValueError
class DatasetsDock(dockarea.Dock):
def __init__(self, dialog_parent, datasets_sub, dataset_ctl):
dockarea.Dock.__init__(self, "Datasets")
self.dialog_parent = dialog_parent
class DatasetsDock(QtWidgets.QDockWidget):
def __init__(self, datasets_sub, dataset_ctl):
QtWidgets.QDockWidget.__init__(self, "Datasets")
self.setObjectName("Datasets")
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
QtWidgets.QDockWidget.DockWidgetFloatable)
self.dataset_ctl = dataset_ctl
grid = LayoutWidget()
self.addWidget(grid)
self.setWidget(grid)
self.search = QtGui.QLineEdit()
self.search.setPlaceholderText("search...")

View File

@ -3,11 +3,11 @@ import asyncio
from functools import partial
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
@ -133,10 +133,16 @@ class _ArgumentEditor(QtGui.QTreeWidget):
pass
class _ExperimentDock(dockarea.Dock):
class _ExperimentDock(QDockWidgetCloseDetect):
def __init__(self, manager, expurl):
dockarea.Dock.__init__(self, "Exp: " + expurl, closable=True)
self.setMinimumSize(QtCore.QSize(740, 470))
name = "Exp: " + expurl
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.setContentsMargins(5, 5, 5, 5)
@ -144,7 +150,7 @@ class _ExperimentDock(dockarea.Dock):
self.expurl = 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)
scheduling = manager.get_submission_scheduling(expurl)
@ -153,8 +159,8 @@ class _ExperimentDock(dockarea.Dock):
datetime = QtGui.QDateTimeEdit()
datetime.setDisplayFormat("MMM d yyyy hh:mm:ss")
datetime_en = QtGui.QCheckBox("Due date:")
self.addWidget(datetime_en, 1, 0)
self.addWidget(datetime, 1, 1)
self.layout.addWidget(datetime_en, 1, 0)
self.layout.addWidget(datetime, 1, 1)
if scheduling["due_date"] is None:
datetime.setDate(QtCore.QDate.currentDate())
@ -175,8 +181,8 @@ class _ExperimentDock(dockarea.Dock):
datetime_en.stateChanged.connect(update_datetime_en)
pipeline_name = QtGui.QLineEdit()
self.addWidget(QtGui.QLabel("Pipeline:"), 1, 2)
self.addWidget(pipeline_name, 1, 3)
self.layout.addWidget(QtGui.QLabel("Pipeline:"), 1, 2)
self.layout.addWidget(pipeline_name, 1, 3)
pipeline_name.setText(scheduling["pipeline_name"])
def update_pipeline_name(text):
@ -185,8 +191,8 @@ class _ExperimentDock(dockarea.Dock):
priority = QtGui.QSpinBox()
priority.setRange(-99, 99)
self.addWidget(QtGui.QLabel("Priority:"), 2, 0)
self.addWidget(priority, 2, 1)
self.layout.addWidget(QtGui.QLabel("Priority:"), 2, 0)
self.layout.addWidget(priority, 2, 1)
priority.setValue(scheduling["priority"])
def update_priority(value):
@ -195,7 +201,7 @@ class _ExperimentDock(dockarea.Dock):
flush = QtGui.QCheckBox("Flush")
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"])
def update_flush(checked):
@ -209,8 +215,8 @@ class _ExperimentDock(dockarea.Dock):
log_level.setToolTip("Minimum level for log entry production")
log_level_label = QtGui.QLabel("Logging level:")
log_level_label.setToolTip("Minimum level for log message production")
self.addWidget(log_level_label, 3, 0)
self.addWidget(log_level, 3, 1)
self.layout.addWidget(log_level_label, 3, 0)
self.layout.addWidget(log_level, 3, 1)
log_level.setCurrentIndex(log_levels.index(
log_level_to_name(options["log_level"])))
@ -224,8 +230,8 @@ class _ExperimentDock(dockarea.Dock):
repo_rev_label = QtGui.QLabel("Revision:")
repo_rev_label.setToolTip("Experiment repository revision "
"(commit ID) to use")
self.addWidget(repo_rev_label, 3, 2)
self.addWidget(repo_rev, 3, 3)
self.layout.addWidget(repo_rev_label, 3, 2)
self.layout.addWidget(repo_rev, 3, 3)
if options["repo_rev"] is not None:
repo_rev.setText(options["repo_rev"])
@ -243,7 +249,7 @@ class _ExperimentDock(dockarea.Dock):
submit.setShortcut("CTRL+RETURN")
submit.setSizePolicy(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)
reqterm = QtGui.QPushButton("Terminate instances")
@ -253,7 +259,7 @@ class _ExperimentDock(dockarea.Dock):
reqterm.setShortcut("CTRL+BACKSPACE")
reqterm.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.addWidget(reqterm, 3, 4)
self.layout.addWidget(reqterm, 3, 4)
reqterm.clicked.connect(self.reqterm_clicked)
def submit_clicked(self):
@ -287,7 +293,7 @@ class _ExperimentDock(dockarea.Dock):
self.argeditor.deleteLater()
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):
return self.argeditor.save_state()
@ -297,11 +303,10 @@ class _ExperimentDock(dockarea.Dock):
class ExperimentManager:
def __init__(self, status_bar, dock_area,
def __init__(self, main_window,
explist_sub, schedule_sub,
schedule_ctl, experiment_db_ctl):
self.status_bar = status_bar
self.dock_area = dock_area
self.main_window = main_window
self.schedule_ctl = schedule_ctl
self.experiment_db_ctl = experiment_db_ctl
@ -385,11 +390,12 @@ class ExperimentManager:
def open_experiment(self, expurl):
if expurl in self.open_experiments:
dock = self.open_experiments[expurl]
self.dock_area.floatDock(dock)
dock.setFloating(True)
return dock
dock = _ExperimentDock(self, expurl)
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))
return dock
@ -398,7 +404,8 @@ class ExperimentManager:
async def _submit_task(self, *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):
file, class_name, _ = self.resolve_expurl(expurl)
@ -436,8 +443,9 @@ class ExperimentManager:
rid, exc_info=True)
def request_inst_term(self, expurl):
self.status_bar.showMessage("Requesting termination of all instances "
"of '{}'".format(expurl))
self.main_window.statusBar().showMessage(
"Requesting termination of all instances "
"of '{}'".format(expurl))
file, class_name, use_repository = self.resolve_expurl(expurl)
rids = []
for rid, desc in self.schedule.items():

View File

@ -2,8 +2,7 @@ import asyncio
import logging
from functools import partial
from quamash import QtGui, QtCore
from pyqtgraph import dockarea
from quamash import QtGui, QtCore, QtWidgets
from pyqtgraph import LayoutWidget
from artiq.gui.models import DictSyncTreeSepModel
@ -116,13 +115,15 @@ class Model(DictSyncTreeSepModel):
DictSyncTreeSepModel.__init__(self, "/", ["Experiment"], init)
class ExplorerDock(dockarea.Dock):
class Explorer(QtWidgets.QWidget):
def __init__(self, status_bar, exp_manager, d_shortcuts,
explist_sub, schedule_ctl, experiment_db_ctl):
dockarea.Dock.__init__(self, "Explorer")
self.setMinimumSize(QtCore.QSize(300, 300))
self.layout.setSpacing(5)
self.layout.setContentsMargins(5, 5, 5, 5)
QtWidgets.QWidget.__init__(self)
layout = QtWidgets.QGridLayout()
self.setLayout(layout)
layout.setSpacing(5)
layout.setContentsMargins(5, 5, 5, 5)
self.status_bar = status_bar
self.exp_manager = exp_manager
@ -132,7 +133,7 @@ class ExplorerDock(dockarea.Dock):
self.el = QtGui.QTreeView()
self.el.setHeaderHidden(True)
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(
partial(self.expname_action, "open_experiment"))
@ -140,7 +141,7 @@ class ExplorerDock(dockarea.Dock):
open.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOpenButton))
open.setToolTip("Open the selected experiment (Return)")
self.addWidget(open, 1, 0)
layout.addWidget(open, 1, 0)
open.clicked.connect(
partial(self.expname_action, "open_experiment"))
@ -148,7 +149,7 @@ class ExplorerDock(dockarea.Dock):
submit.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOkButton))
submit.setToolTip("Schedule the selected experiment (Ctrl+Return)")
self.addWidget(submit, 1, 1)
layout.addWidget(submit, 1, 1)
submit.clicked.connect(
partial(self.expname_action, "submit"))

View File

@ -4,10 +4,10 @@ import time
import re
from functools import partial
from quamash import QtGui, QtCore
from pyqtgraph import dockarea, LayoutWidget
from quamash import QtGui, QtCore, QtWidgets
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):
@ -140,13 +140,13 @@ class _LogFilterProxyModel(QtCore.QSortFilterProxyModel):
self.invalidateFilter()
class _LogDock(dockarea.Dock):
class _LogDock(QDockWidgetCloseDetect):
def __init__(self, manager, name, log_sub):
dockarea.Dock.__init__(self, name, label="Log")
self.setMinimumSize(QtCore.QSize(720, 250))
QDockWidgetCloseDetect.__init__(self, "Log")
self.setObjectName(name)
grid = LayoutWidget()
self.addWidget(grid)
self.setWidget(grid)
grid.addWidget(QtGui.QLabel("Minimum level: "), 0, 0)
self.filter_level = QtGui.QComboBox()
@ -279,8 +279,8 @@ class _LogDock(dockarea.Dock):
class LogDockManager:
def __init__(self, dock_area, log_sub):
self.dock_area = dock_area
def __init__(self, main_window, log_sub):
self.main_window = main_window
self.log_sub = log_sub
self.docks = dict()
@ -294,7 +294,8 @@ class LogDockManager:
dock = _LogDock(self, name, self.log_sub)
self.docks[name] = dock
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))
self.update_closable()
return dock
@ -304,9 +305,12 @@ class LogDockManager:
self.update_closable()
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():
dock.setClosable(closable)
dock.setFeatures(flags)
def save_state(self):
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():
dock = _LogDock(self, name, self.log_sub)
dock.restore_state(dock_state)
self.dock_area.addDock(dock)
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
self.docks[name] = dock
self.update_closable()
def first_log_dock(self):
if self.docks:

View File

@ -4,8 +4,7 @@ import socket
import struct
from operator import itemgetter
from quamash import QtGui, QtCore
from pyqtgraph import dockarea
from quamash import QtGui, QtCore, QtWidgets
from artiq.tools import TaskObject
from artiq.protocols.sync_struct import Subscriber
@ -213,14 +212,17 @@ class _DeviceManager:
return None
class _MonInjDock(dockarea.Dock):
class _MonInjDock(QtWidgets.QDockWidget):
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()
gridw = QtGui.QWidget()
gridw.setLayout(self.grid)
self.addWidget(gridw)
self.setWidget(gridw)
def layout_widgets(self, widgets):
w = self.grid.itemAt(0)

View File

@ -2,7 +2,7 @@ import asyncio
import time
from functools import partial
from quamash import QtGui, QtCore
from quamash import QtGui, QtCore, QtWidgets
from pyqtgraph import dockarea
from artiq.gui.models import DictSyncModel
@ -55,10 +55,12 @@ class Model(DictSyncModel):
raise ValueError
class ScheduleDock(dockarea.Dock):
class ScheduleDock(QtWidgets.QDockWidget):
def __init__(self, status_bar, schedule_ctl, schedule_sub):
dockarea.Dock.__init__(self, "Schedule")
self.setMinimumSize(QtCore.QSize(740, 200))
QtWidgets.QDockWidget.__init__(self, "Schedule")
self.setObjectName("Schedule")
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
QtWidgets.QDockWidget.DockWidgetFloatable)
self.status_bar = status_bar
self.schedule_ctl = schedule_ctl
@ -71,7 +73,7 @@ class ScheduleDock(dockarea.Dock):
self.table.verticalHeader().setResizeMode(
QtGui.QHeaderView.ResizeToContents)
self.table.verticalHeader().hide()
self.addWidget(self.table)
self.setWidget(self.table)
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
request_termination_action = QtGui.QAction("Request termination", self.table)

View File

@ -2,53 +2,61 @@ import logging
from functools import partial
from quamash import QtGui, QtCore, QtWidgets
from pyqtgraph import dockarea
from pyqtgraph import LayoutWidget
logger = logging.getLogger(__name__)
class ShortcutsDock(dockarea.Dock):
class ShortcutsDock(QtWidgets.QDockWidget):
def __init__(self, main_window, exp_manager):
dockarea.Dock.__init__(self, "Shortcuts")
self.layout.setSpacing(5)
self.layout.setContentsMargins(5, 5, 5, 5)
QtWidgets.QDockWidget.__init__(self, "Shortcuts")
self.setObjectName("Shortcuts")
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.shortcut_widgets = dict()
for n, title in enumerate(["Key", "Experiment"]):
label = QtGui.QLabel("<b>" + title + "</b>")
self.addWidget(label, 0, n)
layout.addWidget(label, 0, n)
label.setMaximumHeight(label.sizeHint().height())
self.layout.setColumnStretch(1, 1)
layout.setColumnStretch(1, 1)
for i in range(12):
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.setSizePolicy(QtGui.QSizePolicy.Ignored,
QtGui.QSizePolicy.Ignored)
self.addWidget(label, row, 1)
layout.addWidget(label, row, 1)
clear = QtGui.QToolButton()
clear.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogResetButton))
self.addWidget(clear, row, 2)
layout.addWidget(clear, row, 2)
clear.clicked.connect(partial(self.set_shortcut, i, ""))
open = QtGui.QToolButton()
open.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOpenButton))
self.addWidget(open, row, 3)
layout.addWidget(open, row, 3)
open.clicked.connect(partial(self._open_experiment, i))
submit = QtGui.QPushButton("Submit")
submit.setIcon(QtGui.QApplication.style().standardIcon(
QtGui.QStyle.SP_DialogOkButton))
self.addWidget(submit, row, 4)
layout.addWidget(submit, row, 4)
submit.clicked.connect(partial(self._activated, i))
clear.hide()

View File

@ -1,6 +1,6 @@
import logging
from quamash import QtCore
from PyQt5 import QtCore, QtWidgets, QtGui
def log_level_to_name(level):
@ -27,3 +27,11 @@ class _WheelFilter(QtCore.QObject):
def disable_scroll_wheel(widget):
widget.setFocusPolicy(QtCore.Qt.StrongFocus)
widget.installEventFilter(_WheelFilter(widget))
class QDockWidgetCloseDetect(QtWidgets.QDockWidget):
sigClosed = QtCore.pyqtSignal()
def closeEvent(self, event):
self.sigClosed.emit()
QtWidgets.QDockWidget.closeEvent(self, event)