In the previous series of articles, we’ve covered getting started, basic Address Book usage, and making an app bundle. This time, we’ll look at adding in some basic filtering to the list of dates.
To add filtering, we need to extend the NSArrayController class. The
first step is to create a new python class, ArrayControllerWithSearch
.
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)))
The 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
search:
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 search:
action
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/.