Text autocompletion provides relevant real-time results to users.
Because tkinter does not provide a widget for adding autocompletion to GUIs out of the box,
I decided to make one myself. This utility is compatible with and has been tested on Python 2.7.1 and Python 3.6.0.
References:
NOTE: The Tkinter library for Python 2 and tkinter library for Python 3 will from now on be referred to as tk.
The AutocompleteEntry class (which can be found here)
derives from tk.Frame and is a container used to group a tk.Entry and tk.Listbox widget. Should you need to modify the widgets,
they can be accessed as (respectively) AutocompleteEntry s entry and listbox attributes.
The entry widget acts like a normal textbox. When activated, it binds <KeyRelease> to a private method which will update
the list of suggestions. The listbox widget contains the suggestions themselves. When activated, it binds <<ListboxSelect>> to a
private method which sets the entry widget to whatever value was selected.
Since an instance of AutocompleteEntry is a tk.Frame instance too, you can place it by calling its pack or grid methods with
their respective arguments.
NOTE: These examples will only run under Python 3. To make them Python 2-compatible, replace tkinter with Tkinter.
To add a new autocompletion frame to our interface, first initialize one:
import tkinter as tk
from main import AutocompleteEntry
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
entry = AutocompleteEntry(frame)
# You can pass additional parameters to further customize the window;
# all parameters that you can pass to tk.Frame, are valid here too.Now you need to configure the instance by passing it an iterable containing all autocompletion entries.
Do this by calling its build method:
ENTRIES = (
"Foo",
"Bar"
)
entry.build(ENTRIES)You can pass additional arguments to build:
-
max_entries(integer):
The maximum number of entries to display at once. This value directly corresponds to the listbox widget'sheightattribute. Defaults to5. -
case_sensitive(boolean):
IfTrue, only autocomplete entries that enforce the same capitalization as the current entry will be displayed.
IfFalse, all autocomplete entries that match with the current entry will be displayed.
Defaults toFalse. -
no_results_message(string orNone):
The message to display if no suggestions could be found for the current entry.
This argument may include a formatting identifier ({}) which, at runtime, gets formatted as the current entry. IfNoneis specified, the listbox will instead be hidden until the next<KeyRelease>event.
Let's play around with these arguments:
entry.build(
entries=ENTRIES,
no_results_message="< No results found for '{}' >"
# Note that this is formatted at runtime
)NOTE: You may call the build method multiple times on an instance of AutocompleteEntry, to dynamically change the available suggestions.
With that out of the way, you can display entry:
entry.pack()Now, each time a user presses a key while the entry widget has focus, a list of suggestions will display below it.
By default, the tk.Listbox widget has a width of 25 pixels and a height of 5 (items). The tk.Entry widget also has a default width of 25 pixels. These settings can be modified through the following class attributes:
-
AutocompleteEntry.LISTBOX_HEIGHT: The height to specify when creating thetk.Listboxwidget. There's no need to modify this, since the maximum number of entries to be displayed can be passed as an argument tobuild. -
AutocompleteEntry.LISTBOX_WIDTH: The width to specify when creating thetk.Listboxwidget. Any positive integer is valid. -
AutocompleteEntry.ENTRY_WIDTH: The width to specify when creating thetk.Entrywidget. Any positive integer is valid.
You can retrieve the current entry by accessing the instance's text attribute (which is a tk.StringVar instance):
text = entry.text.get()To further customize the entry widget, you may set its font options, for example:
entry.entry["font"] = (<FONT NAME>, <FONT SIZE>, <FONT WEIGHT>)Or to change the background color for the listbox widget:
entry.listbox["background"] = "#cfeff9"
# Light blueFor a demonstration of this utility, check out the demo.