I'm having trouble saving the contents of dynamic tabs in a GUI environment made with tkinter in Python. When I enter the contents and click the save button, the text file created only shows the contents of the last tab in the GUI. Here is the script I'm working with.
import tkinter as tk
from tkinter import ttk
variables = dict()
def add_vehicle_tab():
v_info = ttk.Frame(tab_control)
tab_control.add(v_info, text='Tab {}'.format(tab_control.index(tk.END)))
#add content here
variables['VEH_MAKE'] = tk.StringVar(value=' ')
ttk.Label(v_info, text= 'VEH_MAKE').grid(row=2, column=0)
ttk.Entry(v_info, textvariable=variables['VEH_MAKE']).grid(row=3, column=0,sticky=(tk.W+tk.E))
variables['COLOR'] = tk.StringVar(value=' ')
ttk.Label(v_info, text= 'COLOR').grid(row=4, column=0)
ttk.Entry(v_info, textvariable=variables['COLOR']).grid(row=5, column=0,sticky=(tk.W+tk.E))
variables['YEAR'] = tk.IntVar(value=' ')
ttk.Label(v_info, text= 'YEAR').grid(row=6, column=0)
ttk.Entry(v_info, textvariable=variables['YEAR']).grid(row=7, column=0,sticky=(tk.W+tk.E))
tab_content['Tab {}'] = variables
def save_tabs():
global records_saved
make = variables['VEH_MAKE'].get()
color = variables['COLOR'].get()
year = variables['YEAR'].get()
with open("C:/tabs_data.txt", "w") as file:
for index, content in tab_content.items():
file.write(f'VEH_MAKE = {make}'), file.write('\n')
file.write(f'COLOR = {color}'), file.write('\n')
file.write(f'YEAR = {year}'), file.write('\n')
root = tk.Tk()
root.title('Vehicle tabs')
tab_control = ttk.Notebook(root)
tab_control.pack(expand=1, fill='both')
tab_content = {}
add_tab_button = tk.Button(root, text='Add vehicle tab', command=add_vehicle_tab)
add_tab_button.pack()
save_button = tk.Button(root, text="Save Tabs", command=save_tabs)
save_button.pack()
root.mainloop()
In the save_tabs() function, the script saves each item and then writes them to a new file. However, the script only saves the last tab. What do I need to do to this script to make it save all tabs?
Note that the content of variables
are overwritten to store the last set of tkinter variables whenever add_vehicle_tab()
is executed. Also same key "tab {}"
is used for tab_content
, so tab_content
has always one item.
To fix the issue:
variables
to local variable insteadtab_content
Below is the updated code required:
...
#variables = dict() # don't use global variable
def add_vehicle_tab():
v_info = ttk.Frame(tab_control)
name = 'Tab {}'.format(tab_control.index(tk.END))
tab_control.add(v_info, text=name)
variables = {} # use local variable
variables['VEH_MAKE'] = tk.StringVar()
ttk.Label(v_info, text= 'VEH_MAKE').grid(row=2, column=0)
ttk.Entry(v_info, textvariable=variables['VEH_MAKE']).grid(row=3, column=0,sticky=(tk.W+tk.E))
variables['COLOR'] = tk.StringVar()
ttk.Label(v_info, text= 'COLOR').grid(row=4, column=0)
ttk.Entry(v_info, textvariable=variables['COLOR']).grid(row=5, column=0,sticky=(tk.W+tk.E))
variables['YEAR'] = tk.IntVar()
ttk.Label(v_info, text= 'YEAR').grid(row=6, column=0)
ttk.Entry(v_info, textvariable=variables['YEAR']).grid(row=7, column=0,sticky=(tk.W+tk.E))
# use tab name as the key
tab_content[name] = variables
def save_tabs():
with open("C:/tabs_data.txt", "w") as file:
for name, variables in tab_content.items():
make = variables['VEH_MAKE'].get()
color = variables['COLOR'].get()
year = variables['YEAR'].get()
file.write(f'{name}:\n')
file.write(f'VEH_MAKE = {make}\n')
file.write(f'COLOR = {color}\n')
file.write(f'YEAR = {year}\n')
...
I would suggest to save the content in JSON format:
import json
...
def save_tabs():
data = {name: {key:var.get() for key, var in variables.items()}
for name, variables in tab_content.items()}
with open("C:/tabs_data.json", "w") as file:
json.dump(data, file, indent=4)