Posts: 12
Threads: 3
Joined: Jul 2017
(Sep-20-2017, 09:08 PM)Larz60+ Wrote: please PM very sparingly.
It's OK to share with the forum.
As to your questions:
Thanks!
Posts: 12,024
Threads: 484
Joined: Sep 2016
Sep-22-2017, 07:18 AM
(This post was last modified: Sep-22-2017, 07:18 AM by Larz60+.)
OK, It now deletes, and I cleaned up a few things.
From here on, you're on your own.
Enjoy:
import tkinter as tk
import os
import json
import tkinter.ttk as ttk
import tkinter.messagebox as tm
class ShoeBot:
def __init__(self, parent, filename):
self.roots = parent
self.roots.title('AWD ShoeBot')
# self.roots.geometry('400x200+10+10')
self.treeheight = 19
self.filename = os.path.abspath(filename)
self.fp = None
self.people = {}
if os.path.isfile(self.filename):
self.load_data()
self.changes_made = False
self.this_person = None
self.name = tk.StringVar()
self.shoe_size = tk.StringVar()
self.build_gui()
self.load_tree()
def build_gui(self):
self.create_main_frame()
self.create_left_frame()
self.create_right_frame()
self.create_bottom_frame()
self.create_tree()
self.create_user_dialog()
self.create_statusbar()
self.roots.protocol("WM_DELETE_WINDOW", self.on_delete)
def create_main_frame(self):
self.main_frame = tk.Frame(self.roots, relief=tk.RAISED)
self.main_frame.grid(row=0, column=0, sticky='nsew')
self.main_frame.columnconfigure(0, weight=1)
self.main_frame.rowconfigure(0, weight=1)
self.main_frame.pack(pady=5, padx=5)
def create_left_frame(self):
self.left_frame = tk.Frame(self.main_frame, relief=tk.SUNKEN)
self.left_frame.grid(row=0, rowspan=self.treeheight, column=0, columnspan=2, sticky='ns')
def create_right_frame(self):
self.right_frame = tk.Frame(self.main_frame, relief=tk.SUNKEN)
self.right_frame.grid(row=0, rowspan=self.treeheight, column=2, columnspan=10, sticky='ns')
def create_bottom_frame(self):
self.bottom_frame = tk.Frame(self.main_frame, relief=tk.SUNKEN)
self.bottom_frame.grid(row=self.treeheight + 1, column=0, columnspan=11, sticky='ew')
def create_tree(self):
treestyle = ttk.Style()
treestyle.configure('Treeview.Heading', foreground='white',
borderwidth=2, background='SteelBlue',
rowheight=self.treeheight,
height=3)
self.tree = ttk.Treeview(self.left_frame,
height=self.treeheight,
padding=(2, 2, 2, 2),
columns='Name',
selectmode="extended")
self.tree.column('#0', stretch=tk.YES, width=180)
self.tree.tag_configure('monospace', font='courier')
treescrolly = tk.Scrollbar(self.left_frame, orient=tk.VERTICAL,
command=self.tree.yview)
treescrolly.grid(row=0, rowspan=self.treeheight, column=1, sticky='ns')
treescrollx = tk.Scrollbar(self.left_frame, orient=tk.HORIZONTAL,
command=self.tree.xview)
treescrollx.grid(row=self.treeheight + 1, column=0, columnspan=2, sticky='ew')
self.tree.configure(yscroll=treescrolly)
self.tree.configure(xscroll=treescrollx)
self.tree.grid(row=0, rowspan=self.treeheight, column=0, sticky='nsew')
self.tree.bind('<Double-1>', self.name_selected)
def clear_entry(self):
self.nameE.delete(0, 'end')
self.shoeSizeE.delete(0, 'end')
def clear_tree(self):
all_children = self.tree.get_children()
for item in all_children:
self.tree.delete(item)
def load_tree(self):
self.clear_tree()
keys = list(self.people.keys())
keys.sort()
for key in keys:
self.tree.insert('', 'end', text='{}'.format(key))
def create_user_dialog(self):
self.intruction = tk.Label(self.right_frame, text='Enter Information Below\n')
self.intruction.grid(row=0, column=0, sticky='nse')
self.nameL = tk.Label(self.right_frame, text='Name: ')
self.shoeSizeL = tk.Label(self.right_frame, text='Shoe Size: ')
self.nameL.grid(row=1, column=0, sticky='w')
self.shoeSizeL.grid(row=2, column=0, sticky='w')
self.nameE = tk.Entry(self.right_frame, textvariable=self.name)
self.shoeSizeE = tk.Entry(self.right_frame, textvariable=self.shoe_size)
self.nameE.grid(row=1, column=1)
self.shoeSizeE.grid(row=2, column=1)
signupButton = tk.Button(self.right_frame, text='Create', command=self.add_person)
signupButton.grid(row=4, column=0, sticky='w')
removeButton = tk.Button(self.right_frame, text='Delete', command=self.remove_person)
removeButton.grid(row=4, column=1, sticky='w')
self.spacer = tk.Label(self.right_frame, bd=0)
self.spacer.grid(row=5, column=0)
def create_statusbar(self):
self.sb = tk.Frame(self.bottom_frame)
self.sb.grid(row=0, column=0, sticky='nsew')
def on_delete(self):
if self.changes_made:
self.save_data()
self.roots.destroy()
def load_data(self):
with open(self.filename) as fp:
self.people = json.load(fp)
def save_data(self):
with open(self.filename, 'w') as fo:
json.dump(self.people, fo)
def add_person(self):
name = self.name.get()
shoesize = self.shoe_size.get()
if len(name) == 0 or len(shoesize) == 0:
tm.showerror('Add Person', 'Missing data')
else:
self.people[name] = {'shoesize': shoesize}
self.tree.insert('', 'end', text='{}'.format(name))
self.changes_made = True
self.clear_entry()
msg = 'Added {}'.format(name)
def remove_person(self):
name = self.name.get()
if len(name) == 0:
tm.showerror('Remove Person', 'No Name')
else:
del self.people[name]
print(f'People: {self.people}')
self.changes_made = True
self.load_tree()
self.clear_entry()
def name_selected(self, event):
curitem = self.tree.focus()
nidx = self.tree.item(curitem)
name = nidx['text']
shoesize = self.people[name]['shoesize']
print('You selected {} who wears size {} shoe'.format(name, shoesize))
# do stuff with selected person
def find_person(self):
try:
person = self.name.get()
self.this_person = self.people[person]
print('found {} shoesize: {}'.format(self.this_person[name], self.this_person[name]['shoesize']))
except:
'Adding {} shoesize: {}'.format(self.name.get(), self.shoe_size.get())
self.add_person()
self.this_person = self.people[person]
self.name.set('')
self.shoe_size.set('')
return self.this_person
def main():
root = tk.Tk()
sb = ShoeBot(root, filename='PeopleFile.json')
root.mainloop()
if __name__ == '__main__':
main()
Posts: 12,024
Threads: 484
Joined: Sep 2016
I haven't forgot about this, almost there.
Probably not today though.
Posts: 12,024
Threads: 484
Joined: Sep 2016
still a few issues to be resolved... soon
Posts: 12,024
Threads: 484
Joined: Sep 2016
Sep-30-2017, 07:52 PM
(This post was last modified: Sep-30-2017, 07:52 PM by Larz60+.)
Well, this has been quite an undertaking:
I said I would post last night, but there was too many loose ends.
There are still several methods here that don't work correctly and
it may take a while longer to complete.
Right now, about the only thing that seems to be solid is the add function
deletes are almost working, but not there yet.
I thought I'd post anyway so that you can start to get an idea of what's what.
As I stated before, the self.people dictionary will need to be replaced by a relational
database, suggest sqlite3. This will eliminate the json file. As is, so long as you have a reasonable
amount of memory it will hold quite a few people, before memory runs out.
the first module must be named 'MakeStateFile.py' as it is imported by the main script
import json
import os
class MakeStateFiles:
def __init__(self):
self.states = {
'USA': {
'Alabama': 'AL',
'Alaska': 'AK',
'Arizona': 'AZ',
'Arkansas': 'AR',
'California': 'CA',
'Colorado': 'CO',
'Connecticut': 'CT',
'Delaware': 'DE',
'District of Columbia': 'DC',
'Florida': 'FL',
'Georgia': 'GA',
'Hawaii': 'HI',
'Idaho': 'ID',
'Illinois': 'IL',
'Indiana': 'IN',
'Iowa': 'IA',
'Kentucky': 'KY',
'Kansas': 'KS',
'Louisiana': 'LA',
'Maine': 'ME',
'Maryland': 'MD',
'Massachusetts': 'MA',
'Michigan': 'MI',
'Mississippi': 'MS',
'Missouri': 'MO',
'Montana': 'MT',
'Nebraska': 'NE',
'Nevada': 'NV',
'New Hampshire': 'NH',
'New Jersey': 'NJ',
'New Mexico': 'NM',
'New York': 'NY',
'North Carolina': 'NC',
'North Dakota': 'ND',
'Ohio': 'OH',
'Oklahoma': 'OK',
'Oregon': 'OR',
'Pennsylvania': 'PA',
'Rhode Island': 'RI',
'South Carolina': 'SC',
'South Dakota': 'SD',
'Tennessee': 'TN',
'Texas': 'TX',
'Utah': 'UT',
'Vermont': 'VT',
'Virginia': 'VA',
'Washington': 'WA',
'West Virginia': 'WV',
'Wisconsin': 'WI',
'Wyoming': 'WY'
},
'Canada': {
'Alberta': 'AB',
'British Columbia': 'BC',
'Manitoba': 'MB',
'New Brunswick': 'NB',
'Newfoundland': 'NF',
'Northwest Territory': 'NT',
'Nova Scotia': 'NS',
'Nunavut': 'NU',
'Ontario': 'ON',
'Prince Edward Island': 'PE',
'Quebec': 'QC',
'Saskatchewan': 'SK',
'Yukon Territory': 'YT'
},
'Mexico': {
'Aguascalientes': 'AG',
'Baja California': 'BJ',
'Baja California Sur': 'BS',
'Campeche': 'CP',
'Chiapas': 'CH',
'Chihuahua': 'CI',
'Coahuila': 'CU',
'Colima': 'CL',
'Distrito Federal': 'DF',
'Durango': 'DG',
'Guanajuato': 'GJ',
'Guerrero': 'GR',
'Hidalgo': 'HG',
'Jalisco': 'JA',
'Mexico': 'EM',
'Michoacan': 'MH',
'Morelos': 'MR',
'Nayarit': 'NA',
'Nuevo': 'Leon NL',
'Oaxaca': 'OA',
'Puebla': 'PU',
'Queretaro': 'QA',
'Quintana': 'Roo QR',
'San Luis Potosi': 'SL',
'Sinaloa': 'SI',
'Sonora': 'SO',
'Tabasco': 'TA',
'Tamaulipas': 'TM',
'Tlaxcala': 'TL',
'Veracruz': 'VZ',
'Yucatan': 'YC',
'Zacatecas': 'ZT',
}
}
self.stup = ('USA','Alabama','Alaska','Arizona','Arkansas','California','Colorado',
'Connecticut','Delaware','District of Columbia', 'Florida','Georgia','Hawaii',
'Idaho','Illinois','Indiana','Iowa','Kentucky','Kansas','Louisiana','Maine',
'Maryland','Massachusetts','Michigan','Mississippi','Missouri','Montana',
'Nebraska','Nevada','New Hampshire','New Jersey','New Mexico','New York',
'North Carolina','North Dakota','Ohio','Oklahoma','Oregon','Pennsylvania',
'Rhode Island','South Carolina','South Dakota','Tennessee','Texas','Utah',
'Vermont','Virginia','Washington','West Virginia','Wisconsin','Wyoming',
' ','Canada', ' ', 'Alberta','British Columbia','Manitoba','New Brunswick',
'Newfoundland','Northwest Territory','Nova Scotia','Nunavut','Ontario',
'Prince Edward Island','Quebec','Saskatchewan','Yukon Territory',' ','Mexico',
' ','Aguascalientes','Baja California', 'Baja California Sur','Campeche',
'Chiapas','Chihuahua','Coahuila','Colima','Distrito Federal', 'Durango',
'Guanajuato','Guerrero','Hidalgo','Jalisco', 'Mexico',' ', 'Michoacan',
'Morelos','Nayarit','Nuevo','Oaxaca','Puebla','Queretaro','Quintana',
'San Luis Potosi','Sinaloa','Sonora', 'Tabasco','Tamaulipas','Tlaxcala',
'Veracruz','Yucatan','Zacatecas')
datapath = os.path.abspath('.')
datapath = '{}\data'.format(datapath)
if not os.path.exists(datapath):
os.makedirs(datapath)
with open('data/States.json', 'w') as state_file:
json.dump(self.states, state_file)
with open('data/StateTuples.json', 'w') as state_tuples:
json.dump(self.stup, state_tuples)
if __name__ == '__main__':
MakeStateFiles()
state_dict = {}
with open('data/States.json', 'r') as f:
state_dict = json.load(f)
# Test dictionary
for key, value in state_dict.items():
for state_name, state_abbr in value.items():
print(f'country: {key}, state_abbr: {state_abbr} state_name: {state_name}') the main program can be named whatever you like:
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.messagebox as tm
import MakeStateFile as msf
import os
import json
import re
class ShoeBot:
def __init__(self, parent):
self.parent = parent
self.parent.title('AWD ShoeBot')
datapath = os.path.abspath('.')
datapath = '{}\data'.format(datapath)
if not os.path.exists(datapath):
msf.MakeStateFiles()
self.tree_rows = 18
self.left_bottom = self.tree_rows + 2
self.dup_tree_rows = 10
self.textbox_rows = 14
self.treestyle = ttk.Style()
self.treestyle.configure('Treeview',
foreground='white',
borderwidth=2,
background='SteelBlue',
rowheight=self.tree_rows,
height=self.tree_rows)
self.filename = os.path.abspath('data/PeopleFile.json')
self.fp = None
self.people = None
self.person_found = None
if os.path.isfile(self.filename):
with open(self.filename) as people_file:
self.people = json.load(people_file)
else:
self.people = {}
self.changes_made = False
self.this_person = None
with open('data/StateTuples.json') as state_tuples_file:
self.states = json.load(state_tuples_file)
print(f'self.states: {self.states}')
with open('data/States.json') as state_dict_file:
self.state_dict = json.load(state_dict_file)
print(f'self.state_dict: {self.state_dict}')
self.selected_person = None
self.last_name = tk.StringVar()
self.first_name = tk.StringVar()
self.address1 = tk.StringVar()
self.address2 = tk.StringVar()
self.city = tk.StringVar()
self.state_name = tk.StringVar()
self.state_abbr = tk.StringVar()
self.country = tk.StringVar()
self.zipcode = tk.StringVar()
self.shoe_size = tk.StringVar()
self.this_item = None
self.build_gui()
self.load_tree()
def build_gui(self):
self.create_main_frame()
self.create_left_frame()
self.create_right_frame()
self.create_bottom_frame()
self.create_tree()
self.create_textbox()
self.create_user_dialog()
self.create_statusbar()
self.parent.protocol("WM_DELETE_WINDOW", self.on_delete)
def create_main_frame(self):
self.main_frame = tk.Frame(self.parent, bd=2, padx=4, pady=4, relief=tk.RAISED)
self.main_frame.grid(row=0, column=0, sticky='nseww')
self.main_frame.columnconfigure(0, weight=1)
self.main_frame.rowconfigure(0, weight=1)
self.main_frame.pack(pady=5, padx=5)
def create_left_frame(self):
self.left_frame = tk.Frame(self.main_frame, bd=2, padx=4, pady=4, relief=tk.SUNKEN)
self.left_frame.grid(row=0, rowspan=self.tree_rows, column=0, columnspan=2, sticky='ns')
def create_right_frame(self):
self.right_frame = tk.Frame(self.main_frame, bd=2, padx=4, pady=4, relief=tk.SUNKEN)
self.right_frame.grid(row=0, rowspan=self.tree_rows, column=2, columnspan=10, sticky='ns')
def create_bottom_frame(self):
self.bottom_frame = tk.Frame(self.main_frame, bd=2, padx=4, pady=4, relief=tk.SUNKEN)
self.bottom_frame.grid(row=self.tree_rows + 1, column=0, columnspan=11, sticky='ew')
def create_tree(self):
self.tree = ttk.Treeview(self.left_frame,
height=self.tree_rows,
padding=(2, 2, 2, 2),
columns=1,
selectmode="extended",
style='Treeview')
self.tree.heading('#0', text='Person, Name, address', anchor='w')
self.tree.column('#0', stretch=tk.NO, width=400)
self.tree.tag_configure('monospace', font='courier')
treescrolly = tk.Scrollbar(self.left_frame, orient=tk.VERTICAL,
command=self.tree.yview)
treescrollx = tk.Scrollbar(self.left_frame, orient=tk.HORIZONTAL,
command=self.tree.xview)
self.tree.grid(row=0, rowspan=self.tree_rows, column=0, sticky='nsew')
treescrolly.grid(row=0, rowspan=self.tree_rows, column=1, sticky='ns')
treescrollx.grid(row=self.tree_rows + 1, column=0, columnspan=2, sticky='ew')
self.tree.configure(yscroll=treescrolly)
self.tree.configure(xscroll=treescrollx)
self.tree.bind('<Double-1>', self.name_selected)
def create_textbox(self):
self.textbox = tk.Text(self.left_frame, bd=2, bg='#CEF6EC', relief=tk.RAISED, width=20, height=self.textbox_rows)
txscrolly = tk.Scrollbar(self.left_frame, orient=tk.VERTICAL, command=self.textbox.yview)
txscrollx = tk.Scrollbar(self.left_frame, orient=tk.HORIZONTAL, command=self.textbox.xview)
txscrollx.config(command=self.textbox.xview)
txscrolly.config(command=self.textbox.yview)
self.textbox.grid(row=self.left_bottom, rowspan=self.textbox_rows, column=0,
padx=2, pady=2, sticky='nsew')
txscrolly.grid(row=self.left_bottom, rowspan=self.textbox_rows, column=1, sticky='ns')
txscrollx.grid(row=self.left_bottom + self.textbox_rows, column=0, columnspan=2, sticky='ew')
self.textbox.insert('end', 'Test message:\n')
def create_user_dialog(self):
self.intruction = tk.Label(self.right_frame, text='Enter Information Below:\n')
self.intruction.grid(row=0, column=0, sticky='nse')
self.first_name_l = tk.Label(self.right_frame, text='First Name: ')
self.first_name_e = tk.Entry(self.right_frame, textvariable=self.first_name)
self.first_name_l.grid(row=1, column=0, sticky='w')
self.first_name_e.grid(row=1, column=1, columnspan=8, sticky='ew')
self.last_name_l = tk.Label(self.right_frame, text='Last Name: ')
self.last_name_e = tk.Entry(self.right_frame, textvariable=self.last_name)
self.last_name_l.grid(row=2, column=0, sticky='w')
self.last_name_e.grid(row=2, column=1, columnspan=8, sticky='ew')
self.address1_l = tk.Label(self.right_frame, text='Address 1: ')
self.address1_e = tk.Entry(self.right_frame, textvariable=self.address1)
self.address1_l.grid(row=3, column=0, sticky='w')
self.address1_e.grid(row=3, column=1, columnspan=8, sticky='ew')
self.address2_l = tk.Label(self.right_frame, text='Address 2: ')
self.address2_e = tk.Entry(self.right_frame, textvariable=self.address2)
self.address2_l.grid(row=4, column=0, sticky='w')
self.address2_e.grid(row=4, column=1, columnspan=8, sticky='ew')
self.city_l = tk.Label(self.right_frame, text='City: ')
self.city_e = tk.Entry(self.right_frame, textvariable=self.city)
self.city_l.grid(row=5, column=0, sticky='w')
self.city_e.grid(row=5, column=1, columnspan=2, sticky='ew')
self.state_l = tk.Label(self.right_frame, text='State: ')
self.state_e = ttk.Combobox(self.right_frame, textvariable=self.state_name)
self.state_e['values'] = self.states
self.state_l.grid(row=5, column=3, sticky='w')
self.state_e.grid(row=5, column=4, columnspan=2, sticky='ew')
self.state_e.bind("<<ComboboxSelected>>", self.set_state)
self.state_e.bind("<FocusIn>", self.set_focus)
self.zipcode_l = tk.Label(self.right_frame, text='Zip Code: ')
self.zipcode_e = tk.Entry(self.right_frame, textvariable=self.zipcode)
self.zipcode_l.grid(row=6, column=0, sticky='w')
self.zipcode_e.grid(row=6, column=1, sticky='w')
self.country_l = tk.Label(self.right_frame, text='Country: ')
self.country_e = tk.Entry(self.right_frame, textvariable=self.country)
self.country_l.grid(row=7, column=0, sticky='w')
self.country_e.grid(row=7, column=1, sticky='w')
self.country_e.configure(state='readonly')
self.shoe_size_l = tk.Label(self.right_frame, text='Shoe Size: ')
self.shoe_size_e = tk.Entry(self.right_frame, textvariable=self.shoe_size)
self.shoe_size_l.grid(row=8, column=0, sticky='w')
self.shoe_size_e.grid(row=8, column=1, sticky='w')
self.spacer1 = ttk.Separator(self.right_frame)
self.spacer1.grid(row=9, rowspan=2, column=0)
create_button = tk.Button(self.right_frame, text='Create', command=self.add_person)
create_button.grid(row=11, column=0, sticky='w')
cancel_button = tk.Button(self.right_frame, text='Cancel', command=self.cancel)
cancel_button.grid(row=11, column=1, sticky='w')
remove_button = tk.Button(self.right_frame, text='Delete')
remove_button.grid(row=11, column=2, sticky='w')
remove_button.bind('<Button-1>', self.name_selected)
self.spacer2 = ttk.Separator(self.right_frame)
self.spacer2.grid(row=12, rowspan=2, column=0)
self.dup_tree = ttk.Treeview(self.right_frame,
height=self.tree_rows,
padding=(2, 2, 2, 2),
columns='Name',
selectmode="extended",
style='Treeview')
self.dup_tree.heading('#0', text='Duplicate Name Selection')
self.dup_tree.column('#0', stretch=tk.YES, width=200)
self.dup_tree.tag_configure('monospace', font='courier')
self.dw_treescrolly = tk.Scrollbar(self.right_frame, orient=tk.VERTICAL,
command=self.dup_tree.yview)
self.dw_treescrollx = tk.Scrollbar(self.right_frame, orient=tk.HORIZONTAL,
command=self.dup_tree.xview)
self.dup_tree.configure(yscroll=self.dw_treescrolly)
self.dup_tree.configure(xscroll=self.dw_treescrollx)
def hide_dup_tree(self):
self.dup_tree.forget()
self.dw_treescrolly.forget()
self.dw_treescrollx.forget()
self.dup_tree.unbind('<Double-1>')
def show_dup_tree(self):
self.dup_tree.grid(row=14, rowspan=self.dup_tree_rows, column=0, columnspan=6, sticky='nsew')
self.dw_treescrolly.grid(row=14, rowspan=self.dup_tree_rows, column=6, sticky='ns')
self.dw_treescrollx.grid(row=self.dup_tree_rows + 14, column=0, columnspan=6, sticky='ew')
self.dup_tree.bind('<Double-1>', self.person_selected)
def create_key(self, fname, lname):
return f'{lname}{fname}'
def name_selected(self, event):
# todo - new indexing
origin = str(event.widget)
widget = event.widget
fromtree = False
address1 = ''
if '!treeview' in origin:
curitem = self.tree.focus()
nidx = self.tree.item(curitem)
entry = nidx['text']
# hack to get address from Treeview element
# If anything is added to the Treeview elements, the following code will have to be changed
address1 = entry[(entry.index('street address:') + 16):]
# look for address hone in on proper dictionary entry
fromtree = True
else:
curitem = self.button.focus()
nidx = self.tree.item(curitem)
entry = nidx['text']
fields = re.split('[, \W]+', entry)
fname = fields[0]
lname = fields[1]
key = self.create_key(fname, lname)
people = self.people[key]
print(f'people: {people}')
self.selected_person = None
last_seq = int(people['last_seq'])
if last_seq > 0:
cur_seq = 0
while(cur_seq <= last_seq):
person = people[str(cur_seq)]
if fromtree:
if person['address1'] != address1:
self.add_to_dups(person)
else:
self.add_to_dups(person)
cur_seq += 1
self.show_dup_tree()
else:
self.selected_person = people['0']
# self.display_person(selected_person)
# else:
# tm.showerror('name_selected', '{} {} not found'.format(fname, lname))
def person_selected():
pass
def select_person_from_dups(self, event):
curitem = self.dup_tree.focus()
nidx = self.tree.item(curitem)
entry = nidx['text']
key = self.create_key(entry['fname'], entry['lname'])
# return self.people[key]
def display_person(self, person):
self.clear_entry()
self.first_name.set(person['fname'])
self.last_name.set(person['lname'])
self.address1.set(person['address1'])
self.address2.set(person['address2'])
self.city.set(person['city'])
self.state_name.set(person['state_name'])
self.state_abbr.set(person['state_abbr'])
self.country.set(person['state_name'])
self.shoe_size.set(person['shoesize'])
self.zipcode.set(person['zip'])
self.parent.update_idletasks()
def add_to_dups(self, person):
# Give enough information to make delete decision
# shoesize because father & son may have same name, address, and hopefully different shoe size
ptext = 'seq: {}, {} {}, {}, {}, {} -- shoe size: {}'\
.format(person['seq'], person['fname'], person['lname'], person['address1'], person['city'],
person['state_abbr'], person['shoesize'])
self.dup_tree.insert('', 'end', text=ptext)
def remove_person(self, event):
# todo - populate dup entry tree
# todo use new indexing
# todo - determine how this method was called, from clicking person in Treeview, or
# todo - from text entry (first & Last Name). If later, need to name
curitem = self.dup_tree.focus()
nidx = self.dup_tree.item(curitem)
entry = nidx['text']
fields = entry.split()
fname = fields[0]
lname = fields[1]
key = self.create_key(fname, lname)
this_item = self.people[key]
print(f'key: {key}, this_item: {this_item}')
self.clear_entry()
self.clear_dup_tree()
def clear_entry(self):
self.first_name_e.delete(0, 'end')
self.last_name_e.delete(0, 'end')
self.address1_e.delete(0, 'end')
self.address2_e.delete(0, 'end')
self.city_e.delete(0, 'end')
self.state = None
self.state_e.set('')
self.zipcode_e.delete(0, 'end')
self.country_e.delete(0, 'end')
self.shoe_size_e.delete(0, 'end')
def clear_tree(self):
all_children = self.tree.get_children()
for item in all_children:
self.tree.delete(item)
def load_tree(self):
# todo -- This one ok
self.clear_tree()
keys = list(self.people.keys())
keys.sort()
for key in keys:
group = self.people[key]
for key, person in group.items():
if key.isnumeric():
ptext = '{} {}, street address: {}'\
.format(person['fname'], person['lname'], person['address1'])
self.tree.insert('', 'end', text=ptext)
def set_focus(self, event):
event.widget.master.focus_set()
def set_state(self, event):
widget = event.widget
state_name = widget.get()
print(f'state_name: {state_name}')
us = self.state_dict['USA']
canada = self.state_dict['Canada']
mexico = self.state_dict['Mexico']
self.state_name.set(state_name)
if state_name in us:
self.state_abbr.set(us[state_name])
self.country.set('USA')
elif state_name in canada:
self.country.set('Canada')
self.state_abbr.set(canada[state_name])
elif state_name in mexico:
self.country.set('Mexico')
self.state_abbr.set(mexico[state_name])
else:
tm.showerror('set_state', 'State {} Not found'.format(state_name))
self.state_name = None
self.country = None
def cancel(self):
self.clear_entry()
def create_statusbar(self):
self.sb = tk.Frame(self.bottom_frame)
self.sb.grid(row=0, column=0, sticky='nsew')
def save_data(self):
with open(self.filename, 'w') as fo:
json.dump(self.people, fo)
def update_seq(self, key):
new_seq = None
if key in self.people:
seq_no = int(self.people[key]['last_seq'])
new_seq = str(int(seq_no) + 1)
else:
new_seq = '0'
self.people[key] = {}
self.people[key]['last_seq'] = new_seq
# self.people[key]['last_seq'] = str(int(new_seq)+1)
return(new_seq)
def add_person(self):
# todo - add check to make sure required fields are populated
# todo use new indexing
new_entry = False
lname = self.last_name.get()
fname = self.first_name.get()
key = self.create_key(fname, lname)
print(f'Add key: {key}')
seq = self.update_seq(key)
print(seq)
new_person = self.people[key][seq] = {}
new_person['lname'] = lname
new_person['fname'] = fname
new_person['seq'] = seq
new_person['address1'] = self.address1.get()
new_person['address2'] = self.address2.get()
new_person['city'] = self.city.get()
new_person['state_name'] = self.state_name.get()
new_person['state_abbr'] =self.state_abbr.get()
new_person['zip'] = self.zipcode.get()
new_person['country'] = self.country.get()
new_person['shoesize'] = self.shoe_size.get()
print(f'self.people 2: {self.people}')
self.save_data()
self.load_tree()
# ival = '{} {} , addr1: {}'.format(fname, lname, seq_no, new_person['address1'])
# self.tree.insert('', 'end', text=ival)
self.clear_entry()
def clear_dup_tree(self):
map(self.dup_tree.delete, self.dup_tree.get_children())
def on_delete(self):
self.parent.destroy()
def main():
root = tk.Tk()
ShoeBot(root)
root.mainloop()
if __name__ == '__main__':
main()
|