Skip to content

Instantly share code, notes, and snippets.

@jasonm23
Last active July 5, 2023 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonm23/88f11ea51c48d0ab2cf70ce31a42bede to your computer and use it in GitHub Desktop.
Save jasonm23/88f11ea51c48d0ab2cf70ce31a42bede to your computer and use it in GitHub Desktop.
A simple autocomplete GUI in TKinter, Suggestions read from stdin or an input file. Title can also be set. Python 3.11 + tkinter required.
import tkinter as tk
from tkinter import END
import os
import sys
import re
import argparse
# --- Event Handler functions
def select_handler(w):
widget = w.widget
index = int(widget.curselection()[0])
value = widget.get(index)
text_entry_str.set(value)
suggestion_list.delete(0, END)
text_entry.focus()
def down_handler(w):
suggestion_list.focus()
suggestion_list.selection_set(0)
def complete_handler(w):
print(text_entry.get())
exit(0)
def get_data(*args):
search_str = text_entry.get()
suggestion_list.delete(0, END)
for element in suggestions:
if (re.match(f".*{search_str}", element, re.IGNORECASE)):
suggestion_list.insert(tk.END, element)
def focus_text(*args):
text_entry.focus()
# --- Command line parser
parser = argparse.ArgumentParser(
prog="autocomplete_gui",
description="Provide a autocomplete selection GUI for a script.",
epilog="Suggestions are read as lines from stdin or input file."
)
parser.add_argument('-i', '--input', help="Suggestions file", type=str)
parser.add_argument('-t', '--title', help="Window title", type=str)
args = parser.parse_args()
if args.input:
print(f"input provided: {args.input}")
if os.path.exists(args.input):
with open('file.txt', 'r') as file:
# Read all lines from the file into an array
suggestions = file.readlines()
else:
print(f"{args.input} does not exist")
exit(1)
else:
print("reading stdin")
suggestions = []
try:
while True:
line = input()
suggestions.append(line)
except EOFError:
pass
if len(suggestions) == 0:
print("no data on stdin")
exit(1)
# --- Set title
if args.title:
title = args.title
else:
title = "Autocomplete"
# --- Default config
title_font = ( 'Helvetica Neue',16,"normal" )
text_width = 70
suggestion_rows = 48
# --- Assemble GUI
root = tk.Tk()
root.geometry("595x370")
root.title(title)
root.grid_columnconfigure(0, weight=1)
# --- Text input
text_entry_str = tk.StringVar()
text_entry = tk.Entry(
root,
textvariable=text_entry_str,
font=title_font,
width=text_width
)
text_entry.pack(
expand=True,
fill='x',
side='top',
padx=10,
pady=0
)
text_entry.bind('<Down>', down_handler)
text_entry.bind('<Return>', complete_handler)
text_entry_str.trace('w', get_data)
# --- Autocomplete Suggestions
suggestion_list = tk.Listbox(
root,
height=suggestion_rows,
width=text_width,
font=title_font
)
suggestion_list.pack(
expand=True,
fill=tk.BOTH,
side='bottom',
padx=10,
pady=0
)
suggestion_list.bind('<Right>', select_handler)
suggestion_list.bind('<Return>', select_handler)
suggestion_list.bind('<Escape>', focus_text)
# --- Start up
text_entry.focus()
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment