Navigation

ManualBindings

A simple example that illustrates establishing bindings programmatically,
including a number of options such as validation and an array operator, and
indexed accessor methods. A custom model object implements custom validation
method.

Originally from “Cocoa Bindings Examples and Hints”, converted to PyObjC by
u.fiedler.

Sources

AppController.py

## AppController.py# ManualBindings#importobjcfromCocoaimportNSObject,NSValidatesImmediatelyBindingOptionfromCocoaimportNSError,NSLocalizedDescriptionKey,NSDecimalclassAppController(NSObject):arrayController=objc.IBOutlet()selectedNameField=objc.IBOutlet()selectedPriceField=objc.IBOutlet()tableView=objc.IBOutlet()totalCountField=objc.IBOutlet()defawakeFromNib(self):self.totalCountField.bind_toObject_withKeyPath_options_("value",self.arrayController,"arrangedObjects.@sum.price",None)bindingOptions={}bindingOptions['NSNullPlaceholder']="No Name"self.selectedNameField.bind_toObject_withKeyPath_options_("value",self.arrayController,"selection.name",bindingOptions)# binding for "name" columntableColumn=self.tableView.tableColumnWithIdentifier_('name')tableColumn.bind_toObject_withKeyPath_options_("value",self.arrayController,"arrangedObjects.name",bindingOptions)# binding options for "price"delbindingOptions['NSNullPlaceholder']bindingOptions[NSValidatesImmediatelyBindingOption]=True# binding for selected "price" fieldself.selectedPriceField.bind_toObject_withKeyPath_options_("value",self.arrayController,"selection.price",bindingOptions)#binding for "price" columntableColumn=self.tableView.tableColumnWithIdentifier_('price')tableColumn.bind_toObject_withKeyPath_options_("value",self.arrayController,"arrangedObjects.price",bindingOptions)# bind array controller to self's itemsArray# we use _k_itemsArray because Python does not have a separate# namespace for instance variables, and we are using accessors.self._k_itemsArray=[]self.arrayController.bind_toObject_withKeyPath_options_("contentArray",self,"self.itemsArray",None)@objc.accessordefcountOfItemsArray(self):returnlen(self._k_itemsArray)@objc.accessordefobjectInItemsArrayAtIndex_(self,index):returnself._k_itemsArray[index]@objc.accessordefinsertObject_inItemsArrayAtIndex_(self,obj,idx):self._k_itemsArray.insert(idx,obj)@objc.accessordefremoveObjectFromItemsArrayAtIndex_(self,idx):delself._k_itemsArray[idx]@objc.accessordefreplaceObjectInItemsArrayAtIndex_withObject_(self,idx,obj):self._k_itemsArray[idx]=objITEM_ERROR_DOMAIN='ITEM_ERROR_DOMAIN'ITEM_NEGATIVE_PRICE=10001classItem(NSObject):defprice(self):returngetattr(self,'_k_price',NSDecimal("0.00"))defsetPrice_(self,aPrice):self._k_price=aPricedefname(self):returngetattr(self,'_k_name',None)defsetName_(self,aName):self._k_name=aName@objc.accessordefvalidatePrice_error_(self,value,error):ifvalue>=0:returnTrue,value,NoneerrorString='Price cannot be negative'userInfoDict={NSLocalizedDescriptionKey:errorString}error=NSError.alloc().initWithDomain_code_userInfo_(ITEM_ERROR_DOMAIN,ITEM_NEGATIVE_PRICE,userInfoDict)returnFalse,value,error

ManualBindings.py

setup.py

"""Script for building the example:Usage: python3 setup.py py2app"""fromsetuptoolsimportsetupsetup(name="ManualBindings",app=["ManualBindings.py"],data_files=["English.lproj"],setup_requires=["py2app","pyobjc-framework-Cocoa",])