Hi All!<div><br></div><div>I am developing a custom widget system. The widgets are written in C++, since the rendering requires very high performance. The widgets are loaded from xml files. A widget can contain several different UI elements, for example a slider, a textbox, a label, buttons, etc... Until now I used a simple but quite powerful solution to synchronize the UI values and the python object attributes. The concept is the following: C++ UI elements can have properties (see the code below). Properties can be bounded to a python object's attribute. If a property changes, it sets the python attribute, and after the setter ran, it gets the actual python value, and sets the property's value to it. (For better understanding: when a property changes because of some user input it rather suggests a value then set it. This is useful when for example you want a slider to be able to set only to odd values, or want to limit the availible values of a numeric text box. So this way you have full control of the "control UI elements" values.) From the other side: when you set an attribute of the python object the object checks if it is bounded to any C++ property, and if it is, then it sets the property to the value. Here are some code snippets:</div>
<div><br></div><div>This is the C++ property:</div><div><br></div><div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #c800a7">template<span style="color: #000000"> <</span>typename<span style="color: #000000"> T> </span>class<span style="color: #000000"> Property : </span>public<span style="color: #000000"> </span><span style="color: #448388">PythonPropertyBinder</span><span style="color: #000000"> {</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #c800a7"><span style="color: #000000"> </span>public<span style="color: #000000">:</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">void</span> bindToAttribute(<span style="color: #448388">PythonComponent</span>* component,<span style="color: #7b1caf">std</span>::<span style="color: #7b1caf">string</span> name) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <font class="Apple-style-span" color="#c800a7">//Add a PyCFunction to the bindings of the python object.</font> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">void</span> unbind() {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <font class="Apple-style-span" color="#c800a7">//Remove the bindings.</font></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> T& <span style="color: #c800a7">operator</span>= (<span style="color: #c800a7">const</span> <span style="color: #448388">Property</span><T>& p) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">return</span> (*<span style="color: #c800a7">this</span> = p.value);</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> T & <span style="color: #c800a7">operator</span> = (<span style="color: #c800a7">const</span> T &i) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">if</span>(!<span style="color: #448388">updating</span>) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">updating</span> = <span style="color: #c800a7">true</span>;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">if</span>(<span style="color: #448388">component</span>) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">component</span>->setAttribute(i, <span style="color: #448388">pythonAttributeName</span>.<span style="color: #470086">c_str</span>());</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">component</span>->getAttribute(<span style="color: #448388">value</span>,<span style="color: #448388">pythonAttributeName</span>.<span style="color: #470086">c_str</span>());</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #470086">PyErr_Print</span>();</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">else</span> {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">value</span> = i;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">updating</span> = <span style="color: #c800a7">false</span>;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #295a5e">notifyObservers</span>();</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">return</span> <span style="color: #448388">value</span>;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }<span style="color: #c800a7">else</span> {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">return</span> <span style="color: #448388">value</span>;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">operator</span> T <span style="color: #c800a7">const</span> & () <span style="color: #c800a7">const</span> {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">return</span> <span style="color: #448388">value</span>;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">void</span> addObserver(<span style="color: #448388">PythonPropertyBinderObserver</span>* observer) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">observers</span>.insert(observer);</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #c800a7">void</span> removeObserver(<span style="color: #448388">PythonPropertyBinderObserver</span>* observer) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">observers</span>.erase(observer);</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> Property(<span style="color: #c800a7">const</span> T& v):Property() {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">value</span> = v;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> Property():<span style="color: #448388">updating</span>(<span style="color: #c800a7">false</span>),<span style="color: #448388">component</span>(<span style="color: #c800a7">nullptr</span>) {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> //set up stuff...</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> ~Property() {</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #295a5e">unbind</span>();</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> }</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #c800a7"><span style="color: #000000"> </span>private<span style="color: #000000">:</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> T value;</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #7b1caf">std</span>::<span style="color: #7b1caf">string</span> pythonAttributeName;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <font class="Apple-style-span" color="#c800a7">//...not interesting</font></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> };</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">
<br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">And for example a slider looks like the following:</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">
<br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #448388"><span style="color: #c800a7">class</span><span style="color: #000000"> Slider : </span><span style="color: #c800a7">public</span><span style="color: #000000"> </span>View<span style="color: #000000">, </span><span style="color: #c800a7">public</span><span style="color: #000000"> </span>PythonPropertyBinderObserver<span style="color: #000000"> {</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #c800a7"><span style="color: #000000"> </span>public<span style="color: #000000">:</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"> //...</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px"><br></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">Property</span><<span style="color: #c800a7">double</span>> value;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">Property</span><<span style="color: #c800a7">double</span>> low;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"> <span style="color: #448388">Property</span><<span style="color: #c800a7">double</span>> high;</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">
//...</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">};</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br>
</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">The python class:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
<span style="color: #3c00ff">class</span> Component(object):</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
<span class="Apple-style-span"><span style="color: #3c00ff"> def</span> bind_to_attribute(self,attribute_name,</span> cpp_property_setter<span class="Apple-style-span">):</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span> <span style="color: #3c00ff">not</span> hasattr(self,attribute_name):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">return</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span> self.binder_functions.has_key(attribute_name):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span"> self.binder_functions[attribute_name].add(</span>cpp_property_setter<span class="Apple-style-span">)</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">else</span>:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> s = set()</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span"> s.add(</span>cpp_property_setter<span class="Apple-style-span">)</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.binder_functions[attribute_name] = s </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span"> <span style="color: #3c00ff">def</span> unbind_from_attribute(self,attribute_name,</span> cpp_property_setter<span class="Apple-style-span">):</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span> self.binder_functions.has_key(attribute_name):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span"> self.binder_functions[attribute_name].remove(</span>cpp_property_setter<span class="Apple-style-span">)</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> __setattr__(self,attributename,value):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> super(Component,self).__setattr__(attributename,value)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.sync_attribute(attributename)</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> sync_attribute(self,attributename):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span>(hasattr(self,<span style="color: #00bf00">'binder_functions'</span>) <span style="color: #3c00ff">and</span> self.binder_functions.has_key(attributename)):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> s = self.binder_functions[attributename]</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">for</span> cpp_property_setter <span style="color: #3c00ff">in</span> s:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span class="Apple-style-span"> </span>cpp_property_setter<span class="Apple-style-span">()</span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
<br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #00bf00">'''</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00"> And several other methods...</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00"> '''</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00">
<span class="Apple-style-span" style="color: rgb(0, 0, 0); ">So this way I can simply bind a UI element's property to a python attribute, and it is guaranteed that they will be the same (until a python property is not accessed by its setter...) </span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00"><span class="Apple-style-span" style="color: rgb(0, 0, 0); ">For example:</span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; color: #00bf00">
<span class="Apple-style-span" style="color: rgb(0, 0, 0); "> </span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "> <span class="Apple-style-span" style="color: rgb(0, 0, 0); "></span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><span style="color: #3c00ff">class</span> Slider(Component):</p><span class="Apple-style-span" style="color: rgb(0, 0, 0); ">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> get_value(self):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">return</span> self.__value</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> set_value(self,value):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span>((value<=self.high <span style="color: #3c00ff">and</span> value>=self.low) <span style="color: #3c00ff">or</span> (value>=self.high <span style="color: #3c00ff">and</span> value<=self.low)):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">if</span> self.integers_only:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.__value = round(value)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">else</span>:</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.__value = value</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.run()</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> get_high(self):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">return</span> self.__high </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> set_high(self,high):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.__high = high</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> get_low(self):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">return</span> self.__low</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> <span style="color: #3c00ff">def</span> set_low(self,low):</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> self.low = low</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px"> </p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> value = property(get_value,set_value)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> low = property(get_low,set_low)</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"> high = property(get_high,set_high)</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
And then all I have to do from the C++ UI:</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"><br></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo">
<span style="color: #448388"> Slider</span>* slider = <span style="color: #c800a7">new</span> <span style="color: #448388">Slider</span>(<span style="color: #448388">Point</span>(<span style="color: #4100e0">20</span>, <span style="color: #4100e0">30.</span>), <span style="color: #4100e0">195.</span>);</p>
<p></p></span><span class="Apple-style-span" style="font-family: Menlo; "> </span><span class="Apple-style-span" style="color: rgb(0, 0, 0); "><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco">
</p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"> slider-></span><span style="color: #448388">value</span><span style="color: #000000">.</span>bindToAttribute<span style="color: #000000">(</span><span style="color: #448388">controller</span><span style="color: #000000">-></span>getModel<span style="color: #000000">(),</span><span style="color: #dd0005">"value"</span><span style="color: #000000">);</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"> slider-></span><span style="color: #448388">low</span><span style="color: #000000">.</span>bindToAttribute<span style="color: #000000">(</span><span style="color: #448388">controller</span><span style="color: #000000">-></span>getModel<span style="color: #000000">(),</span><span style="color: #dd0005">"low"</span><span style="color: #000000">);</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"> slider-></span><span style="color: #448388">high</span><span style="color: #000000">.</span>bindToAttribute<span style="color: #000000">(</span><span style="color: #448388">controller</span><span style="color: #000000">-></span>getModel<span style="color: #000000">(),</span><span style="color: #dd0005">"high"</span><span style="color: #000000">);</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"><br></span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"><br>
</span></p><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #295a5e"><span style="color: #000000"><br></span></p><p></p></span><span class="Apple-style-span" style="font-family: arial; font-size: small; ">So this way:</span><p>
</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- the python objects work like models</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- the values are synced</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- the script writer is not able access to any other properties of the UI elements</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- however one have total control of the values</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- all the widgets can work without binded to any UI elements</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- if I want to serialize the objects (and I want to), the PyCFunctions and other - runtime added - objects can be easily excluded</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- properties can be easily bounded and unbouded</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- I did not have to create any new types, such as MySyncedFloat, MySyncedString etc.</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- the script writer doesn't even have to know about that a value will be bounded to a UI element</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- the UI elements are not strongly connected to any python code</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><font class="Apple-style-span" face="arial" size="2">- more UI elements can be bounded to a single python attribute for example I can bind an attribute to a slider's max value and to a numeric text box at the same time</font></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">- this approach can be easily used with a graphical interface builder: one just have to drag and drop some UI elements to a widget, and tell the interface builder that a property of an element will be bounded to a python attribute. Then it can be exported to an XML and loaded runtime and bind the properties runtime. Cool.</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><font class="Apple-style-span" face="arial" size="2"><br></font></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">
<span class="Apple-style-span" style="font-family: arial; font-size: small; "><br></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; ">
<span class="Apple-style-span" style="font-family: arial; font-size: small; "> This approach worked very well. But... Few days ago our UI/UX designer created some new UI elements which I call "batched controllers". A batched controller is an array of same controllers for example sliders. The number of the sliders can be changed runtime for example when I click on a button a new slider is added. And this type of view can not be used with the previous approach, since a value is determined by two values: the ordinal of the slider and the value itself. </span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; "><br></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">So my question is: does anybody have any idea how to create something that works like I previously specified for these "batched controllers" (==properties with indices)</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; "><br></span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Monaco; "><span class="Apple-style-span" style="font-family: arial; font-size: small; ">István</span></p>
<p></p><p></p><p></p><p></p><p></p><p></p></div>