Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entry with suggestions

Tags:

python

pygtk

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:

  • http://www.google.com
  • http://www.google.com/android
  • http://www.greatstuff.com
  • http://www.facebook.com

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?

like image 645
Joelbitar Avatar asked Feb 12 '10 08:02

Joelbitar


People also ask

How do you show the suggestion list in the input field?

Approach: Create a div with the class as a container. Inside of this div, create another div with a class as a text-container that will contain the <input> tag & <datalist> tag. Declare the list attribute as programmingLanguages inside the <input> tag.


1 Answers

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.

like image 83
Beni Cherniavsky-Paskin Avatar answered Sep 28 '22 07:09

Beni Cherniavsky-Paskin