To add filtering, we need to extend the NSArrayController class. The
first step is to create a new python class,
This will extend the standard array controller with a search method.
from PyObjCTools import NibClassBuilder class ArrayControllerWithSearch(NibClassBuilder.AutoBaseClass): searchString = None def search_(self, sender): self.searchString = sender.stringValue()
This doesn’t do anything particularly interesting, except to store the search string for the other methods to use. The AutoBaseClass means that the class we are going to derive from will be specified in Interface Builder and then allocated dynamically.
The next step is to over-ride the method that actually lists the objects
in the array,
arrangeObjects_. (recalling that the underscore is
required for when Objective C wants a ‘:’).
def arrangeObjects_(self, objects): # retrieve a reference to the same method in the base class supermethod = super(ArrayControllerWithSearch, self).arrangeObjects_ if self.searchString is None or self.searchString == '': return supermethod(objects) return supermethod(list(filterObjects(objects, self.searchString)))
supermethod variable is actually a function pointer to the
arrangeObjects_ method on the super class. This gets used under either
case, so it is easier to have the code to access this in one place.
filterObjects will be defined next. The search is going to be rather
simplistic in that it will check if the search string is contained
within the name of the person.
def filterObjects(objs, searchString): lowerSearch = searchString.lower() for obj in objs: if(lowerSearch in obj['name'].lower()): yield obj continue
Also, add an import statement for the class in the main application (main.py):
from PyObjCTools import AppHelper import DateListDelegate import ArrayControllerWithSearch AppHelper.runEventLoop(argv=)
In Interface Builder, subclass NSArrayController in the Classes tab, and
call the sub class the same name as your custom controller
(ArrayControllerWithSearch). In the Attributes section of the Inspector
(with the Classes tab still selected), add a new Action, called
From the Instances tab, select the NSArrayController for the list of names. In the Inspector, select Custom Class, and then select the new controller class:
Add a search control to the form. This will call the search_ method added to the controller.
Now, Ctrl-drag from the search control to the array controller in the
Instances tab. This creates a connection. Select the
and then press the Connect button.
Congratulations! You now have a searchable list of birthdays for all your friends and family, integrated into your Address Book.
The complete example is available here and includes a working application bundle in dist/.