Skip to content

Commit

Permalink
gui: rough conversion to the Qt docking system
Browse files Browse the repository at this point in the history
sbourdeauducq committed Feb 14, 2016
1 parent ed36a96 commit daf49ef
Showing 9 changed files with 159 additions and 130 deletions.
48 changes: 21 additions & 27 deletions artiq/frontend/artiq_gui.py
Original file line number Diff line number Diff line change
@@ -6,11 +6,8 @@
import os

import PyQt5
from quamash import QEventLoop, QtGui, QtCore
from quamash import QEventLoop, QtGui, QtCore, QtWidgets
assert QtGui is PyQt5.QtGui
# pyqtgraph will pick up any already imported Qt binding.
from pyqtgraph import dockarea


from artiq import __artiq_dir__ as artiq_dir
from artiq.tools import *
@@ -88,33 +85,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_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)

@@ -126,21 +120,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
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.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_ttl_dds.ttl_dock)
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_applets)
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, 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.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_datasets)
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, d_shortcuts)
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, d_explorer)
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, d_schedule)

# load/initialize state
smgr.load()
@@ -150,11 +144,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.addDockWidget(QtCore.Qt.TopDockWidgetArea, 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()
46 changes: 22 additions & 24 deletions artiq/gui/applets.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
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
@@ -85,12 +84,13 @@ async def stop(self):
await asyncio.wait([self.server_task])


class AppletDock(dockarea.Dock):
class AppletDock(QtWidgets.QDockWidget):
sigClosed = QtCore.pyqtSignal()

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))
QtWidgets.QDockWidget.__init__(self, "Applet: " + name)
self.setObjectName("applet" + str(uid))

self.datasets_sub = datasets_sub
self.applet_name = name
self.command = command
@@ -99,7 +99,7 @@ def __init__(self, datasets_sub, uid, name, command):

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 @@ def embed(self, win_id):
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.
@@ -164,6 +164,10 @@ async def restart(self):
await self.terminate()
await self.start()

def closeEvent(self, event):
QtWidgets.QDockWidget.closeEvent(self, event)
self.sigClosed.emit()


_templates = [
("Big number", "{python} -m artiq.applets.big_number "
@@ -181,16 +185,16 @@ async def restart(self):
]


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.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 +207,7 @@ def __init__(self, dock_area, datasets_sub):
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 +236,8 @@ def __init__(self, dock_area, datasets_sub):

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 +340,6 @@ def save_state(self):
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 +350,3 @@ def restore_state(self, state):
self.table.setItem(row, 2, item)
if enabled:
self.table.item(row, 0).setCheckState(QtCore.Qt.Checked)
self.workaround_pyqtgraph_bug = False
14 changes: 7 additions & 7 deletions artiq/gui/datasets.py
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@
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,15 @@ def convert(self, k, v, column):
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.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...")
Loading

0 comments on commit daf49ef

Please sign in to comment.