An important detail of the ContactList class is that it exposes the possibility to attach a callback to the double-click event. It also passes the clicked index as an argument to this function. We do this because we want to hide the implementation details of the underlying Listbox:
def bind_doble_click(self, callback):
handler = lambda _: callback(self.lb.curselection()[0])
self.lb.bind("<Double-Button-1>", handler)
ContactForm also offers an abstraction to instantiate a new contact from the values input in the entries:
def get_details(self):
values = [e.get() for e in self.entries]
try:
return Contact(*values)
except ValueError as e:
mb.showerror("Validation error", str(e), parent=self)
Since we included field validations in our Contact class, instantiating a new contact might raise a ValueError if an entry contains an invalid value. To notify the user of this, we show an error dialog with the error message.