I am currently on my first somewhat To Do App and i have trouble with deleting things. I dont actually understand how to properly get the value to search it by index.
import json
import tkinter as tk
class JsonArrayStore:
def __init__(self, filename):
self.filename = filename
self.__load()
def __load(self):
try:
f = open(self.filename, 'r')
self.info = json.load(f)
f.close()
except FileNotFoundError:
self.info = []
def __save(self):
with open(self.filename, 'w') as f:
json.dump(self.info, f)
def append(self, data, force_save=True):
self.info.append(data)
if force_save:
self.__save()
def remove(self, index, force_save=True):
del self.info[index]
if force_save:
self.__save()
class ToDoGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Don't Forget!")
self.geometry('600x400+200+100')
self.configure(bg='#eae5e1')
self.logo_bg = tk.Frame(master=self, height=20, width=3000)
self.logo_bg.pack()
self.logo_text = tk.Label(master=self.logo_bg, bg = '#599D9C',
width=3000,
text="Kelpie's To Do App!",
font=('Impact', 45), fg='white')
self.logo_text.pack()
self.add_button_frame = tk.Frame(master=self, bg='#eae5e1')
self.add_button_frame.pack(fill='x')
self.label_border = tk.Label(master=self.add_button_frame, bg='#eae5e1',
bd=12, width='500')
self.label_border.pack()
self.add_btn = tk.Button(master=self.label_border, text='Add Task!', command=self.on_button)
self.add_btn.pack(side='right', padx=10)
# Later: Add a placeholder func
self.add_text = tk.Entry(master=self.label_border)
self.add_text.insert(0, '')
self.add_text.pack(side='left', padx=10)
# Frames for tasks
self.task_frame = tk.Frame(master=self)
self.task_frame.pack()
# load from json file
a = JsonArrayStore('test1.json')
for i in a.info:
add_task_label = tk.Label(master=self, bg='red', text=f'{i}')
add_task_label.pack()
delete_btn = tk.Button(self, bg='green', text='Delete', command=self.del_btn)
delete_btn.pack()
def on_button(self):
a = JsonArrayStore('test1.json')
a.append(self.add_text.get())
task = tk.Label(master=self, bg='red', text=f'{self.add_text.get()}')
task.pack()
delete_btn = tk.Button(self, bg='green', text='Delete', command=self.del_btn)
delete_btn.pack()
def del_btn(self):
a = JsonArrayStore('test1.json')
x = a.info.index()
test = ToDoGUI()
test.mainloop()
This can be done by using enumerate to get the index in the for-loop and then using a lambda as command for the delete button which stores the index. Roughly:
for idx, i in enumerate(a.info):
add_task_label = tk.Label(master=self, bg='red', text=f'{i}')
add_task_label.pack()
delete_btn = tk.Button(self, bg='green', text='Delete', command=lambda idx=idx: self.del_btn(idx))
delete_btn.pack()
...
def del_btn(self, idx):
Related
I am building a small app where I am doing some calculations and want to save the variables and results into a *.csv file.
My desire is to open the *.csv file via a menu point in Tkinter and, after calculations done, save the results with a button to the *.csv file.
What I am not able to do is to save the data, as I am passing the file name in the wrong way.
I have tried to assign the file name to a variable, declare it as global but have not find any solution.
This is the code snippet requested, not just the 2 functions:
import tkinter as tk
from tkinter import *
# Used for styling the GUI
from tkinter import ttk
from math import *
import csv
from tkinter import filedialog as fd
from tkinter.filedialog import asksaveasfile
from tkinter.messagebox import showinfo
from datetime import datetime
# global database
class windows(tk.Tk):
def __init__(self, *args, **kwargs):
global database
tk.Tk.__init__(self, *args, **kwargs)
# Adding a title to the window
self.wm_title("calculator and database")
#
tire_menu = Menu(self)
self.config(menu=tire_menu)
def command_open():
filename = fd.askopenfilename(
title = 'Select database',
filetypes = [("CSV files", "*.csv")])
showinfo(
title = 'You have selected',
message = filename)
database = filename
return(database)
def command_new():
extensions = [("csv file(*.csv)", "*.csv")]
file = asksaveasfile(filetypes=extensions,
defaultextension=extensions)
headerlist = [
"Date",
"Track"]
database = file.name
with open(database, "w") as f:
writer = csv.writer(f)
writer.writerow(headerlist)
# create a menu item
file_menu = Menu(tire_menu)
db_menu = Menu(tire_menu)
tire_menu.add_cascade(label="File", menu = file_menu)
file_menu.add_command(label="Exit", command=self.quit)
tire_menu.add_cascade(label="Database", menu = db_menu)
db_menu.add_command(label="New DB", command=command_new)
db_menu.add_command(label="Open DB", command=command_open)
# creating a frame and assigning it to container
container = tk.Frame(self, height=600, width=800)
# specifying the region where the frame is packed in root
container.pack(side="top", fill="both", expand=True)
# configuring the location of the container using grid
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
# We will now create a dictionary of frames
self.frames = {}
# we'll create the frames themselves later but let's add the components to the dictionary.
for F in (MainPage, SidePage, CompletionScreen):
frame = F(container, self)
# the windows class acts as the root window for the frames.
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
# Using a method to switch frames
self.show_frame(MainPage)
def show_frame(self, cont):
frame = self.frames[cont]
# raises the current frame to the top
frame.tkraise()
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
title_main = tk.Label(
self,
text="calculator")
title_main.config(font=("Times 18 bold"), bg="white")
title_main.grid(row=0, column=0, columnspan=2, pady=5)
def savetodb():
data = [
datetime.today().strftime('%Y-%m-%d'),
]
with open(database, "w") as f:
writer = csv.writer(f)
writer.writerow(data)
## Create reference tire pressures frame
frame_reference = tk.LabelFrame(
self,
text = "1: Enter reference data: ")
frame_reference.grid(row=1, column=0, padx=5, pady=5, columnspan = 2)
lbl_track = Label(
frame_reference,
text = "Track: ",
font = 'Times 11',
justify = tk.CENTER)
lbl_track.grid(row = 0, column = 0)
# entries for database save
ent_track = Entry(
frame_reference,
justify = tk.CENTER,
width = 23).grid(row=0, column=1)
btn_savetodb = Button(
frame_reference,
text="Save to DB!",
font = 'Times 11 bold',
command=savetodb)
btn_savetodb.grid(row=2, column=0, columnspan=2, padx=10, pady=5)
class SidePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="This is the Side Page")
label.pack(padx=10, pady=10)
switch_window_button = tk.Button(
self,
text="Go to the Completion Screen",
command=lambda: controller.show_frame(CompletionScreen),
)
switch_window_button.pack(side="bottom", fill=tk.X)
class CompletionScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Completion Screen, we did it!")
label.pack(padx=10, pady=10)
switch_window_button = ttk.Button(
self, text="Return to menu", command=lambda: controller.show_frame(MainPage)
)
switch_window_button.pack(side="bottom", fill=tk.X)
if __name__ == "__main__":
testObj = windows()
testObj.mainloop()
Could you please provide some help?
You have declared global database in wrong place. It should be put inside command_open() as I said in my comment:
class windows(tk.Tk):
def __init__(self, *args, **kwargs):
...
def command_open():
global database
...
database = filename
return database
...
...
However I would suggest to use a class variable inside windows class instead of global variable, so that it can be accessed using controller.database inside MainPage class:
class windows(tk.Tk):
def __init__(self, *args, **kwargs):
...
self.database = None
...
def command_open():
...
self.database = filename
return self.database
...
...
...
class MainPage(tk.Frame):
def __init__(self, parent, controller):
...
def savetodb():
...
with open(controller.database, "w") as f:
...
...
...
Note that you have to change all occurrences of database to self.database inside windows class.
I have a json file that i save my listbox data in. After i choose items (highlight) from the listbox and save my file then load it, the listbox items are stored in my file and they are printed but they are not highlighted. How can I highlight them so i can deselect and select again if i want to change my item selection?
THE CODE:
import tkinter as tk
import json
from tkinter.filedialog import askdirectory
root = tk.Tk()
root.title('Intialization')
value = []
def callback(listbox):
global value
value = [listbox.get(ratio) for ratio in listbox.curselection()]
def writeToJSONFile(path, fileName, data):
filePathNameWExt = path + '/' + fileName + '.json'
with open(filePathNameWExt, 'w') as fp:
json.dump(data, fp)
def check():
global value
data = {}
path = askdirectory()
data['items'] = value
writeToJSONFile(path, 'json', data)
def w():
window = tk.Toplevel(root)
window.title('Main')
global value
listbox = tk.Listbox(window, activestyle='dotbox', selectmode=tk.MULTIPLE, exportselection=False)
values = [100, 155, 200, 255, 300, 355, 400]
for item in values:
listbox.insert(tk.END, item)
scrollbar = tk.Scrollbar(window)
scrollbar.grid(column=0, row=2, sticky='nse', pady=20)
listbox.bind('<<ListboxSelect>>', func=lambda z: callback(listbox))
listbox.config(width=13, height=4, yscrollcommand=scrollbar.set)
listbox.grid(column=0, row=2, pady=20, sticky='ne')
save_config = tk.Button(window, text="Save Configuration", bg='green', command=lambda: check())
save_config.grid(column=0, row=3)
try:
f = open('json.json', "r")
j = json.loads(f.read())
for key, value in j.items():
print(key, ":", value)
value = j['items']
print(j)
except FileNotFoundError:
print("No Json File")
window.grab_set()
load_btn = tk.Button(root, text="Load", command=w)
load_btn.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
root.mainloop()
After you read this json file,you could get the index of values and make those items selected.
Try:
import tkinter as tk
import json
from tkinter.filedialog import askdirectory
root = tk.Tk()
root.title('Intialization')
value = []
def callback(listbox):
global value
value = [listbox.get(ratio) for ratio in listbox.curselection()]
def writeToJSONFile(path, fileName, data):
filePathNameWExt = path + '/' + fileName + '.json'
with open(filePathNameWExt, 'w') as fp:
json.dump(data, fp)
def check():
global value
data = {}
path = askdirectory()
data['items'] = value
writeToJSONFile(path, 'json', data)
def w():
window = tk.Toplevel(root)
window.title('Main')
global value
listbox = tk.Listbox(window, activestyle='dotbox', selectmode=tk.MULTIPLE, exportselection=False)
values = [100, 155, 200, 255, 300, 355, 400]
for item in values:
listbox.insert(tk.END, item)
scrollbar = tk.Scrollbar(window)
scrollbar.grid(column=0, row=2, sticky='nse', pady=20)
listbox.bind('<<ListboxSelect>>', func=lambda z: callback(listbox))
listbox.config(width=13, height=4, yscrollcommand=scrollbar.set)
listbox.grid(column=0, row=2, pady=20, sticky='ne')
save_config = tk.Button(window, text="Save Configuration", bg='green', command=lambda: check())
save_config.grid(column=0, row=3)
try:
f = open('json.json', "r")
j = json.loads(f.read())
for key, value in j.items():
print(key, ":", value)
value = j['items']
index_list = [values.index(i) for i in value] # get the index
for index in index_list:
listbox.selection_set(index) # make it selected
f.close()
except FileNotFoundError:
print("No Json File")
window.grab_set()
load_btn = tk.Button(root, text="Load", command=w)
load_btn.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
root.mainloop()
This is my first time here, and I would really appreciate some help with this.
So I have some code which runs a Tkinter tab and shows 2 buttons. If you click the first one, a picture of a cat appears.
However, if you click the button again, the same picture appears again at the bottom, making there 2.
If I click the other button, titled N/A, a different picture appears. But if you click the button again, the picture duplicates.
I want to make it so that when each button is pressed, the image is replaced, not duplicated.
Here is what I have so far.
from tkinter import *
root = Tk()
class HomeClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome to the game!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.FirstButton = Button(root, text="Start", bg="RED", fg="White",
command=self.FirstClick)
self.FirstButton.pack(side=LEFT, fill=X)
self.SecondButton = Button(root, text="N/A", bg="Blue", fg="White",
command=self.SecondClick)
self.SecondButton.pack(side=LEFT, fill=X)
def FirstClick(self):
FirstPhoto = PhotoImage(file="keyboardcat.gif")
FiLabel = Label(root, image=FirstPhoto)
FiLabel.img = FirstPhoto
FiLabel.pack()
def SecondClick(self):
FirstPhoto = PhotoImage(file="donald.gif")
FiLabel = Label(root, image=FirstPhoto)
FiLabel.img = FirstPhoto
FiLabel.pack()
k = HomeClass(root)
root.mainloop()
That's becouse every time you click a button, you're calling FirstClick method which in turn creates new instance of PhotoImage class. I think it would be better to store FirstPhoto and in every FirstClick method call check if it is already has value or not.
class HomeClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome to the game!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.FirstButton = Button(root, text="Start", bg="RED", fg="White",
command=self.FirstClick)
self.FirstButton.pack(side=LEFT, fill=X)
self.SecondButton = Button(root, text="N/A", bg="Blue", fg="White",
command=self.SecondClick)
self.SecondButton.pack(side=LEFT, fill=X)
self.FirstPhoto = None
def FirstClick(self):
if self.FirstPhoto is None:
self.FirstPhoto = PhotoImage(file="ksiazka.png")
self.FiLabel = Label(root, image=self.FirstPhoto)
self.FiLabel.img = self.FirstPhoto
self.FiLabel.pack()
Try this to change SecondPhoto
def SecondClick(self):
if self.SecondPhoto is None:
self.SecondPhoto = PhotoImage(file="ksiazka.png")
self.SecondPhotoLabel = Label(root, image=self.FirstPhoto)
self.SecondPhotoLabel.img = self.SecondPhoto
self.SecondPhotoLabel.pack()
Else:
self.SecondPhotoLabel.config(image='newimage')
self.SecondPhotoLabel.update()
Note - you can declare the newImage before as you have to read it with PhotoImage and then just put the image name in the .config
In this example you have two methods FirstClick, SecondClick to display an image and two methods to clear an first and second image accordingly: clearFirstImage, clearSecondImage. You just have to add two buttons to trigger those clear methods :)
from tkinter import *
from tkFileDialog import askopenfilename
root = Tk()
class HomeClass(object):
def __init__(self, master):
self.master = master
self.frame = Frame(master)
self.WelcomeLabel = Label(root, text="Welcome to the game!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.FirstButton = Button(root, text="Start", bg="RED", fg="White",
command=self.FirstClick)
self.FirstButton.pack(side=LEFT, fill=X)
self.SecondButton = Button(root, text="N/A", bg="Blue", fg="White",
command=self.SecondClick)
self.SecondButton.pack(side=LEFT, fill=X)
self.ToggleButtonText = "Show image"
self.ToggleButton = Button(root, text=self.ToggleButtonText, bg="Grey", fg="White",
command=self.ToggleClick)
self.ToggleButton.pack(side=LEFT, fill=X)
self.FirstPhoto = None
self.FiLabel = None
self.SecondPhoto = None
self.SecondPhotoLabel = None
self.ToggleButtonPhoto = None
self.ToggleButtonPhotoLabel = None
self.frame.pack()
def FirstClick(self):
if self.FirstPhoto is None:
self.FirstPhoto = PhotoImage(file="ksiazka.png")
self.FiLabel = Label(root, image=self.FirstPhoto)
self.FiLabel.img = self.FirstPhoto
self.FiLabel.pack()
def ToggleClick(self):
if self.ToggleButtonPhoto is None:
self.ToggleButtonPhoto = PhotoImage(file="ksiazka.png")
self.ToggleButtonPhotoLabel = Label(self.frame, image=self.ToggleButtonPhoto)
self.ToggleButtonPhotoLabel.img = self.ToggleButtonPhoto
self.ToggleButtonPhotoLabel.pack()
# and set label
self.ToggleButton.config(text="Hide image")
else:
self.ToggleButton.config(text="Show image")
self.ToggleButtonPhotoLabel.destroy()
self.ToggleButtonPhotoLabel.img = None
self.ToggleButtonPhotoLabel = None
self.ToggleButtonPhoto = None
self.frame.pack()
def SecondClick(self):
filename = askopenfilename()
allowed_extensions = ['jpg', 'png']
if len(filename) > 0 and filename.split('.')[-1] in allowed_extensions:
self.SecondPhoto = PhotoImage(file=filename)
self.SecondPhotoLabel = Label(root, image=self.SecondPhoto)
self.SecondPhotoLabel.img = self.SecondPhoto
self.SecondPhotoLabel.pack()
def clearFirstImage(self):
self.FirstPhoto = None
self.FiLabel = None
def clearSecondImage(self):
self.SecondPhoto = None
self.SecondPhotoLabel = None
k = HomeClass(root)
root.mainloop()
If you want to replace an existing image, first create the label the image is displayed in, and simply reconfigure only its image option with each click. Below is an example that does that:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def download_images():
# In order to fetch the image online
try:
import urllib.request as url
except ImportError:
import urllib as url
url.urlretrieve("https://i.stack.imgur.com/57uJJ.gif", "13.gif")
url.urlretrieve("https://i.stack.imgur.com/8LThi.gif", "8.gif")
class ImageFrame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
self._create_widgets()
self._display_widgets()
def _create_widgets(self):
def __create_image_label():
def ___load_images():
self.label.images = list()
self.label.images.append(tk.PhotoImage(file="8.gif"))
self.label.images.append(tk.PhotoImage(file="13.gif"))
self.label = tk.Label(self)
___load_images()
def __create_buttons():
self.buttons = list()
for i in range(2):
self.buttons.append(tk.Button(self, text=i,
command=lambda i=i: self.replace_image(i)))
__create_image_label()
__create_buttons()
def replace_image(self, button_index):
"""
Replaces the image in label attribute based on the index of the
button pressed.
"""
self.label['image'] = self.label.images[button_index]
def _display_widgets(self):
self.label.pack()
for i in range(2):
self.buttons[i].pack(fill='x', expand=True)
if __name__ == '__main__':
#download_images() # comment out after initial run
root = tk.Tk()
frame = ImageFrame(root)
frame.pack()
tk.mainloop()
I am trying to make a GUI for my program but I have changed my code a lot and I saw that GUI misses one frame but it was fine before.
Could anyone help me and tell why a frame with a button does not appear on the bottom?
Whole "button_part" object does not appear.
from tkinter import *
import tkinter as tk
import os
import glob
BOUNDS = ["Last week", "Last 2 weeks", "Last 3 weeks"]
class settings_part:
path_to_copy = 0
def __init__(self, master, update_func):
path_to_copy = StringVar()
settings_frame = Frame(master, background="")
settings_frame.pack(side=TOP, fill=X)
date_bound = StringVar()
date_bound.set(BOUNDS[1])
date_option = OptionMenu(settings_frame, date_bound, *BOUNDS, command=update_func)
date_option.config(background="#732c30")
date_option.config(foreground="white")
date_option.config(bd=0)
date_option.pack(side=LEFT, padx=5, pady=5)
path_to_copy.set("~/Python/usun")
box_with_path = Entry(settings_frame, textvariable=path_to_copy)
box_with_path.pack(side=RIGHT, padx=5, pady=5)
# s = path_to_copy.get()
class songs_part:
def __init__(self, master, root):
self.songs_frame = Frame(master)
self.update_songs(root.list_of_songs)
self.songs_frame.pack()
def update_songs(self, l):
for song in l:
c = Checkbutton(self.songs_frame, text=song[0], variable=song[1])
c.pack()
class button_part:
def __init__(self, master, copyFunc):
self.button_frame = Frame(master)
btn_image = PhotoImage(file="copybtn.png")
self.copy_button = Button(self.button_frame, command=copyFunc, text="Copy",
image=btn_image, highlightthickness=0, bd=0, activebackground="#732c30")
self.copy_button.pack()
class App:
def __init__(self):
root = Tk()
root.title("Copying songs")
root.geometry("500x500")
root.option_add("*Font", "Calibra")
back_image = PhotoImage(file="back.png")
self.window = Label(root, image=back_image)
self.window.pack(fill="both", expand="yes")
self.list_of_songs = list()
self.make_list_of_songs()
self.set_part = settings_part(self.window, self.update_list)
self.son_part = songs_part(self.window, self)
self.but_part = button_part(self.window, self.copy_songs)
root.mainloop()
def make_list_of_songs(self):
owd = os.getcwd()
os.chdir("/home/stanek/Music/usun")
for file in glob.glob("*.mp3"):
self.list_of_songs.append([file, tk.IntVar()])
os.chdir(owd)
def copy_songs(self):
for s in self.list_of_songs:
print(s)
def update_list(self, arg):
print("updating list with songs from " + arg)
self.son_part = songs_part(self.window, self)
if __name__ == '__main__':
App()
You never pack the button frame.
I am making a client list and I am using a dictionary and pickle to save and store the clients name and age. Unfortunately my save function overwrites any existing users and then my __init__ function doesn't display the pickled data in the dictionary just the ones I have typed in myself. Also the add function doesn't display the label with the client name on it. Can you please help with the pickle problems because I need an answer fast!
Thanks in advance!
from Tkinter import *
import pickle
root=Tk()
dic={}
class Launch(object):
def __init__(self, root):
root.withdraw()
root=Toplevel(root)
root.title("Choose Client")
self.row=3
for key in dic:
Label(root, text=key).grid(row=row, column=0)
self.row+=1
l3=Label(root, text="Client Name")
l3.grid(row=0, column=0)
self.e1=Entry(root)
self.e1.grid(row=0, column=1)
l4=Label(root, text="Client age")
l4.grid(row=1, column=0)
self.e2=Entry(root)
self.e2.grid(row=1, column=1)
b3=Button(root, text="Create client", command=self.add)
b3.grid(row=2)
def add(self):
client=self.e1.get()
age=self.e2.get()
dic[client]=age
Label(root, text="%s" % (client)).grid(row=self.row)
with open("data", "w") as f:
pickle.dump(dic, f)
def load(self):
dic=pickle.load(open("data", "rb"))
app=Launch(root)
root.mainloop()
The load method is not used at all. The following is modified code to use the load.
from Tkinter import *
import pickle
root=Tk()
dic={}
class Launch(object):
def __init__(self, root):
self.load() # <-- load
root.title("Choose Client")
self.row = 3
for key in dic:
Label(root, text=key).grid(row=self.row, column=0)
self.row += 1
l3=Label(root, text="Client Name")
l3.grid(row=0, column=0)
self.e1=Entry(root)
self.e1.grid(row=0, column=1)
l4=Label(root, text="Client age")
l4.grid(row=1, column=0)
self.e2=Entry(root)
self.e2.grid(row=1, column=1)
b3=Button(root, text="Create client", command=self.add)
b3.grid(row=2)
def add(self):
client=self.e1.get()
age=self.e2.get()
dic[client]=age
Label(root, text=client).grid(row=self.row)
self.row += 1 # <--- increase row count
with open("data", "wb") as f:
pickle.dump(dic, f)
def load(self):
# should be declared, otherwise, will create local variable
global dic
try:
dic = pickle.load(open("data", "rb"))
except IOError: # if file does not exist.
pass
app = Launch(root)
root.mainloop()
Following is another version that use instance variable instead of global variable:
from Tkinter import *
import pickle
class Launch(object):
def __init__(self, root):
self.load() # <-- load
root.title("Choose Client")
self.row = 3
for key in self.dic:
Label(root, text=key).grid(row=self.row, column=0)
self.row += 1
l3 = Label(root, text="Client Name")
l3.grid(row=0, column=0)
self.e1 = Entry(root)
self.e1.grid(row=0, column=1)
l4 = Label(root, text="Client age")
l4.grid(row=1, column=0)
self.e2 = Entry(root)
self.e2.grid(row=1, column=1)
b3 = Button(root, text="Create client", command=self.add)
b3.grid(row=2)
def add(self):
client = self.e1.get()
age = self.e2.get()
self.dic[client] = age
Label(root, text=client).grid(row=self.row)
self.row += 1 # <--- increase row count
with open("data", "wb") as f:
pickle.dump(self.dic, f)
def load(self):
try:
self.dic = pickle.load(open("data", "rb"))
except IOError:
self.dic = {}
root = Tk()
app = Launch(root)
root.mainloop()