mirror of https://github.com/m-labs/artiq.git
dashboard/moninj: fancy level setting and layout improvements. Closes #163
This commit is contained in:
parent
e7c58a7d62
commit
fc524961b2
|
@ -8,6 +8,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui
|
||||||
|
|
||||||
from artiq.tools import TaskObject
|
from artiq.tools import TaskObject
|
||||||
from artiq.protocols.sync_struct import Subscriber
|
from artiq.protocols.sync_struct import Subscriber
|
||||||
|
from artiq.gui.tools import LayoutWidget
|
||||||
from artiq.gui.flowlayout import FlowLayout
|
from artiq.gui.flowlayout import FlowLayout
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ class _MoninjWidget(QtWidgets.QFrame):
|
||||||
QtWidgets.QFrame.__init__(self)
|
QtWidgets.QFrame.__init__(self)
|
||||||
qfm = QtGui.QFontMetrics(self.font())
|
qfm = QtGui.QFontMetrics(self.font())
|
||||||
self._size = QtCore.QSize(
|
self._size = QtCore.QSize(
|
||||||
29*qfm.averageCharWidth(),
|
18*qfm.averageCharWidth(),
|
||||||
10*qfm.lineSpacing())
|
6*qfm.lineSpacing())
|
||||||
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
|
||||||
self.setFrameShape(QtWidgets.QFrame.Box)
|
self.setFrameShape(QtWidgets.QFrame.Box)
|
||||||
|
@ -53,52 +54,66 @@ class _TTLWidget(_MoninjWidget):
|
||||||
label.setWordWrap(True)
|
label.setWordWrap(True)
|
||||||
grid.addWidget(label, 1, 1)
|
grid.addWidget(label, 1, 1)
|
||||||
|
|
||||||
self._direction = QtWidgets.QLabel()
|
self.stack = QtWidgets.QStackedWidget()
|
||||||
self._direction.setAlignment(QtCore.Qt.AlignCenter)
|
grid.addWidget(self.stack, 2, 1)
|
||||||
grid.addWidget(self._direction, 2, 1)
|
|
||||||
self._override = QtWidgets.QLabel()
|
|
||||||
self._override.setAlignment(QtCore.Qt.AlignCenter)
|
|
||||||
grid.addWidget(self._override, 3, 1)
|
|
||||||
self._value = QtWidgets.QLabel()
|
|
||||||
self._value.setAlignment(QtCore.Qt.AlignCenter)
|
|
||||||
grid.addWidget(self._value, 4, 1, 6, 1)
|
|
||||||
|
|
||||||
self._value.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
self.direction = QtWidgets.QLabel()
|
||||||
menu = QtWidgets.QActionGroup(self._value)
|
self.direction.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
menu.setExclusive(True)
|
self.stack.addWidget(self.direction)
|
||||||
self._expctl_action = QtWidgets.QAction("Experiment controlled", self._value)
|
|
||||||
self._expctl_action.setCheckable(True)
|
grid_cb = LayoutWidget()
|
||||||
menu.addAction(self._expctl_action)
|
self.override = QtWidgets.QCheckBox("Override")
|
||||||
self._value.addAction(self._expctl_action)
|
grid_cb.addWidget(self.override, 3, 1)
|
||||||
self._expctl_action.triggered.connect(lambda: self.set_mode("exp"))
|
self.level = QtWidgets.QCheckBox("Level")
|
||||||
separator = QtWidgets.QAction(self._value)
|
grid_cb.addWidget(self.level, 3, 2)
|
||||||
separator.setSeparator(True)
|
self.stack.addWidget(grid_cb)
|
||||||
self._value.addAction(separator)
|
|
||||||
self._force1_action = QtWidgets.QAction("Force 1", self._value)
|
self.value = QtWidgets.QLabel()
|
||||||
self._force1_action.setCheckable(True)
|
self.value.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
menu.addAction(self._force1_action)
|
grid.addWidget(self.value, 3, 1)
|
||||||
self._value.addAction(self._force1_action)
|
|
||||||
self._force1_action.triggered.connect(lambda: self.set_mode("1"))
|
|
||||||
self._force0_action = QtWidgets.QAction("Force 0", self._value)
|
|
||||||
self._force0_action.setCheckable(True)
|
|
||||||
menu.addAction(self._force0_action)
|
|
||||||
self._value.addAction(self._force0_action)
|
|
||||||
self._force0_action.triggered.connect(lambda: self.set_mode("0"))
|
|
||||||
self._forcein_action = QtWidgets.QAction("Force input", self._value)
|
|
||||||
self._forcein_action.setCheckable(True)
|
|
||||||
self._forcein_action.setEnabled(not force_out)
|
|
||||||
menu.addAction(self._forcein_action)
|
|
||||||
self._value.addAction(self._forcein_action)
|
|
||||||
self._forcein_action.triggered.connect(lambda: self.set_mode("in"))
|
|
||||||
|
|
||||||
grid.setRowStretch(1, 1)
|
grid.setRowStretch(1, 1)
|
||||||
grid.setRowStretch(2, 0)
|
grid.setRowStretch(2, 0)
|
||||||
grid.setRowStretch(3, 0)
|
grid.setRowStretch(3, 0)
|
||||||
grid.setRowStretch(4, 0)
|
grid.setRowStretch(4, 1)
|
||||||
grid.setRowStretch(5, 1)
|
|
||||||
|
self.programmatic_change = False
|
||||||
|
self.override.stateChanged.connect(self.override_toggled)
|
||||||
|
self.level.stateChanged.connect(self.level_toggled)
|
||||||
|
|
||||||
self.set_value(0, False, False)
|
self.set_value(0, False, False)
|
||||||
|
|
||||||
|
def enterEvent(self, event):
|
||||||
|
self.stack.setCurrentIndex(1)
|
||||||
|
_MoninjWidget.enterEvent(self, event)
|
||||||
|
|
||||||
|
def leaveEvent(self, event):
|
||||||
|
if not self.override.isChecked():
|
||||||
|
self.stack.setCurrentIndex(0)
|
||||||
|
_MoninjWidget.leaveEvent(self, event)
|
||||||
|
|
||||||
|
def override_toggled(self, override):
|
||||||
|
print("override", override, self.programmatic_change)
|
||||||
|
if self.programmatic_change:
|
||||||
|
return
|
||||||
|
if override:
|
||||||
|
if self.level.isChecked():
|
||||||
|
self.set_mode("1")
|
||||||
|
else:
|
||||||
|
self.set_mode("0")
|
||||||
|
else:
|
||||||
|
self.set_mode("exp")
|
||||||
|
|
||||||
|
def level_toggled(self, level):
|
||||||
|
print("level", level, self.programmatic_change)
|
||||||
|
if self.programmatic_change:
|
||||||
|
return
|
||||||
|
if self.override.isChecked():
|
||||||
|
if level:
|
||||||
|
self.set_mode("1")
|
||||||
|
else:
|
||||||
|
self.set_mode("0")
|
||||||
|
|
||||||
def set_mode(self, mode):
|
def set_mode(self, mode):
|
||||||
data = struct.pack("bbb",
|
data = struct.pack("bbb",
|
||||||
2, # MONINJ_REQ_TTLSET
|
2, # MONINJ_REQ_TTLSET
|
||||||
|
@ -110,25 +125,22 @@ class _TTLWidget(_MoninjWidget):
|
||||||
if override:
|
if override:
|
||||||
value_s = "<b>" + value_s + "</b>"
|
value_s = "<b>" + value_s + "</b>"
|
||||||
color = " color=\"red\""
|
color = " color=\"red\""
|
||||||
self._override.setText("<font size=\"1\" color=\"red\">OVERRIDE</font>")
|
|
||||||
else:
|
else:
|
||||||
color = ""
|
color = ""
|
||||||
self._override.setText("")
|
self.value.setText("<font size=\"9\"{}>{}</font>".format(
|
||||||
self._value.setText("<font size=\"9\"{}>{}</font>".format(
|
|
||||||
color, value_s))
|
color, value_s))
|
||||||
oe = oe or self.force_out
|
oe = oe or self.force_out
|
||||||
direction = "OUT" if oe else "IN"
|
direction = "OUT" if oe else "IN"
|
||||||
self._direction.setText("<font size=\"1\">" + direction + "</font>")
|
self.direction.setText("<font size=\"1\">" + direction + "</font>")
|
||||||
|
|
||||||
|
self.programmatic_change = True
|
||||||
|
try:
|
||||||
|
self.override.setChecked(bool(override))
|
||||||
if override:
|
if override:
|
||||||
if oe:
|
self.stack.setCurrentIndex(1)
|
||||||
if value:
|
self.level.setChecked(bool(value))
|
||||||
self._force1_action.setChecked(True)
|
finally:
|
||||||
else:
|
self.programmatic_change = False
|
||||||
self._force0_action.setChecked(True)
|
|
||||||
else:
|
|
||||||
self._forcein_action.setChecked(True)
|
|
||||||
else:
|
|
||||||
self._expctl_action.setChecked(True)
|
|
||||||
|
|
||||||
|
|
||||||
class _DDSWidget(_MoninjWidget):
|
class _DDSWidget(_MoninjWidget):
|
||||||
|
@ -146,10 +158,10 @@ class _DDSWidget(_MoninjWidget):
|
||||||
label.setWordWrap(True)
|
label.setWordWrap(True)
|
||||||
grid.addWidget(label, 1, 1)
|
grid.addWidget(label, 1, 1)
|
||||||
|
|
||||||
self._value = QtWidgets.QLabel()
|
self.value = QtWidgets.QLabel()
|
||||||
self._value.setAlignment(QtCore.Qt.AlignCenter)
|
self.value.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
self._value.setWordWrap(True)
|
self.value.setWordWrap(True)
|
||||||
grid.addWidget(self._value, 2, 1, 6, 1)
|
grid.addWidget(self.value, 2, 1, 6, 1)
|
||||||
|
|
||||||
grid.setRowStretch(1, 1)
|
grid.setRowStretch(1, 1)
|
||||||
grid.setRowStretch(2, 0)
|
grid.setRowStretch(2, 0)
|
||||||
|
@ -159,8 +171,8 @@ class _DDSWidget(_MoninjWidget):
|
||||||
|
|
||||||
def set_value(self, ftw):
|
def set_value(self, ftw):
|
||||||
frequency = ftw*self.sysclk()/2**32
|
frequency = ftw*self.sysclk()/2**32
|
||||||
self._value.setText("<font size=\"6\">{:.7f} MHz</font>"
|
self.value.setText("<font size=\"5\">{:.7f} MHz</font>"
|
||||||
.format(float(frequency)/1e6))
|
.format(frequency/1e6))
|
||||||
|
|
||||||
|
|
||||||
class _DeviceManager:
|
class _DeviceManager:
|
||||||
|
@ -188,14 +200,13 @@ class _DeviceManager:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
if v["type"] == "local":
|
if v["type"] == "local":
|
||||||
title = k
|
widget = None
|
||||||
if "comment" in v:
|
|
||||||
title += ": " + v["comment"]
|
|
||||||
if v["module"] == "artiq.coredevice.ttl":
|
if v["module"] == "artiq.coredevice.ttl":
|
||||||
channel = v["arguments"]["channel"]
|
channel = v["arguments"]["channel"]
|
||||||
force_out = v["class"] == "TTLOut"
|
force_out = v["class"] == "TTLOut"
|
||||||
self.ttl_widgets[k] = _TTLWidget(
|
widget = _TTLWidget(
|
||||||
channel, self.send_to_device, force_out, title)
|
channel, self.send_to_device, force_out, k)
|
||||||
|
self.ttl_widgets[k] = widget
|
||||||
self.ttl_cb()
|
self.ttl_cb()
|
||||||
if (v["module"] == "artiq.coredevice.dds"
|
if (v["module"] == "artiq.coredevice.dds"
|
||||||
and v["class"] == "CoreDDS"):
|
and v["class"] == "CoreDDS"):
|
||||||
|
@ -204,9 +215,12 @@ class _DeviceManager:
|
||||||
and v["class"] in {"AD9858", "AD9914"}):
|
and v["class"] in {"AD9858", "AD9914"}):
|
||||||
bus_channel = v["arguments"]["bus_channel"]
|
bus_channel = v["arguments"]["bus_channel"]
|
||||||
channel = v["arguments"]["channel"]
|
channel = v["arguments"]["channel"]
|
||||||
self.dds_widgets[channel] = _DDSWidget(
|
widget = _DDSWidget(
|
||||||
bus_channel, channel, self.get_dds_sysclk, title)
|
bus_channel, channel, self.get_dds_sysclk, k)
|
||||||
|
self.dds_widgets[channel] = widget
|
||||||
self.dds_cb()
|
self.dds_cb()
|
||||||
|
if widget is not None and "comment" in v:
|
||||||
|
widget.setToolTip(v["comment"])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue