1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
__all__ = ["ParameterSystem", "SystemSolver"]
from .. import functions as fn
from .parameterTypes import GroupParameter
from .SystemSolver import SystemSolver
class ParameterSystem(GroupParameter):
"""
ParameterSystem is a subclass of GroupParameter that manages a tree of
sub-parameters with a set of interdependencies--changing any one parameter
may affect other parameters in the system.
See parametertree/SystemSolver for more information.
NOTE: This API is experimental and may change substantially across minor
version numbers.
"""
def __init__(self, *args, **kwds):
GroupParameter.__init__(self, *args, **kwds)
self._system = None
self._fixParams = [] # all auto-generated 'fixed' params
sys = kwds.pop('system', None)
if sys is not None:
self.setSystem(sys)
self._ignoreChange = [] # params whose changes should be ignored temporarily
self.sigTreeStateChanged.connect(self.updateSystem)
def setSystem(self, sys):
self._system = sys
# auto-generate defaults to match child parameters
defaults = {}
vals = {}
for param in self:
name = param.name()
constraints = ''
if hasattr(sys, '_' + name):
constraints += 'n'
if not param.readonly():
constraints += 'f'
if 'n' in constraints:
ch = param.addChild(dict(name='fixed', type='bool', value=False))
self._fixParams.append(ch)
param.setReadonly(True)
param.setOpts(expanded=False)
else:
vals[name] = param.value()
ch = param.addChild(dict(name='fixed', type='bool', value=True, readonly=True))
#self._fixParams.append(ch)
defaults[name] = [None, param.type(), None, constraints]
sys.defaultState.update(defaults)
sys.reset()
for name, value in vals.items():
setattr(sys, name, value)
self.updateAllParams()
def updateSystem(self, param, changes):
changes = [ch for ch in changes if ch[0] not in self._ignoreChange]
#resets = [ch[0] for ch in changes if ch[1] == 'setToDefault']
sets = [ch[0] for ch in changes if ch[1] == 'value']
#for param in resets:
#setattr(self._system, param.name(), None)
for param in sets:
#if param in resets:
#continue
#if param in self._fixParams:
#param.parent().setWritable(param.value())
#else:
if param in self._fixParams:
parent = param.parent()
if param.value():
setattr(self._system, parent.name(), parent.value())
else:
setattr(self._system, parent.name(), None)
else:
setattr(self._system, param.name(), param.value())
self.updateAllParams()
def updateAllParams(self):
try:
self.sigTreeStateChanged.disconnect(self.updateSystem)
for name, state in self._system._vars.items():
param = self.child(name)
try:
v = getattr(self._system, name)
if self._system._vars[name][2] is None:
self.updateParamState(self.child(name), 'autoSet')
param.setValue(v)
else:
self.updateParamState(self.child(name), 'fixed')
except RuntimeError:
self.updateParamState(param, 'autoUnset')
finally:
self.sigTreeStateChanged.connect(self.updateSystem)
def updateParamState(self, param, state):
if state == 'autoSet':
bg = fn.mkBrush((200, 255, 200, 255))
bold = False
readonly = True
elif state == 'autoUnset':
bg = fn.mkBrush(None)
bold = False
readonly = False
elif state == 'fixed':
bg = fn.mkBrush('y')
bold = True
readonly = False
else:
raise ValueError("'state' must be one of 'autoSet', 'autoUnset', or 'fixed'")
param.setReadonly(readonly)
#for item in param.items:
#item.setBackground(0, bg)
#f = item.font(0)
#f.setWeight(f.Bold if bold else f.Normal)
#item.setFont(0, f)
|