(Disclaimer: I haven't tested it, please let me know if it needs fixing)
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
window.title('ACFA Save Editor')
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
window.title('ACFA Save Editor')
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
(Disclaimer: I haven't tested it, please let me know if it needs fixing)
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
window.title('ACFA Save Editor')
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
window.title('ACFA Save Editor')
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
```
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
window.title('ACFA Save Editor')
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
```
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
window.title('ACFA Save Editor')
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
It depends what direction you want to go with your program, but my suggestion would be to make small factories for components you use the most often. Here it seems you are building a common UI feature: a form with several fields. Since you only have a single form you don't really benefit from abstracting the form for now, except for clarity, but you benefit from abstracting the fields as you use 4 of them.
So this code separates better generic UI components and data although it's not perfect; but UI code rarely is. Since you usually only have a handfew windows in the average app it's often OK to hardcode some values and components. It's a matter of making compromises between genericity, features, and verbosity.
class FormField:
def __init__(self, window, row, label, placeholder=None):
tk.Label(window, text=label).grid(row=row)
self.entry = tk.Entry(window)
self.entry.grid(row, column=1)
if placeholder:
self.entry.insert(0, placeholder)
def get(self):
return self.entry.get()
class Form:
def __init__ (self, window, row, field_keywords, callback, button_text):
self.fields = []
for i, field_keyword in enumerate(field_keywords):
self.fields.append(window, row=row + i, **field_keyword)
self.callback = callback
# This '10' is hardcoded, but you could compute it from button_text length
b_apply = tk.Button(window, text=button_text, width=10, command=self.submit))
def submit(self):
self.callback(*[field.get() for field in self.fields])
def init_ui(window, root_dir):
window.title('ACFA Save Editor')
p, a, c, f = read_data(APGD)
fields_kws = [{'label':'Pilot name: ', 'placeholder':p},
{'label':'AC name: ', 'placeholder':a},
{'label':'COAM (money): ', 'placeholder':c},
{'label':'FRS Memory: ', 'placeholder':f}]
ui_form = Form(window, 1, field_kws, lambda p, a, c, f: apply(p, a, c, f, APGD, GAMEDAT), 'Apply')
# Below is code that is tricky to make any more generic and can be left as is
# Making UI abstractions for single use components can be complexity you don't need
messagebox.showinfo('Open Save Folder', 'Ex: GAMEDATXXXX')
directory = askdirectory(initialdir=root_dir)
APGD = directory + '/APGD.dat'
GAMEDAT = directory + '/' + directory.split('/')[-1] + '_CONTENT'
b_quit = tk.Button(window, text='Quit', width=10,
command=window.destroy).grid(row=4, column=1)
return window
```