GUI: show grouping of parameters
still todo: grouping of modules Change-Id: I67e8582004f16061dda96e455f424f5a12e6a163
This commit is contained in:
@ -8,7 +8,7 @@ description = short description
|
||||
[interface tcp]
|
||||
interface=tcp
|
||||
bindto=0.0.0.0
|
||||
bindport=10769
|
||||
bindport=10767
|
||||
# protocol to use for this interface
|
||||
framing=eol
|
||||
encoding=demo
|
||||
@ -39,3 +39,8 @@ timeout=900
|
||||
# some (non-default) parameter properties
|
||||
pollinterval.export=False
|
||||
|
||||
# some parameter grouping
|
||||
p.group='pid'
|
||||
i.group='pid'
|
||||
d.group='pid'
|
||||
|
||||
|
@ -469,8 +469,11 @@ class Client(object):
|
||||
def getParameters(self, module):
|
||||
return self.describing_data['modules'][module]['parameters'].keys()
|
||||
|
||||
def getModuleProperties(self, module):
|
||||
return self.describing_data['modules'][module]['properties']
|
||||
|
||||
def getModuleBaseClass(self, module):
|
||||
return self.describing_data['modules'][module]['interfaceclass']
|
||||
return self.getModuleProperties(module)['interface']
|
||||
|
||||
def getCommands(self, module):
|
||||
return self.describing_data['modules'][module]['commands'].keys()
|
||||
|
@ -65,15 +65,15 @@ class Cryostat(CryoBase):
|
||||
maxpower=PARAM("Maximum heater power",
|
||||
validator=nonnegative, default=1, unit="W",
|
||||
readonly=False,
|
||||
group='heater',
|
||||
group='heater_settings',
|
||||
),
|
||||
heater=PARAM("current heater setting",
|
||||
validator=floatrange(0, 100), default=0, unit="%",
|
||||
group='heater',
|
||||
group='heater_settings',
|
||||
),
|
||||
heaterpower=PARAM("current heater power",
|
||||
validator=nonnegative, default=0, unit="W",
|
||||
group='heater',
|
||||
group='heater_settings',
|
||||
),
|
||||
target=PARAM("target temperature",
|
||||
validator=nonnegative, default=0, unit="K",
|
||||
@ -110,17 +110,17 @@ class Cryostat(CryoBase):
|
||||
tolerance=PARAM("temperature range for stability checking",
|
||||
validator=floatrange(0, 100), default=0.1, unit='K',
|
||||
readonly=False,
|
||||
group='window',
|
||||
group='stability',
|
||||
),
|
||||
window=PARAM("time window for stability checking",
|
||||
validator=floatrange(1, 900), default=30, unit='s',
|
||||
readonly=False,
|
||||
group='window',
|
||||
group='stability',
|
||||
),
|
||||
timeout=PARAM("max waiting time for stabilisation check",
|
||||
validator=floatrange(1, 36000), default=900, unit='s',
|
||||
readonly=False,
|
||||
group='window',
|
||||
group='stability',
|
||||
),
|
||||
)
|
||||
CMDS = dict(
|
||||
|
@ -33,9 +33,9 @@ from secop.client.baseclient import Client as SECNode
|
||||
import sys
|
||||
|
||||
ITEM_TYPE_NODE = QTreeWidgetItem.UserType + 1
|
||||
ITEM_TYPE_MODULE = QTreeWidgetItem.UserType + 2
|
||||
ITEM_TYPE_PARAMETER = QTreeWidgetItem.UserType + 3
|
||||
|
||||
ITEM_TYPE_GROUP = QTreeWidgetItem.UserType + 2
|
||||
ITEM_TYPE_MODULE = QTreeWidgetItem.UserType + 3
|
||||
ITEM_TYPE_PARAMETER = QTreeWidgetItem.UserType + 4
|
||||
|
||||
|
||||
class QSECNode(SECNode, QObject):
|
||||
@ -111,6 +111,8 @@ class MainWindow(QMainWindow):
|
||||
def on_treeWidget_currentItemChanged(self, current, previous):
|
||||
if current.type() == ITEM_TYPE_NODE:
|
||||
self._displayNode(current.text(0))
|
||||
elif current.type() == ITEM_TYPE_GROUP:
|
||||
self._displayGroup(current.parent().text(0), current.text(0))
|
||||
elif current.type() == ITEM_TYPE_MODULE:
|
||||
self._displayModule(current.parent().text(0), current.text(0))
|
||||
elif current.type() == ITEM_TYPE_PARAMETER:
|
||||
|
@ -21,7 +21,7 @@
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
from PyQt4.QtGui import QWidget, QLabel, QMessageBox
|
||||
from PyQt4.QtGui import QWidget, QLabel, QMessageBox, QCheckBox
|
||||
from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal
|
||||
|
||||
from secop.gui.util import loadUi
|
||||
@ -55,6 +55,38 @@ class ParameterButtons(QWidget):
|
||||
self.setLineEdit.text())
|
||||
|
||||
|
||||
class ParameterGroup(QWidget):
|
||||
def __init__(self, groupname, parent=None):
|
||||
super(ParameterGroup, self).__init__(parent)
|
||||
loadUi(self, 'paramgroup.ui')
|
||||
|
||||
self._groupname = groupname
|
||||
|
||||
self._row = 0
|
||||
self._widgets = []
|
||||
|
||||
self.paramGroupBox.setTitle('Group: ' + str(groupname))
|
||||
self.paramGroupBox.toggled.connect(self.on_toggle_clicked)
|
||||
self.paramGroupBox.setChecked(False)
|
||||
|
||||
def addWidgets(self, label, widget):
|
||||
self._widgets.extend((label, widget))
|
||||
self.paramGroupBox.layout().addWidget(label, self._row, 0)
|
||||
self.paramGroupBox.layout().addWidget(widget, self._row, 1)
|
||||
label.hide()
|
||||
widget.hide()
|
||||
self._row += 1
|
||||
|
||||
def on_toggle_clicked(self):
|
||||
print "ParameterGroup.on_toggle_clicked"
|
||||
if self.paramGroupBox.isChecked():
|
||||
for w in self._widgets:
|
||||
w.show()
|
||||
else:
|
||||
for w in self._widgets:
|
||||
w.hide()
|
||||
|
||||
|
||||
class ModuleCtrl(QWidget):
|
||||
|
||||
def __init__(self, node, module, parent=None):
|
||||
@ -65,50 +97,128 @@ class ModuleCtrl(QWidget):
|
||||
self._lastclick = None
|
||||
|
||||
self._paramWidgets = {} # widget cache do avoid garbage collection
|
||||
self._groupWidgets = {} # cache of grouping widgets
|
||||
|
||||
self._labelfont = self.font()
|
||||
self._labelfont.setBold(True)
|
||||
|
||||
self.moduleNameLabel.setText(module)
|
||||
self._initModuleWidgets()
|
||||
|
||||
self._node.newData.connect(self._updateValue)
|
||||
|
||||
|
||||
def _initModuleWidgets(self):
|
||||
initValues = self._node.queryCache(self._module)
|
||||
row = 0
|
||||
|
||||
font = self.font()
|
||||
font.setBold(True)
|
||||
|
||||
for param in sorted(self._node.getParameters(self._module)):
|
||||
labelstr = param + ':'
|
||||
unit = self._node.getProperties(self._module, param).get('unit',
|
||||
'')
|
||||
descr = self._node.getProperties(self._module,
|
||||
param).get('description', '')
|
||||
|
||||
if unit:
|
||||
labelstr = "%s (%s):" % (param, unit)
|
||||
|
||||
label = QLabel(labelstr)
|
||||
label.setFont(font)
|
||||
|
||||
# collect grouping information
|
||||
paramsByGroup = {} # groupname -> [paramnames]
|
||||
allGroups = set()
|
||||
params = self._node.getParameters(self._module)
|
||||
for param in params:
|
||||
props = self._node.getProperties(self._module, param)
|
||||
group = props.get('group',None)
|
||||
if group is not None:
|
||||
allGroups.add(group)
|
||||
paramsByGroup.setdefault(group, []).append(param)
|
||||
|
||||
buttons = ParameterButtons(self._module, param,
|
||||
initValues[param].value,
|
||||
props['readonly'])
|
||||
groupWidgets = {} # groupname -> CheckBoxWidget for (un)folding
|
||||
|
||||
# buttons.setRequested.connect(self._node.setParameter)
|
||||
buttons.setRequested.connect(self._set_Button_pressed)
|
||||
# create and insert widgets into our QGridLayout
|
||||
for param in sorted(allGroups.union(set(params))):
|
||||
labelstr = param + ':'
|
||||
if param in paramsByGroup:
|
||||
group = param
|
||||
# is the name of a group -> create (un)foldable label
|
||||
checkbox = QCheckBox(labelstr)
|
||||
checkbox.setFont(self._labelfont)
|
||||
groupWidgets[param] = checkbox
|
||||
|
||||
if descr:
|
||||
buttons.setToolTip(descr)
|
||||
# check if there is a param of the same name too
|
||||
if group in params:
|
||||
# yes: create a widget for this as well
|
||||
labelstr, buttons = self._makeEntry(param, initValues[param].value, nolabel=True, checkbox=checkbox, invert=True)
|
||||
checkbox.setText(labelstr)
|
||||
|
||||
# add to Layout (yes: ignore the label!)
|
||||
self.paramGroupBox.layout().addWidget(checkbox, row, 0)
|
||||
self.paramGroupBox.layout().addWidget(buttons, row, 1)
|
||||
else:
|
||||
self.paramGroupBox.layout().addWidget(checkbox, row, 0, 1, 2) # or .. 1, 2) ??
|
||||
row += 1
|
||||
|
||||
# loop over all params and insert and connect
|
||||
for param in paramsByGroup[param]:
|
||||
if param == group:
|
||||
continue
|
||||
label, buttons = self._makeEntry(param, initValues[param].value, checkbox=checkbox, invert=False)
|
||||
|
||||
# add to Layout
|
||||
self.paramGroupBox.layout().addWidget(label, row, 0)
|
||||
self.paramGroupBox.layout().addWidget(buttons, row, 1)
|
||||
row += 1
|
||||
|
||||
else:
|
||||
# param is a 'normal' param: create a widget if it has no group or is named after a group (otherwise its created above)
|
||||
props = self._node.getProperties(self._module, param)
|
||||
if props.get('group', param) == param:
|
||||
label, buttons = self._makeEntry(param, initValues[param].value)
|
||||
|
||||
# add to Layout
|
||||
self.paramGroupBox.layout().addWidget(label, row, 0)
|
||||
self.paramGroupBox.layout().addWidget(buttons, row, 1)
|
||||
row += 1
|
||||
|
||||
|
||||
def _makeEntry(self, param, initvalue, nolabel=False, checkbox=None, invert=False):
|
||||
props = self._node.getProperties(self._module, param)
|
||||
|
||||
description = props.get('description', '')
|
||||
unit = props.get('unit','')
|
||||
|
||||
if unit:
|
||||
labelstr = '%s (%s):' % (param, unit)
|
||||
else:
|
||||
labelstr = '%s:' % (param,)
|
||||
|
||||
if checkbox and not invert:
|
||||
labelstr = ' ' + labelstr
|
||||
|
||||
buttons = ParameterButtons(self._module, param, initvalue, props['readonly'])
|
||||
buttons.setRequested.connect(self._set_Button_pressed)
|
||||
|
||||
if description:
|
||||
buttons.setToolTip(description)
|
||||
|
||||
if nolabel:
|
||||
label = labelstr
|
||||
else:
|
||||
label = QLabel(labelstr)
|
||||
label.setFont(self._labelfont)
|
||||
|
||||
if checkbox:
|
||||
def stateChanged(newstate, buttons=buttons, label=None if nolabel else label, invert=invert):
|
||||
if (newstate and not invert) or (invert and not newstate):
|
||||
buttons.show()
|
||||
if label:
|
||||
label.show()
|
||||
else:
|
||||
buttons.hide()
|
||||
if label:
|
||||
label.hide()
|
||||
# set initial state
|
||||
stateChanged(0)
|
||||
# connect
|
||||
checkbox.stateChanged.connect(stateChanged)
|
||||
|
||||
self._paramWidgets[param] = (label, buttons)
|
||||
|
||||
row += 1
|
||||
return label, buttons
|
||||
|
||||
|
||||
|
||||
|
||||
def _set_Button_pressed(self, module, parameter, target):
|
||||
sig = (module, parameter, target)
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<width>238</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -55,7 +55,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="propertyGroupBox">
|
||||
<property name="title">
|
||||
<string>Parameters:</string>
|
||||
<string>Properties</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
|
Reference in New Issue
Block a user