tags:

views:

46

answers:

3

I'm building a small PyGTK application and I have an text input field (currently a ComboBoxEntry) which is populated with a few values that the user should be able to choose from.

I think what I want to do is to filter out the matching fields and only show those ones so the user using the keyboard arrows can choose one of the matching ones.

To give some background the predefined values are a bunch of urls and the user should be able to choose from theese or fill in a new one.

Example: the predefined urls:

When a user types 'http://www.g' The three URLs starting with that string is to be shown (in some way) and when typeing 'http://www.goog' the two starting with that is to be shown

Any Ideas?

A: 

You may want to look at how Deskbar Applet's Cuemiac does it.

Ignacio Vazquez-Abrams
A: 

Well, you obviously want to deal with prefixes so you'll probably want to use some sort of trie. Of course, there are issues to deal with. For instance, after a person has typed in a few letters ( or maybe even just one) you will want to either traverse the rest of the branches of the trie to find suggestions, or have suggestions stored in each node. A lot of these sorts of decisions depend on how many possible suggestions you plan on having.

Justin Peel
I an planning to have small amount of suggestions, max 10.
Joelbitar
if you only have 10 suggestions, then just take the entered text and compare it with the beginnings of each of your suggestions. If they match, add the suggestion to the suggestions list.
Justin Peel
+1  A: 

An Entry with an EntryCompletion seems more appropriate than a ComboBoxEntry. As always, the tutorial is a good start.

It's very easy to set up when the predefined URLs list is small and fixed. You just need to populate a ListStore:

# simplified example from the tutorial
import gtk

urls = [
    'http://www.google.com',
    'http://www.google.com/android',
    'http://www.greatstuff.com',
    'http://www.facebook.com',
    ]
liststore = gtk.ListStore(str)
for s in urls:
    liststore.append([s])

completion = gtk.EntryCompletion()
completion.set_model(liststore)
completion.set_text_column(0)

entry = gtk.Entry()
entry.set_completion(completion)

# boilerplate
window = gtk.Window()
window.add(entry)

window.connect('destroy', lambda w: gtk.main_quit())
window.show_all()
gtk.main()

Users are not likely to bother typing "http://" or even "www.", so you probably want to match any part of the URL (e.g. just "og" works!):

def match_anywhere(completion, entrystr, iter, data):
    modelstr = completion.get_model()[iter][0]
    return entrystr in modelstr
completion.set_match_func(match_anywhere, None)

This will test every value in the ListStore for a match, so it's not scalable to huge lists (I mean huge; a 1000 works fine).

Be sure to play with the various options of EntryCompletion, to configure the most pleasant behavior.

Beni Cherniavsky-Paskin