Skip to content

Commit 385b59c

Browse files
committed
changes per ch9 review
1 parent 306d8a7 commit 385b59c

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

Chapter09/ABQ_Data_Entry/abq_data_entry/application.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ def __init__(self, *args, **kwargs):
2121
# Hide window while GUI is built
2222
self.withdraw()
2323

24+
# Set taskbar icon
25+
self.taskbar_icon = tk.PhotoImage(file=images.ABQ_LOGO_64)
26+
self.iconphoto(True, self.taskbar_icon)
27+
2428
# Authenticate
2529
if not self._show_login():
2630
self.destroy()
@@ -32,24 +36,14 @@ def __init__(self, *args, **kwargs):
3236
# Create model
3337
self.model = m.CSVModel()
3438

35-
# Load settings
36-
# self.settings = {
37-
# 'autofill date': tk.BooleanVar(),
38-
# 'autofill sheet data': tk.BoleanVar()
39-
# }
39+
# load settings
4040
self.settings_model = m.SettingsModel()
4141
self._load_settings()
4242

43-
self.inserted_rows = []
44-
self.updated_rows = []
45-
4643
# Begin building GUI
4744
self.title("ABQ Data Entry Application")
4845
self.columnconfigure(0, weight=1)
4946

50-
# Set taskbar icon
51-
self.taskbar_icon = tk.PhotoImage(file=images.ABQ_LOGO_64)
52-
self.iconphoto(True, self.taskbar_icon)
5347

5448
# Create the menu
5549
menu = MainMenu(self, self.settings)
@@ -91,9 +85,7 @@ def __init__(self, *args, **kwargs):
9185

