save entry values for next programmstart tkinter - python

thanks a lot for your time. I'm currently stuck at the following point: I have developed a GUI with Tkinter with about 200 entries. (For simplification I have only included a small section below). But these 200 entries are seldom filled in at once. Normally 50 entries are filled in every start of the program. When the program is closed, these filled in values are deleted and have to be filled in again after the program is started again. Is there a way to prevent this?
I do not want to lose the values entered in jobNameA_entry and jobNameB_entry when closing the program.
Many thanks in any case.
import tkinter as tk
class Win1:
def __init__(self, master):
self.master = master
self.master.title("Gap Assessment")
self.topFrame = tk.Frame(self.master)
self.topFrame.grid(row=0, column=0, sticky='news', ipady = 5)
self.A_GapFrame = tk.Frame(self.master)
self.B_GapFrame = tk.Frame(self.master)
self.subframe_AGap()
self.subframe_BGap()
# Create a Tkinter variable
self.gapType = tk.StringVar(self.master)
# Dictionary with optionsverschwinden
self.choiceGap = ['AFrame','BFrame']
# self.choiceGap = sorted(self.choiceGap)
self.gapType.set('') # set the default option
self.ctngMenu = tk.OptionMenu(self.topFrame, self.gapType, *self.choiceGap, command=self.chioseGap_handle)
self.ctngMenu.grid(row = 1, column =2)
def chioseGap_handle(self, selected):
if selected == 'AFrame':
self.A_GapFrame.tkraise()
# self.subframe_AGap()
self.A_GapFrame.place(x=20, y=30, width = 210)
self.B_GapFrame.place_forget()
if selected == 'BFrame':
self.B_GapFrame.tkraise()
# self.subframe_BGap()
self.B_GapFrame.place(x=30, y=70, width = 210)
self.A_GapFrame.place_forget()
def subframe_AGap(self):
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
self.jobNameA_entry.grid(row=1, column=0, sticky='news')
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
def subframe_BGap(self):
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
self.jobNameB_entry.grid(row=2, column=0, sticky='news')
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
root = tk.Tk()
root.geometry("200x300+50+50")
app = Win1(root)
root.mainloop()

Related

Tkinter issue when removing text fields

