I'm trying to do is to make a listbox using a Treeview widget. The listBox is successfully created BUt i don't understand how to export data from entry widget to listbox and i need to REMOVE button for listbox content. the program is working successfully.
from tkinter import ttk
import tkinter as tk
def update_sum(first_number_tk, second_number_tk, sum_tk) :
# Sets the sum of values of e1 and e2 as val of e3
try:
sum_tk.set((float(first_number_tk.get().replace(' ', '')) + float(second_number_tk.get().replace(' ', ''))))
except :
pass
root.after(10, update_sum, first_number_tk, second_number_tk, sum_tk) # reschedule the event
return
root = tk.Tk()
root.geometry('1000x600')
e1_tk = tk.StringVar(root) # Initializes a text variable of tk to use to get e1's val.
e2_tk = tk.StringVar(root) # Initializes a text variable of tk to use to get e2's val.
sum_tk = tk.StringVar(root) # Initializes a text variable of tk to use to set e3's val.
# Entries
e1 = tk.Entry(root, textvariable = e1_tk)
e1.grid(row=1,column=1)
e2 = tk.Entry(root, textvariable = e2_tk)
e2.grid(row=1,column=2)
e3 = tk.Entry(root, textvariable = sum_tk)
e3.grid(row=1,column=3)
e4=tk.Label(root,text="SL")
e4.grid(row=1,column=0)
e3_tk = tk.StringVar(root) # Initializes a text variable of tk to use to get e1's val.
e4_tk = tk.StringVar(root) # Initializes a text variable of tk to use to get e2's val.
sum2_tk = tk.StringVar(root) # Initializes a text variable of tk to use to set e3's val.
# Entries
e5 = tk.Entry(root, textvariable = e3_tk)
e5.grid(row=2,column=1)
e6 = tk.Entry(root, textvariable = e4_tk)
e6.grid(row=2,column=2)
e7 = tk.Entry(root, textvariable = sum2_tk)
e7.grid(row=2,column=3)
e8=tk.Label(root,text="DR")
e8.grid(row=2,column=0)
cols = ('name', 'No1', 'No2', 'total sum')
listBox = ttk.Treeview(root, columns=cols, show='headings')
for col in cols:
listBox.heading(col, text=col)
listBox.grid(row=1, column=0, columnspan=2)
listBox.place(x=10, y=300)
# Will update the sum every second 10 ms = 0.01 second it takes ms as arg.
root.after(10, update_sum, e1_tk, e2_tk, sum_tk)
root.after(10, update_sum, e3_tk, e4_tk, sum2_tk)
root.mainloop()
Thanks in Advance..
You can just add two new button and two new function, like:
b = tk.Button(root,text='Update Listbox',command=update)
b.grid(row=3)
b1 = tk.Button(root, text='Delete Items', command=delete)
b1.grid(row=4)
and then the update() could be something like:
def update():
listBox.insert('','end',value=('SOME NAME', float(e1.get()),float(e2.get()),float(e3.get())))
listBox.insert('', 'end', value=('SOME NAME', float(e5.get()), float(e6.get()), float(e7.get())))
and then delete() to be something like:
def delete():
selected_item = listBox.selection()[0] # get selected item
listBox.delete(selected_item)
For the delete() to work properly, you have to click on the item you want to delete and then click on delete button
The value argument is the only place where you will have to make the necessary changes.
Hope it cleared your doubt, do let me know if any more errors or doubt.
Cheers
Related
This program is being written in Tkinter. I am writing a program that will have multiple entry boxes where the user will input certain parameters. I want there to be a single button that saves all the entries from all the entry boxes to be used later by another part of my program. At this moment, the entry boxes and the button are done but the button does not do anything. How could I go about making the button read and save all the entries? Thanks!
You just need to get the data in the Entries and store them as variables, inside functions and globalize those variables. After that just call all the functions in a separate function. And then give this function as a command to the button.
import tkinter as tk
root = tk.Tk()
e_1 = tk.Entry(root)
e_1.pack()
e_2 = tk.Entry(root)
e_2.pack()
e_3 = tk.Entry(root)
e_3.pack()
var_1 = 0
var_2 = 0
var_3 = 0
def func_1():
global var_1
var_1 = e_1.get()
def func_2():
global var_2
var_2 = e_2.get()
def func_3():
global var_3
var_3 = e_3.get()
def store_all():
func_1()
func_2()
func_3()
print(var_1)
print(var_2)
print(var_3)
b = tk.Button(root, text="get", width=10, command=store_all)
b.pack()
root.mainloop()
I have used print() inside the function to confirm to you that the values are stored successfully. You can just remove those.
Here is an example of a program that reads contents of one Entry and prints it:
https://effbot.org/tkinterbook/entry.htm#patterns
Below you can find code in python 3:
from tkinter import *
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
def callback():
print(e.get())
b = Button(master, text="get", width=10, command=callback)
b.pack()
mainloop()
Just add more Entry widgets and read them all in the callback method.
i have tried most things possible here but could get it to work. any help would be highly appreciated.
I want the users to select the dates AND THEN get theose values, storeit in a and b, find the difference, and store it in y.
But what is actually happening is, when i call cal_fun1, it gets the value of b even before allowing the user selection.
how can i change this? Also i need the value to be stored in L3, as the difference.
from tkinter import *
from tkcalendar import Calendar, DateEntry
def pay_cal():
def cal_fun():
t = Toplevel()
global cal
cal = Calendar(t, year=2019, month=6, day=1, foreground='Blue', background='White', selectmode='day')
cal.pack()
cal.bind("<<CalendarSelected>>",lambda e: c.set(cal.get_date()))#make use of the virtual event to dynamically update the text variable c
def cal_fun1():
t = Toplevel()
global cal1, y
cal1 = Calendar(t, foreground='Blue', background='White', selectmode='day')
cal1.pack()
cal1.bind("<<CalendarSelected>>", lambda e: d.set(cal1.get_date()) ) # make use of the virtual event to dynamically update the text variable c
a=cal.selection_get()
b=cal1.selection_get()
y =a-b
print(y) #this is only for testing the output
sub_win = Tk()
sub_win.geometry('400x500+600+100')
sub_win.title('Payout Calculator')
c = StringVar() #create a stringvar here - note that you can only create it after the creation of a TK instance
c.set(0)
d = StringVar() # create a stringvar here - note that you can only create it after the creation of a TK instance
d.set(0)
y = StringVar()
l1 = Button(sub_win, text= 'Check-In Date:', command= cal_fun)
chck_in_date = Label(sub_win, textvariable=c)
l1.grid(row=1)
chck_in_date.grid(row=1, column=2)
l2 = Button(sub_win, text='Can Date:', command=cal_fun1)
q = Label(sub_win, textvariable=d)
l2.grid(row=2)
q.grid(row=2, column=2)
total_days = Label(sub_win, textvariable= y.get())
L3 = Label(sub_win, text="Total Days")
L3.grid(row=3)
total_days.grid(row=3, column=2)
sub_win.mainloop()
pay_cal()
I've successfully looped the textvariable for all the entries created to point to DoubleVar(), and its working properly. The problem arose when i tried creating reset button for all the entries. from my code as shown, the program runs, doesn't raise any error, and the values in the entries are not cleared. thanks in advance :)
from tkinter import*
root = Tk()
img = PhotoImage(file = 'background.png')
cc = DoubleVar()
cc.set('##')
dr =Label(root, text='helo world')
sd = []
y = -1
dr.pack()
Entry(root, textvariable =cc).pack()
def clear():
cc.set('')
for i in sd:
i['textvariable'] = DoubleVar().set('')
def create():
global y
y +=1
sd.append(Entry(root, width =5))
for i in sd:
i["textvariable"] = DoubleVar()
sd[y].pack()
Button(root, text = 'push', command = clear).pack()
Button(root, text = 'create', command = create).pack()
root.mainloop()
`
Your reset code is creating new DoubleVars, and setting them to the empty string. You're doing nothing to the original variables.
You don't need to use the variables for this, you can simply call the delete method on each entry widget:
for entry in sd:
entry.delete(0, "end")
I am trying to make a GUI text based adventure game in python. I want to be able to take text from a textinput box and store it as string variable.
I have 2 problems:
Making the python wait for the submit button to be pressed, before
processing the input and updating the game.
Getting the text variable out of the command, I would like to not
use global if possible.
Here is some of my code to better understand:
root = tk.Tk()
root.geometry('800x600+100+100')
root.title("my game")
textbox = tk.StringVar()
textboxentry = tk.Entry(root, textvariable=textbox, bd=5, width = "40", font=("times", 20))
textboxentry.pack(in_=bgImageLabel, side = "bottom")
def getInput():
textboxInput = textbox.get() #gets entry
lengthEntry = len(textbox.get())
textboxentry.delete(0,lengthEntry) #removes entry from widget
return textboxInput # I would like this return to work
submit = tk.Button(root, text ="Submit", command = (textboxInput = getInput()))
##I want the command function to use command = getInput and store the return on getInput as textboxInput. This will update the wait_variable down below, and give the inputs(textboxInput) a string to work with.
submit.pack(in_=bgImageLabel, side = "bottom")
while game == True:
root.update_idletasks()
root.update()
submit.wait_variable(textboxentry)
## I need it to wait before proceeding to this next line because i need the textboxInput from the entry widget.
actionInput, extraInput, texts = inputs(textboxInput)
Currently I can't figure a way to use command = (textboxInput = getInput), using lambda or anything else. I just want to store the return which comes off of the Entry as a string variable that can be used by the main function.
All help is appreciated!
Below code processes entry widget's text when Submit button is pressed.
import tkinter as tk
root = tk.Tk()
aVarOutside = 'asd'
def btn_cmd(obj):
#use global variable
global aVarOutside
#print its unmodified value
print("aVarOutside: " + aVarOutside)
#modify it with what's written in Entry widget
aVarOutside = obj.get()
#modify lblTextVar, which is essentially modifying Label's text as lblTextVar is its textvariable
lblTextVar.set(obj.get())
#print what's inside Entry
print("Entry: " + obj.get())
txt = tk.Entry(root)
txt.pack()
lblTextVar = tk.StringVar()
lbl = tk.Label(root, textvariable=lblTextVar)
lbl.pack()
btn = tk.Button(text="Submit", command=lambda obj = txt : btn_cmd(obj))
btn.pack()
root.mainloop()
When the button is pressed:
Value of a global variable, aVarOutside is printed.
Value of aVarOutside is modified to the value of Entry box's
(txt's) content.
Value of a textvariable used by a label (lbl) is modified. Which
means that the text of lbl is updated and can be seen on the GUI.
Finally Entry box, txt's content is printed.
I think you should use inputs() inside getInputs() and then button doesn't have to return any variables - and then you can use root.mainloop() instead of while loop.
import tkinter as tk
# --- functions ---
def inputs(text):
# do something with text
print(text)
# and return something
return 'a', 'b', 'c'
def get_input():
global action_input, extra_input, texts
text = textbox.get()
if text: # check if text is not empty
textbox.set('') # remove text from entry
#textbox_entry.delete(0, 'end') # remove text from entry
action_input, extra_input, texts = inputs(text)
# --- main ---
root = tk.Tk()
textbox = tk.StringVar()
textbox_entry = tk.Entry(root, textvariable=textbox)
textbox_entry.pack()
submit = tk.Button(root, text="Submit", command=get_input)
submit.pack()
root.mainloop()
BTW: you could better organize code
all functions before main part (root = tk.Tk())
PEP8 suggests to use lower_case_names for functions and variables (instead of CamelCaseNames)
global is not prefered method but I think it is better solution than yours.
If you don't need global then you can use classes with self.
import tkinter as tk
# --- classes ---
class Game:
def __init__(self):
self.root = tk.Tk()
self.textbox = tk.StringVar()
self.textbox_entry = tk.Entry(self.root, textvariable=self.textbox)
self.textbox_entry.pack()
self.submit = tk.Button(self.root, text="Submit", command=self.get_input)
self.submit.pack()
def run(self):
self.root.mainloop()
def inputs(self, text):
# do something with text
print(text)
# and return something
return 'a', 'b', 'c'
def get_input(self):
text = self.textbox.get()
if text: # check if text is not empty
self.textbox.set('') # remove text from entry
#textbox_entry.delete(0, 'end') # remove text from entry
self.action_input, self.extra_input, self.texts = self.inputs(text)
# --- functions ---
# empty
# --- main ---
app = Game()
app.run()
So I've been working on this program and I'm finding it very hard to figure out what's wrong. I'm fairly new to tkinter so this may be quite minor.
I'm trying to get the program to change the entry box's background colour when the check button is pressed. Or even better if somehow I can change it dynamically it would be even better.
This is my code at the moment:
TodayReading = []
colour = ""
colourselection= ['green3', 'dark orange', "red3"]
count = 0
def MakeForm(root, fields):
entries = []
for field in fields:
row = Frame(root)
lab = Label(row, width=15, text=field, font=("Device",10, "bold"), anchor='center')
ent = Entry(row)
row.pack(side=TOP, padx=5, fill=X, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((field, ent))
return entries
def SaveData(entries):
import time
for entry in entries:
raw_data_point = entry[1].get()
data_point = (str(raw_data_point))
TodayReading.append(data_point)
c.execute("CREATE TABLE IF NOT EXISTS RawData (Date TEXT, Glucose REAL, BP INTEGER, Weight INTEGER)")
c.execute("INSERT INTO RawData (Date, Glucose, BP, Weight) VALUES (?, ?, ?, ?)", (time.strftime("%d/%m/%Y"), TodayReading[0], TodayReading[1] , TodayReading[2]))
conn.commit()
conn.close()
def DataCheck():
if ((float(TodayReading[0])>=4 and (float(TodayReading[0])<=6.9))):
colour = colourselection[count]
NAME OF ENTRY BOX HERE.configure(bg=colour)
Thanks for the help. Someone may have answered it already but like i said I'm new to tkinter so if i've seen it already, I haven't figured out how to implement it.
Please see my example below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.var = StringVar() #creates StringVar to store contents of entry
self.var.trace(mode="w", callback=self.command)
#the above sets up a callback if the variable containing
#the value of the entry gets updated
self.entry = Entry(self.root, textvariable = self.var)
self.entry.pack()
def command(self, *args):
try: #trys to update the background to the entry contents
self.entry.config({"background": self.entry.get()})
except: #if the above fails then it does the below
self.entry.config({"background": "White"})
root = Tk()
App(root)
root.mainloop()
So, the above creates an entry widget and a variable which contains the contents of that widget.
Every time the variable is updated we call command() which will try to update the entry background colour to the contents of the entry (IE, Red, Green, Blue) and except any errors, updating the background to White if an exception is raised.
Below is a method of doing this without using a class and using a separate test list to check the value of the entry:
from tkinter import *
root = Tk()
global entry
global colour
def callback(*args):
for i in range(len(colour)):
if entry.get().lower() == test[i].lower():
entry.configure({"background": colour[i]})
break
else:
entry.configure({"background": "white"})
var = StringVar()
entry = Entry(root, textvariable=var)
test = ["Yes", "No", "Maybe"]
colour = ["Red", "Green", "Blue"]
var.trace(mode="w", callback=callback)
entry.pack()
root.mainloop()