9286
# The data record list
9387
self.recordlist_icon = tk.PhotoImage(file=images.LIST_ICON)
94-
self.recordlist = v.RecordList(
95-
self, self.inserted_rows, self.updated_rows
96-
)
88+
self.recordlist = v.RecordList(self)
9789
self.notebook.insert(
9890
0, self.recordlist, text='Records',
9991
image=self.recordlist_icon, compound=tk.LEFT
@@ -139,10 +131,10 @@ def _on_save(self, *_):
139131
rownum = self.recordform.current_record
140132
self.model.save_record(data, rownum)
141133
if rownum is not None:
142-
self.updated_rows.append(rownum)
134+
self.recordlist.add_updated_row(rownum)
143135
else:
144136
rownum = len(self.model.get_all_records()) -1
145-
self.inserted_rows.append(rownum)
137+
self.recordlist.add_inserted_row(rownum)
146138
self.records_saved += 1
147139
self.status.set(
148140
"{} records saved this session".format(self.records_saved)
@@ -160,9 +152,8 @@ def _on_file_select(self, *_):
160152
)
161153
if filename:
162154
self.model = m.CSVModel(filename=filename)
163-
self.inserted_rows.clear()
164-
self.updated_rows.clear()
165155
self._populate_recordlist()
156+
self.recordlist.clear_tags()
166157

167158
@staticmethod
168159
def _simple_login(username, password):
@@ -260,7 +251,9 @@ def _set_font(self, *_):
260251
"""Set the application's font"""
261252
font_size = self.settings['font size'].get()
262253
font_family = self.settings['font family'].get()
263-
font_names = ('TkDefaultFont', 'TkMenuFont', 'TkTextFont')
254+
font_names = (
255+
'TkDefaultFont', 'TkMenuFont', 'TkTextFont', 'TkFixedFont'
256+
)
264257
for font_name in font_names:
265258
tk_font = font.nametofont(font_name)
266259
tk_font.config(size=font_size, family=font_family)

Chapter09/ABQ_Data_Entry/abq_data_entry/views.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,16 @@ def __init__(self, parent, model, settings, *args, **kwargs):
126126
field_spec=fields['Lab'],
127127
var=self._vars['Lab'],
128128
label_args={'style': 'RecordInfo.TLabel'},
129-
input_args={'style': 'RecordInfo.TRadiobutton'}
129+
input_args={
130+
'button_args':{'style': 'RecordInfo.TRadiobutton'}
131+
}
130132
).grid(row=1, column=0)
131133
w.LabelInput(
132134
r_info, "Plot",
133135
field_spec=fields['Plot'],
134136
var=self._vars['Plot'],
135137
label_args={'style': 'RecordInfo.TLabel'}
136-
).grid(row=1, column=0)
138+
).grid(row=1, column=1)
137139
w.LabelInput(
138140
r_info, "Seed Sample",
139141
field_spec=fields['Seed Sample'],
@@ -419,10 +421,11 @@ class RecordList(tk.Frame):
419421
default_minwidth = 10
420422
default_anchor = tk.CENTER
421423

422-
def __init__(self, parent, inserted, updated, *args, **kwargs):
424+
def __init__(self, parent, *args, **kwargs):
423425
super().__init__(parent, *args, **kwargs)
424-
self.inserted = inserted
425-
self.updated = updated
426+
self._inserted = list()
427+
self._updated = list()
428+
426429
self.columnconfigure(0, weight=1)
427430
self.rowconfigure(0, weight=1)
428431

@@ -471,9 +474,9 @@ def populate(self, rows):
471474
cids = list(self.column_defs.keys())[1:]
472475
for rownum, rowdata in enumerate(rows):
473476
values = [rowdata[cid] for cid in cids]
474-
if rownum in self.inserted:
477+
if rownum in self._inserted:
475478
tag = 'inserted'
476-
elif rownum in self.updated:
479+
elif rownum in self._updated:
477480
tag = 'updated'
478481
else:
479482
tag = ''
@@ -490,3 +493,15 @@ def _on_open_record(self, *args):
490493

491494
self.selected_id = int(self.treeview.selection()[0])
492495
self.event_generate('<<OpenRecord>>')
496+
497+
def add_updated_row(self, row):
498+
if row not in self._updated:
499+
self._updated.append(row)
500+
501+
def add_inserted_row(self, row):
502+
if row not in self._inserted:
503+
self._inserted.append(row)
504+
505+
def clear_tags(self):
506+
self._inserted.clear()
507+
self._updated.clear()

Chapter09/ABQ_Data_Entry/abq_data_entry/widgets.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -283,23 +283,31 @@ def _focusout_validate(self, **kwargs):
283283

284284
return valid
285285

286-
class ValidatedRadio(ttk.Radiobutton):
287-
"""A validated radio button"""
286+
class ValidatedRadioGroup(ttk.Frame):
287+
"""A validated radio button group"""
288288

289-
def __init__(self, *args, error_var=None, **kwargs):
289+
def __init__(
290+
self, *args, variable=None, error_var=None,
291+
values=None, button_args=None, **kwargs
292+
):
290293
super().__init__(*args, **kwargs)
294+
self.variable = variable or tk.StringVar()
291295
self.error = error_var or tk.StringVar()
292-
self.variable = kwargs.get("variable")
293-
self.bind('<FocusOut>', self._focusout_validate)
296+
self.values = values or list()
297+
button_args = button_args or dict()
294298

295-
def _focusout_validate(self, *_):
299+
for v in self.values:
300+
button = ttk.Radiobutton(
301+
self, value=v, text=v, variable=self.variable, **button_args
302+
)
303+
button.pack(side=tk.LEFT, ipadx=10, ipady=2, expand=True, fill='x')
304+
self.bind('<FocusOut>', self.trigger_focusout_validation)
305+
306+
def trigger_focusout_validation(self, *_):
296307
self.error.set('')
297308
if not self.variable.get():
298309
self.error.set('A value is required')
299310

300-
def trigger_focusout_validation(self):
301-
self._focusout_validate()
302-
303311

304312
class BoundText(tk.Text):
305313
"""A Text widget with a bound variable."""
@@ -337,7 +345,7 @@ class LabelInput(ttk.Frame):
337345
field_types = {
338346
FT.string: RequiredEntry,
339347
FT.string_list: ValidatedCombobox,
340-
FT.short_string_list: ValidatedRadio,
348+
FT.short_string_list: ValidatedRadioGroup,
341349
FT.iso_date_string: DateEntry,
342350
FT.long_string: BoundText,
343351
FT.decimal: ValidatedSpinbox,
@@ -381,14 +389,14 @@ def __init__(
381389

382390
# setup the variable
383391
if input_class in (
384-
ttk.Checkbutton, ttk.Button, ttk.Radiobutton, ValidatedRadio
392+
ttk.Checkbutton, ttk.Button, ttk.Radiobutton, ValidatedRadioGroup
385393
):
386394
input_args["variable"] = self.variable
387395
else:
388396
input_args["textvariable"] = self.variable
389397

390398
# Setup the input
391-
if input_class in (ttk.Radiobutton, ValidatedRadio):
399+
if input_class == ttk.Radiobutton:
392400
# for Radiobutton, create one input per value
393401
self.input = tk.Frame(self)
394402
for v in input_args.pop('values', []):

0 commit comments

Comments
 (0)