i am working on a GUI in Tkinter, and i have encountered a wierd issue that i have been struggling to solve.
The goal is to remove and add users from the interface. When a user is added, it is displayed, and when deleted the user should disappear from the GUI.
This is where my issue begins. When only adding and removing one user, everything works fine.
However when two or more users are added, the removal process fails. The removal works as expected on the first try, but when trying to remove any more, the interface does not update. The users get removed from the list as should, but the GUI never updates. Here is my code
#anden slet klik virker ikke
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.entries = -1
self.people = []
self.names = []
self.id = []
self.tlf = []
self.frames = []
self.master = master
self.pack()
self.create_widgets()
#Create the first two rows of the application
def create_widgets(self):
# Row 0: Input boxes
self.inputName = tk.Entry(self, bd=4)
self.inputName.grid(row=0, column=0)
self.inputID = tk.Entry(self, bd=4)
self.inputID.grid(row=0, column=1)
self.inputTLF = tk.Entry(self, bd=4)
self.inputTLF.grid(row=0, column=2)
# Row 0: "Add" button
self.addButton = tk.Button(self, text="Add", command=self.AddMember)
self.addButton.grid(row=0, column=3)
# Row 1: Labels
tk.Label(self, text = "Navn", borderwidth = 4).grid(row=1, column=0)
tk.Label(self, text="ID", borderwidth=4).grid(row=1, column=1)
tk.Label(self, text="Tlf", borderwidth=4).grid(row=1, column=2, ipadx=30)
tk.Label(self, text=" ", borderwidth=4).grid(row=1, column=3)
# What the "add" button does
def AddMember(self):
self.people.append([self.inputName.get(), self.inputID.get(), self.inputTLF.get()]) #Add textbox-text to list
self.entries += 1
self.updateMembers()
def updateMembers(self): # Display new member
# This is declared to make sure that self.entries is assigned by value, and not by index
entry = self.entries
# Add the new name from 'people' to the list of name entries, and display
self.names.append(tk.Label(self, text=self.people[entry][0], borderwidth=4))
self.names[entry].grid(row=entry + 2, column=0)
# -//- but with ids
self.id.append(tk.Label(self, text=self.people[entry][1], borderwidth=4))
self.id[entry].grid(row=entry + 2, column=1)
# -//- but with phone numbers
self.tlf.append(tk.Label(self, text=self.people[entry][2], borderwidth=4))
self.tlf[entry].grid(row=entry + 2, column=2)
# Create a frame to but multiple buttons in one grid-cell
self.frames.append(tk.Frame(self))
self.frames[entry].grid(row=entry + 2, column=3)
#Create such buttons
removeButton = tk.Button(self.frames[entry], text="X", command=lambda: self.remove(entry))
msgButton = tk.Button(self.frames[entry], text="SMS", command=lambda: self.sendSMS(entry))
callButton = tk.Button(self.frames[entry], text="Ring", command=lambda: self.makeCall(entry))
#Display such buttons
removeButton.pack(side='top')
callButton.pack(side = 'right')
msgButton.pack(side='left')
def sendSMS(self, sender_id):
print("SMSMSMSM")
def makeCall(self, sender_id):
print("RINGRINGRING")
def remove(self, sender_id):
print("")
print(self.entries)
self.people.pop(sender_id) # Remove from the "People" list
if self.entries >= 0:
# Un-display the lowest entry
self.tlf[self.entries].destroy()
self.frames[self.entries].destroy()
self.id[self.entries].destroy()
self.names[self.entries].destroy()
for i in range(self.entries): # RE-display all current entries (deleted one excluded)
tk.Label(self, text=self.people[i][0], borderwidth=4).grid(row=i + 2, column=0)
tk.Label(self, text=self.people[i][1], borderwidth=4).grid(row=i + 2, column=1)
tk.Label(self, text=self.people[i][2], borderwidth=4).grid(row=i + 2, column=2)
# Remove deleted user's info in the display lists.
self.names.pop(sender_id)
self.id.pop(sender_id)
self.tlf.pop(sender_id)
self.frames.pop(sender_id)
self.entries -= 1 # Decrement size of people
print(self.entries)
#Actually start the program
root = tk.Tk()
app = Application(master=root)
app.mainloop()
I have been troubleshooting this for hours on end, and have not managed to solve this, so any help is appreciated :D

problem with tkinter under defined function

Can you please help me with follwing issue I face:
When I am creating radiobutton with tkinter, I don't have a problem to select from the list.
However, if I put the same script under a menu, then selected option is always the default one, ("Python",1) in this specific case. Do you have any idea how to overcome this? Thanks in advance!
import tkinter as tk
root_m = tk.Tk()
root_m.geometry("400x200")
frame_m = tk.Frame(root_m)
root_m.title("NUMERIC UNIVERSE")
frame_m.pack()
def chars_merging():
languages = [
("Python",1),
("Perl",2),
("Java",3),
("C++",4),
("C",5)
]
root = tk.Tk()
root.geometry("400x200")
frame = tk.Frame(root)
root.title("SELECT SOMETHING")
frame.pack()
v = tk.IntVar()
v.set(0) # initializing the choice, i.e. Python
label = tk.Label(frame,
text="""Choose your favourite
programming language:""",
justify = tk.LEFT,
padx = 20)
label.pack()
def ShowChoice():
global data_sel
data_sel = v.get()
print(data_sel)
for val, language in enumerate(languages):
tk.Radiobutton(frame,
text=language,
indicatoron = 0,
width = 20,
padx = 20,
variable=data_sel,
command=ShowChoice,
value=val).pack(anchor=tk.W)
root.mainloop()
#return(languages[v.get()])
print("You selected", languages[v.get()])
button3 = tk.Button(frame_m,
text="3.Prepare and merge chars",
command=chars_merging,
width=25)
button3.pack()
# CLOSING THE WINDOW ---------------------------------------------------------
def finish():
root_m.destroy()
button_n = tk.Button(frame_m,
text="Finish",
command=finish,
width=25)
button_n.pack()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
root_m.mainloop()

