I'm trying to figure out how to deal with multiple matches in my address book, say the user has two people by the name of Bob; one is Bob Lastname and the other is Bob Namelast, how would you approach dealing with telling them to specify, and then allowing them to do so and get a result. Also, what if a user just has two contacts named Bob with no last name, what would you do then? I've got a temporary system in place that checks the within a given len of the input against a given len of the keys at hand, but that has several issues as I'm sure you can imagine.

If your address book is a console application, I suggest displaying a menu to choose from like

'Bob' matches 4 contacts:

1. Bob Lastname
2. Bob Namelast
3. Bob
4. Bob

enter your choice:

oh great, I haven't even heard of the listbox until now, I'll let you know how it works out. Thanks.

oh great, I haven't even heard of the listbox until now, I'll let you know how it works out. Thanks.

Some applications let you choose a word in a dictionary. You have an entry widget where you start typing your word and a listbox-like widget which content is updated every time you type a character in the entry widget. It's very easy to use. There's something similar in GPS devices like TomTom. As I enter the name of a city, a list of cities is updated for me to choose from.

I guess I'm just not quite getting how it would update each time the user enters a character into the Entry field.

From http://stackoverflow.com/questions/4140437/python-tkinter-interactively-validating-entry-widget-content:

import Tkinter as tk

class MyApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        # valid percent substitutions (from the Tk entry man page)
        # %d = Type of action (1=insert, 0=delete, -1 for others)
        # %i = index of char string to be inserted/deleted, or -1
        # %P = value of the entry if the edit is allowed
        # %s = value of entry prior to editing
        # %S = the text string being inserted or deleted, if any
        # %v = the type of validation that is currently set
        # %V = the type of validation that triggered the callback
        #      (key, focusin, focusout, forced)
        # %W = the tk name of the widget
        vcmd = (self.register(self.OnValidate), 
                '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
        self.entry = tk.Entry(self, validate="key", 
                              validatecommand=vcmd)
        self.entry.pack()
        self.mainloop()

    def OnValidate(self, d, i, P, s, S, v, V, W):
        print("""
OnValidate:
d='%s'
i='%s'
P='%s'
s='%s'
S='%s'
v='%s'
V='%s'
W='%s'
""" % (d, i, P, s, S, v, V, W))
        # only allow if the string is lowercase, not digit
        return (S.lower() == S and not S.isdigit())

app=MyApp()

You can put search of address book after the validation. Actually validation would be to be found in db.

EDIT: made vegaseat style inherit Tk, more natural multiline print. BTW interesting new thing this register

Edited 5 Years Ago by pyTony: n/a

I guess I'm just not quite getting how it would update each time the user enters a character into the Entry field.

An exemple is perhaps the Pmw.EntryField widget with validator (see http://pmw.sourceforge.net/doc/EntryField.html). Every time the 'Odd length' entry is modified in the following example, a function is called

import time
import Tkinter as tk
import Pmw

class Demo:
    def __init__(self, parent):
        # Create and pack the EntryFields.
        self._any = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Any:',
                validate = None,
                command = self.execute)
        self._real = Pmw.EntryField(parent,
                labelpos = 'w',
                value = '55.5',
                label_text = 'Real (10.0 to 99.0):',
                validate = {'validator' : 'real',
                        'min' : 10, 'max' : 99, 'minstrict' : 0},
                modifiedcommand = self.changed)
        self._odd = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Odd length:',
                validate = self.custom_validate,
                value = 'ABC')
        self._date = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Date (in 2000):',
                value = '2000/2/29',
                validate = {'validator' : 'date',
                        'min' : '2000/1/1', 'max' : '2000/12/31',
                        'minstrict' : 0, 'maxstrict' : 0,
                        'format' : 'ymd'},
                )
        now = time.localtime(time.time())
        self._date2 = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Date (d.m.y):',
                value = '%d.%d.%d' % (now[2], now[1], now[0]),
                validate = {'validator' : 'date',
                        'format' : 'dmy', 'separator' : '.'},
                )
        self._time = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Time (24hr clock):',
                value = '8:00:00',
                validate = {'validator' : 'time',
                        'min' : '00:00:00', 'max' : '23:59:59',
                        'minstrict' : 0, 'maxstrict' : 0},
                )
        self._comma = Pmw.EntryField(parent,
                labelpos = 'w',
                label_text = 'Real (with comma):',
                value = '123,456',
                validate = {'validator' : 'real', 'separator' : ','},
                )

        entries = (self._any, self._real, self._odd, self._date, self._date2,
                self._time, self._comma)

        for entry in entries:
            entry.pack(fill='x', expand=1, padx=10, pady=5)
        Pmw.alignlabels(entries)

        self._any.component('entry').focus_set()

    def changed(self):
        print 'Text changed, value is', self._real.getvalue()

    def execute(self):
        print 'Return pressed, value is', self._any.getvalue()

    # This implements a custom validation routine.  It simply checks
    # if the string is of odd length.
    def custom_validate(self, text):
        print 'text:', text
        if len(text) % 2 == 0:
          return -1
        else:
          return 1

root = tk.Tk()
dem = Demo(root)
root.mainloop()

""" my output -->
text: ABC
text: ABCH
text: ABCHE
text: ABCHEo
text: ABCHE
text: ABCHEL
text: ABCHE
text: ABCH
text: ABC
text: AB
"""
This article has been dead for over six months. Start a new discussion instead.