Python GUI 027 – Wordlist Updater, button_utils.py changes

As shown in part 26, there are two new entry boxes from button_utils.py: WordListBox and YesNoNGrams.


(Word selector box)

"""
The idea here is that we start out with a long list of words from the CON solutions, then weed out the ones already in the existing wordlist file. The remaining words will be composed of stuff I don't want to keep (uncommon author names, garbage keywords and extremely rare words) plus the words I do want added to the wordlist file. I've found it's easier to select the unwanted words and then remove them, than it is to select the wanted words. After the unwanted ones are removed, click "All" to select everything left, and Finish to close the window and return the selection to the calling method.
"""

class WordListBox(simpledialog.Dialog):
... def __init__(self, master, *args, **kwargs):

# recordset contains the list object to display.
# lheight and lwidth set the window dimensions.

....... self.recordset = kwargs.pop("recordset")
....... self.lheight = kwargs.pop("lheight")
....... self.lwidth = kwargs.pop("lwidth")

# Track when the user clicks All.

....... self.togglestate = 0

# Open our simpledialog window

....... simpledialog.Dialog.__init__(
........... self, master, title=kwargs.pop("wtitle",
........... "default title"), *args, **kwargs)

# Define the widgets in the window

... def body(self, master):

....... self.listbox = tk.Listbox(master,
........... height=self.lheight, width=self.lwidth,
........... selectmode=tk.MULTIPLE)
....... self.listbox.grid(row=0, columnspan=3)

....... self.scrollbar = ttk.Scrollbar(
........... master, orient = tk.VERTICAL)
....... self.scrollbar.grid(row=0, column=3, sticky=tk.NS)

# Load the listbox with our selectable items

....... for rec in self.recordset:
........... self.listbox.insert(tk.END, rec)

....... self.listbox['yscrollcommand'] = self.scrollbar.set
....... self.scrollbar['command'] = self.listbox.yview

# Set up the All, Remove and Finished buttons

....... self.btn_all = ttk.Button(
........... master, text="All", command=lambda:
............self._button_toggleall(master)
....... ).grid(row=1, column=0, padx=10, pady=10)

....... self.btn_remove = ttk.Button(
........... master, text="Remove", command=lambda:
............self._button_remove(master)
....... ).grid(row=1, column=2, padx=10, pady=10)

....... self.btn_finished = ttk.Button(
........... master, text="Finished", command=lambda:
........... self._button_finished()
....... ).grid(row=1, column=3, padx=10, pady=10)

# If All is clicked, toggle the select states of
# the items in the listbox.

... def _button_toggleall(self, master):
....... if self.togglestate:
........... self.togglestate = 0
........... self.listbox.selection_clear(0, tk.END)
....... else:
........... self.togglestate = 1
........... self.listbox.selection_set(0, tk.END)

# If Remove is clicked, delete the selected
# items from the listbox. Work backwards to
# avoid confusion from deleting a record then
# trying to locate the next one to delete.

... def _button_remove(self, master):
....... self.togglestate = 0
....... for r in self.listbox.curselection()[::-1]:
........... self.listbox.delete(r)

# If Finished is selected, trigger the process to
# close the window.

... def _button_finished(self):
....... self.ok()

# Automatically validate the data.

def validate(self):
return 1 # Always validate as True

# Go through all of the selected item line numbers and
# return the values of each line item.

... def apply(self):
....... ret = []
....... for r in self.listbox.curselection():
........... ret.append(self.listbox.get(r))
....... self.result = ret

# Deactivate the default window buttons.

... def buttonbox(self):
....... pass


(Wordlist stats and ngram settings box)

"""
Show the results of updating the wordlist file, then ask the user if they want to update the ngrams file for that language.

Normally, we'd just save the 2-, 3- and 4-gram data, but give the user the option to save the higher-number n-grams.

Also, there's little point to having more than 50 of each n-gram set, since a small increase in "n-gram count accuracy" comes with a bigger increase in program run times. But, there may be cases where having 600 or more entries in the sets could be useful. Let the user specify the desired numbers of n-grams if so desired.
"""

class YesNoNGrams(simpledialog.Dialog):
... def __init__(self, master, *args, **kwargs):

# Initialize the message label elements.

....... self.label_var = tk.StringVar()
....... self.label_var.set(kwargs.pop("msg", "default msg"))

# Initialize the integer entry box variables.

....... self.button_var = tk.IntVar()
....... self.ngram_max = tk.IntVar()
....... self.elements = tk.IntVar()

# Initialize the yes/no buttons setting, and entry box
# data values from the calling parameters.

....... self.button_var.set(0)
....... self.ngram_max.set(kwargs.pop("ngram_max"))
....... self.elements.set(kwargs.pop("elements"))

....... simpledialog.Dialog.__init__(
........... self, master, title=kwargs.pop("wtitle",
..............."default title"), *args, **kwargs)

# Set up the window itself.

... def body(self, master):
....... self.geometry('350x200')

# Set up the labels.

....... ttk.Label(master, textvariable=self.label_var).
........... grid(row=0, columnspan=3)
....... ttk.Label(master, text='Max n-grams: ').
........... grid(row=1, column=0)
....... ttk.Label(master, text='Max elements:').
........... grid(row=2, column=0)

# Set up the entry box widgets

....... self.elem_ngram = ttk.Entry(master, width=5,
........... textvariable=self.ngram_max).grid(column = 2,
............... row = 1, sticky=tk.W, padx=5, pady=5)

....... self.elem_entry = ttk.Entry(master, width=5,
........... textvariable=self.elements).grid(column = 2,
............... row = 2, sticky=tk.W, padx=5, pady=5)

# Set up the Yes and No buttons.

....... self.btn_yes = ttk.Button(
........... master, text="Yes", command=lambda:
........... self._buttons(master, 1)
....... ).grid(row=3, column=0, pady=10)

....... self.btn_no = ttk.Button(
........... master, text="No", command=lambda:
........... self._buttons(master, 0)
....... ).grid(row=3, column=2, pady=10)

# When either the Yes or No button is clicked, set
# button_var to val and start the process to close
# the window.

... def _buttons(self, master, val):
....... self.button_var.set(val)
....... self.ok() # Close the window.

# Default the validation process.

... def validate(self):
....... return 1 # Always valid

# Return the user's selections and close the window.

... def apply(self):
....... self.result = (self.button_var.get(),
........... self.ngram_max.get(), self.elements.get())

# Suppress the default buttons.

def buttonbox(self):
pass

Next up: cons_parser_update_wordlists.py.

Published by The Chief

Who wants to know?

Leave a comment

Design a site like this with WordPress.com
Get started