Python/Tkinter: How to reduce the size of the expanded frames to their first positions?

According to the below codes; when the application is first run, two buttons display on the screen. If the user click one of the buttons, the frame is expanded and new buttons can be seen. If the user click the new buttons, another frame is expanded and new buttons can be seen again.
For example if the user first clicks the "English" button, the "Expand" button can be seen. And if the user click the "Expand" button, "Data" button can be seen. After that if the user click the "Turkish" button, the "Expand" button changes to "Genişlet" but the "Data" button still keeps on displaying, finally if the user clicks the "Genişlet" button, the "Data" button changes to "Veri".
But the above operation is not what i want to do. I want to change the "Veri" or "Data" buttons by clicking the "English" or "Turkish" buttons.
So, in order to do that, which parts of the codes i should modify? Thank you in advance.
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(row=0, column=0, sticky="nsew")
self.b1 = tk.Button(master=self, text="Turkish", width=20)
self.b1.grid(row=0, column=0)
self.b2 = tk.Button(master=self, text="English", width=20)
self.b2.grid(row=0, column=1)
self.f1 = tk.Frame(master=master)
self.f1.grid(row=1, column=0)
self.f2 = tk.Frame(master=master)
self.f2.grid(row=2, column=0)
self.f3 = tk.Frame(master=self.f1)
self.f4 = tk.Frame(master=self.f1)
self.b3 = tk.Button(master=self.f3, text="Genişlet")
self.b3.grid(row=0, column=0)
self.b4 = tk.Button(master=self.f4, text="Expand")
self.b4.grid(row=0, column=0)
self.f5 = tk.Frame(master=self.f2)
self.f6 = tk.Frame(master=self.f2)
self.b5 = tk.Button(master=self.f5, text="Veri")
self.b5.grid(row=0, column=0)
self.b6 = tk.Button(master=self.f6, text="Data")
self.b6.grid(row=0, column=0)
self.configure_buttons()
#staticmethod
def activate(frame, parent):
for child in parent:
child.grid_forget()
frame.grid(row=0, column=0)
def configure_buttons(self):
self.b1.configure(command=lambda: self.activate(self.f3, self.f1.winfo_children()))
self.b2.configure(command=lambda: self.activate(self.f4, self.f1.winfo_children()))
self.b3.configure(command=lambda: self.activate(self.f5, self.f2.winfo_children()))
self.b4.configure(command=lambda: self.activate(self.f6, self.f2.winfo_children()))
if __name__ == "__main__":
root = tk.Tk()
frame = App(master=root)
frame.mainloop()
Here is an example that keeps the functionality you currently have while being able to apply the language changes using textvariable and stringVar()
There is a better way I am sure but for this simple program this should suffice.
I created two variables set to a StringVar() The first 2 buttons are linked to a function/method that will change the strings for each stringVar to reflect the language choice.
I also created some place holder variables to use until the other buttons needed to be created. Let me know what you think of this option.
Update: I added a menu that will remove all the buttons except for the starting 2 buttons. Effectively a restart.
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master = master
self.btn1_text = tk.StringVar()
self.btn1_text.set("Expand")
self.btn2_text = tk.StringVar()
self.btn2_text.set("Data")
self.second_frame = "None"
self.btn2 = "None"
self.master.columnconfigure(0, weight = 1)
self.top_frame = tk.Frame(self.master)
self.top_frame.grid(row = 0, column = 0, sticky = "ew")
self.turkish_button = tk.Button(self.top_frame, text="Turkish", width=20, command = lambda: self.change_lang_and_add_btn1("turkish"))
self.turkish_button.grid(row=0, column=0)
self.english_button = tk.Button(self.top_frame, text="English", width=20, command = lambda: self.change_lang_and_add_btn1("english"))
self.english_button.grid(row=0, column=1)
self.menu = tk.Menu(self.master)
self.master.config(menu = self.menu)
self.file_menu = tk.Menu(self.menu, tearoff = 0)
self.menu.add_cascade(label = "File", menu = self.file_menu)
self.file_menu.add_command(label = "Reset", command = self.reset_buttons)
def change_lang_and_add_btn1(self, choice):
if choice == "english":
self.btn1_text.set("Expand")
self.btn2_text.set("Data")
if choice == "turkish":
self.btn1_text.set("Genişlet")
self.btn2_text.set("Veri")
if self.second_frame == "None":
self.second_frame = tk.Frame(self.master)
self.second_frame.grid(row = 1, column = 0, columnspan = 2)
self.btn1 = tk.Button(self.second_frame, textvariable = self.btn1_text, width=20, command = lambda: self.add_btn2())
self.btn1.grid(row = 1, column = 0, columnspan = 2)
def add_btn2(self):
if self.btn2 == "None":
self.btn2 = tk.Button(self.second_frame, textvariable = self.btn2_text, width=20)
self.btn2.grid(row = 2, column = 0, columnspan = 2)
def reset_buttons(self):
if self.second_frame != "None":
self.second_frame.destroy()
self.second_frame = "None"
self.btn2 = "None"
if __name__ == "__main__":
root = tk.Tk()
frame = App(root)
frame.mainloop()

