File: ParameterSystem.py

package info (click to toggle)
python-pyqtgraph 0.13.7-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,068 kB
  • sloc: python: 54,043; makefile: 129; ansic: 40; sh: 2
file content (118 lines) | stat: -rw-r--r-- 4,308 bytes parent folder | download
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
__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]
        
        sets = [ch[0] for ch in changes if ch[1] == 'value']

        for param in sets:
            if param in self._fixParams:
                parent = param.parent()
                setattr(self._system, parent.name(), parent.value() if parent.hasValue() else 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)