Source code for ccpn.ui.gui.lib.GuiGenerator
from collections import Mapping, Iterable
from functools import partial
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtCore
from ccpn.ui.gui.widgets.Frame import Frame
# def _updateRunArgs(argsDict, arg, value):
# argsDict[arg] = value
AUTOGEN_TAG = 'Auto-generated input:'
#TODO: document
#TODO: removed hard-coded strings
[docs]def generateWidget(params, widget, argsDict=None, columns=1):
if argsDict is None:
argsDict = {}
# widget = Container()
# # ndac = self._getNonDefaultArgCount(objMethod.run) -1 # -1 so we don't count the self arg
from ccpn.ui.gui.widgets.Label import Label
for i, param in enumerate(params):
assert isinstance(param, Mapping)
row = int(i / columns)
column = i % columns
frame = Frame(widget, setLayout=True) # ejb
frame.setObjectName('autoGeneratedFrame')
# TODO: remove style sheet hard coding
frameColour = '#BEC4F3' if 'dark' else '#000000'
frame.setStyleSheet('Frame#autoGeneratedFrame {{margin:5px; border:1px solid {};}}'
.format(frameColour))
try:
widget.layout().addWidget(frame, row, column)
except TypeError: # Compatability between our layout and PyQt's layout()
widget.layout.addWidget(frame, row, column)
l = Label(frame, param.get('label', param['variable']), grid=(0, 0))
l.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
if isinstance(param['value'], str):
from ccpn.ui.gui.widgets.LineEdit import LineEdit
le = LineEdit(frame, grid=(0, 1))
le.setText(param['default'])
le.setObjectName(AUTOGEN_TAG + param['variable'])
setattr(widget, param['variable'], le)
callback = partial(argsDict.__setitem__, param['variable'])
le.textChanged.connect(callback)
callback(le.get())
elif isinstance(param['value'], bool):
from ccpn.ui.gui.widgets.CheckBox import CheckBox
cb = CheckBox(frame, checked=param['value'], grid=(0, 1))
cb.setObjectName(AUTOGEN_TAG + param['variable'])
setattr(widget, param['variable'], cb)
cb.stateChanged.connect(partial(argsDict.__setitem__, param['variable']))
cb.setCheckState(param['default'])
argsDict[param['variable']] = param['default']
elif isinstance(param['value'], Iterable):
if isinstance(param['value'][0], str):
from ccpn.ui.gui.widgets.PulldownList import PulldownList
pdl = PulldownList(frame, texts=param['value'], grid=(0, 1))
pdl.setObjectName(AUTOGEN_TAG + param['variable'])
pdl.set(param.get('default', param['value'][0]))
setattr(widget, param['variable'], pdl)
callback = partial(argsDict.__setitem__, param['variable'])
pdl.setCallback(callback)
callback(pdl.get())
elif isinstance(param['value'][0], tuple):
if isinstance(param['value'][0][1], bool):
from ccpn.ui.gui.widgets.RadioButtons import RadioButtons
t, b = zip(*param['value'])
rb = RadioButtons(frame, texts=t, grid=(0, 1))
rb.setObjectName(AUTOGEN_TAG + param['variable'])
setattr(widget, param['variable'], rb)
rb.set(param['default'])
rb.buttonGroup.buttonClicked[QtWidgets.QAbstractButton].connect(partial(selectedRadioButton, param=param, argsDict=argsDict))
argsDict[param['variable']] = param['default']
else:
assert all([len(v) == 2 for v in param['value']])
assert all([isinstance(v[0], str) for v in param['value']])
from ccpn.ui.gui.widgets.PulldownList import PulldownList
t, o = zip(*param['value'])
pdl = PulldownList(frame, texts=t, objects=o, grid=(0, 1))
pdl.setObjectName(AUTOGEN_TAG + param['variable'])
pdl.set(param.get('default', param['value'][0]))
setattr(widget, param['variable'], pdl)
callback = partial(argsDict.__setitem__, param['variable'])
pdl.setCallback(callback)
callback(pdl.get())
elif isinstance(param['value'][0], int):
assert len(param['value']) == 2
from ccpn.ui.gui.widgets.Spinbox import Spinbox
sb = Spinbox(frame, min=param['value'][0], max=param['value'][1], grid=(0, 1))
sb.setObjectName(AUTOGEN_TAG + param['variable'])
sb.setSingleStep(param.get('stepsize', 1))
sb.setValue(param.get('default', param['value'][0]))
callback = partial(argsDict.__setitem__, param['variable'])
sb.valueChanged.connect(callback)
setattr(widget, param['variable'], sb)
callback(sb.value())
elif isinstance(param['value'][0], float):
assert len(param['value']) == 2
from ccpn.ui.gui.widgets.DoubleSpinbox import DoubleSpinbox
dsb = DoubleSpinbox(frame, min=param['value'][0], max=param['value'][1], grid=(0, 1))
dsb.setObjectName(AUTOGEN_TAG + param['variable'])
defaultStepSize = (param['value'][1] - param['value'][0]) / 100
dsb.setSingleStep(param.get('stepsize', defaultStepSize))
dsb.setValue(param.get('default', param['value'][0]))
callback = partial(argsDict.__setitem__, param['variable'])
dsb.valueChanged.connect(callback)
setattr(widget, param['variable'], dsb)
callback(dsb.value())
else:
raise NotImplementedError(param)
else:
raise NotImplementedError(param)
return widget
[docs]def selectedRadioButton(self, argsDict, param):
clicked = [b.text() for b in self.sender().buttons() if b.isChecked()]
partial(argsDict.__setitem__, param['variable'])
def _getNonDefaultArgCount(self, f:callable) -> int: # TODO: Move this to util
import inspect
count = 0
sig = inspect.signature(f)
for _, p in sig.parameters.items():
if p.default == inspect._empty:
count += 1
return count
def _anyArgsVarPositional(self, f:callable) -> int:
import inspect
sig = inspect.signature(f)
for _, p in sig.parameters.items():
if p.kind == inspect._ParameterKind.VAR_POSITIONAL:
return True
return False