How to store values from an Entry widget for loop in tkinter?

This should be a very very simple problem. I'm making a GUI in which I have multiple entry widgets... about 30 or so all in one column. Instead of making each box one by one it seems like a better idea to just generate the widgets with a loop. However, I'm finding it extremely difficult to .get() values from the entry widgets, and convert them into floats. This is what I have so far... any help would be greatly appreciated.
class Application(Frame):
def __init__(root,master):
Frame.__init__(root,master)
root.grid()
root.create_widgets()
def calcCR(root):
d1 = root.enter.get()
d1 = float(d1)
#root.answer.delete(0.0,END)
a = 'The C/R Alpha is! %lf \n' % (d1)
root.answer.insert(0.0, a)
def create_widgets(root):
### Generate Element List ###
for i in range(len(elem)):
Label(root, text=elem[i]).grid(row=i+1, column=0)
### Generate entry boxes for element wt% ###
for i in range(len(elem)):
enter = Entry(root, width = 8)
enter.grid(row = i+1,column=1)
enter.insert(0,'0.00')
root.button = Button(root, text = 'Calculate C/R', command = root.calcCR)
root.button.grid(row=11, column=2, sticky = W, padx = 10)
root.answer = Text(root, width = 50, height = 12.5, wrap = WORD)
root.answer.grid(row=1, column=2, rowspan = 10, sticky = W, padx = 10)
root = Tk()
root.title('C/R Calculator')
app = Application(root)
root.mainloop()
Put the Entry instances into a list.
from tkinter import Tk, Frame, Label, Entry, Button
class App(Frame):
def __init__(root, master):
Frame.__init__(root, master)
root.grid()
root.create_widgets()
def get_values(root):
return [float(entry.get()) for entry in root.entries]
def calc_CR(root):
answer = sum(root.get_values()) #Replace with your own calculations
root.answer.config(text=str(answer))
def create_widgets(root):
root.entries = []
for i in range(20):
label = Label(root, text=str(i))
label.grid(row=i, column=0)
entry = Entry(root, width=8)
entry.grid(row=i, column=1)
entry.insert(0, '0.00')
root.entries.append(entry)
root.calc_button = Button(root, text='Calculate C/R', command=root.calc_CR)
root.calc_button.grid(row=20, column=0)
root.answer = Label(root, text='0')
root.answer.grid(row=20, column=1)
def run(root):
root.mainloop()
root = Tk()
root.title('C/R Calculator')
app = App(root)
app.run()

Unable to achieve wanted entry textBox alignment

HI i am trying to place the alignment of my Entry(Text Box) according to the image below. I tried everything, TOP BOTTOM LEFT RIGHT.
This is the alignment i want. Obtained from paint program*
Problem
Coding of tkinter
master = Tk.Tk() # Open up GUI connection
master.title('Program Application')
print "VSM activated input range first (X2 must be larger than X1)"
#Declare button and respective method
button = Tk.Button(text='VSM', command=VSM, fg="red")
button.config( height = 10, width = 80 )
button.pack() #pack is needed to display the button
bluebutton = Tk.Button(text="AGM Folder",command= lambda: Folder(0), fg="blue").pack(side = LEFT)
bluebutton = Tk.Button(text="VSM Folder",command= lambda: Folder(1), fg="blue").pack(side = RIGHT)
Label(text='Correct Range for Gradient\nX2 X1').pack(side=TOP,padx=10,pady=10)
entryX2 = Entry(master, width=10)
entryX2.pack(side=LEFT,padx=10,pady=10)
entryX1 = Entry(master,width=10)
entryX1.pack(side=RIGHT,padx=10,pady=10)
buttonGradient = Tk.Button(text='Input Range OP',command= lambda: Folder(2), fg="red").pack()
entryX2IP = Entry(master, width=10)
entryX2IP.pack(side=LEFT,padx=10,pady=10)
entryX1IP = Entry(master,width=10)
entryX1IP.pack(side=RIGHT,padx=10,pady=10)
btnGradientIP = Tk.Button(text='Input Range IP',command= lambda: Folder(2), fg="red").pack(side = TOP)
master.mainloop() # Continue loop till user close tab
Use Frame:
master = Tk.Tk() # Open up GUI connection
master.title('Program Application')
print "VSM activated input range first (X2 must be larger than X1)"
#Declare button and respective method
button = Tk.Button(text='VSM', command=VSM, fg="red")
button.config( height = 10, width = 80 )
button.pack() #pack is needed to display the button
bluebutton = Tk.Button(text="AGM Folder",command= lambda: Folder(0), fg="blue").pack(side = LEFT)
bluebutton = Tk.Button(text="VSM Folder",command= lambda: Folder(1), fg="blue").pack(side = RIGHT)
Label(text='Correct Range for Gradient\nX2 X1').pack(side=TOP,padx=10,pady=10)
################### Use 3 frames to contains entries, buttons.
frameX2 = Frame(master)
frameX2.pack(side=LEFT, expand=1, anchor=E)
entryX2 = Entry(frameX2, width=10)
entryX2.pack(side=TOP,padx=10,pady=10)
entryX2IP = Entry(frameX2, width=10)
entryX2IP.pack(side=TOP,padx=10,pady=10)
frameButton = Frame(master)
frameButton.pack(side=LEFT)
Tk.Button(frameButton, text='Input Range OP',command= lambda: Folder(2), fg="red").pack(padx=10, pady=10)
Tk.Button(frameButton, text='Input Range IP',command= lambda: Folder(2), fg="red").pack(padx=10, pady=10)
frameX1 = Frame(master)
frameX1.pack(side=LEFT, expand=1, anchor=W)
entryX1 = Entry(frameX1,width=10)
entryX1.pack(side=TOP,padx=10,pady=10)
entryX1IP = Entry(frameX1,width=10)
entryX1IP.pack(side=TOP,padx=10,pady=10)
#####################
master.mainloop() # Continue loop till user close tab

Categories