Related
In my code, I have tried to get the user input through text fields, store them in variables and finally print them in a tabular form.
The problem I am facing is that none of the values I enter through the text fields get displayed; when I try printing the variables, they come up empty.
Here's part of my code:
# SPASC
from tkinter import *
import tkinter as tk
import tkinter.ttk as tktrv
root = tk.Tk()
root.title("SPASC")
root.geometry("410x400")
lb1 = Label(root, text="SPASC \n Welcomes You !!!", fg="red", bg="sky blue"
, font=('Arial Black', 20), width=22, anchor=CENTER)
lb2 = Label(root, text="What would you like to compare?",
font=('Arial', 18), anchor=CENTER)
space1 = Label(root, text="\n\n")
lb1.grid(row=0)
lb2.grid(row=5)
space1.grid(row=1)
hpw, mil = StringVar(), StringVar()
def bt_cars():
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hpw_cb = Checkbutton(fr1, text="Horsepower", variable=hpw, anchor='w', onvalue="Horsepower", offvalue="")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mil, anchor='w', onvalue="Mileage", offvalue="")
mil_cb.grid()
mil_cb.deselect()
var_stor = [hpw, mil]
print(hpw)
print(mil)
var_fill = []
for itr1 in var_stor:
if itr1 != "":
var_fill.append(itr1)
print(var_fill)
def car_1():
name1 = StringVar()
c1 = Toplevel()
c1.title("Car 1")
c1.geometry("430x200")
car1_lb1 = Label(c1, text="Car Name:")
name1_ifl = Entry(c1)
name1 = name1_ifl.get()
elm_var_fill = len(var_fill)
ct1 = 0
car1_val = []
for itr2 in var_fill:
if ct1 == elm_var_fill:
break
lb5 = Label(c1, text=itr2.get())
#Creating text field
ftr1_ifl = Entry(c1)
car1_ftr = ftr1_ifl.get()
car1_val.append(car1_ftr)
car1_ftr = None
lb5.grid(row=ct1 + 2, column=1)
ftr1_ifl.grid(row=ct1 + 2, column=2)
ct1 += 1
print(car1_val)
def display():
dp = Toplevel()
dp.title("Results")
dp.geometry("500x200")
car1_pt = 0
car2_pt = 0
car_tree = tktrv.Treeview(dp)
car_tree["columns"] = ("car1col")
car_tree.column("#0", width=120, minwidth=30)
car_tree.column("car1col", width=120, minwidth=30)
car_tree.heading("#0", text="Features" )
car_tree.heading("car1col", text=str(name1))
car_tree.pack()
c1.withdraw()
print(var_fill)
done1_bt = Button(c1, text="Continue", command=display)
name1_ifl.grid(row=0, column=2)
car1_lb1.grid(row=0, column=1)
done1_bt.grid(row=5,column=1)
w1.withdraw()
done_bt = Button(w1, text="Done", command=car_1)
done_bt.grid(row=3, column=1)
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
root.mainloop()
I am facing trouble with the variables named: hpw, mil, name1.
Any help would be welcome.
NOTE:- Please excuse the amount of code; I wanted others to replicate the error and see it for themselves
For the variables hpw and mil, these variables are empty strings that's why you are not getting any value from those checkboxes. To get values from the checkboxes replace these lines of code:
var_stor = [hpw, mil]
with
var_stor = [hpw_cb.cget('onvalue'), mil_cb.cget('onvalue')]
since you want the onvalue then you must use cget() method to access those values.
also, replace
lb5 = Label(c1, text=itr2.get())
with
lb5 = Label(c1, text=itr2)
because now you have required values (not objects) in a list, so just need to access those values.
For the variable name1 you can use #BokiX's method.
The problem is you are using get() wrong. You cannot use get() right after Entry() because as soon as entry is created it's getting the input before the user can even input something.
Use this code:
def get_input(text):
print(text)
e = Entry(root)
e.pack()
b = Button(root, text="Print input", command=lambda: get_input(e.get()))
b.pack()
Now get() method will not be executed before you click the button.
I've wracked my brain about this. I'm new to Python and Tk,and just trying it out. I would think this would be really easy, but I can't get it. Here's my code:
from tkinter import *
window = Tk()
window.geometry = ('400x200')
mylabel = Label(window)
def button_command():
Label(window).destroy()
text = entry1.get()
selection=variable.get()
if selection == "Celsius":
f = "Fahrenheit: " + str(round((int(text) - 32) * 5/9,2))
mylabel = Label(window, text = f).pack()
else:
c = "Celsuius: " + str(round((int(int(text)) * 9/5) + 32))
mylabel = Label(window, text = c).pack()
return None
def clear_label():
mylabel.destroy()
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
w.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
window.mainloop()
I don't get an error, but the clear_label function doesn't do anything. It doesn't return an error. It just doesn't work. Any suggestions would be appreciated. :)
You never actually packed the label into the window, therefore there was nothing to destroy. If you run this code, you can see that once packed, your function works as expected.
from tkinter import *
window = Tk()
window.geometry = ('400x200')
mylabel = Label(window, text="test")
def button_command():
Label(window).destroy()
text = entry1.get()
selection=variable.get()
if selection == "Celsius":
f = "Fahrenheit: " + str(round((int(text) - 32) * 5/9,2))
mylabel = Label(window, text = f).pack()
else:
c = "Celsuius: " + str(round((int(int(text)) * 9/5) + 32))
mylabel = Label(window, text = c).pack()
return None
def clear_label():
mylabel.destroy()
mylabel.pack
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
mylabel.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
window.mainloop()
Not sure whether the aim of the exercise is to destroy a label or just clear the label and give it a new value. If it is the latter, it can be achieved using the text variable parameter to label.
from tkinter import *
def button_command():
text = entry1.get()
selection=variable.get()
# Change the value of the stringvar to set the new value
if selection == "Celsius":
labelvalue.set("Fahrenheit: " + str(round((int(text) - 32) * 5/9,2)))
else:
labelvalue.set("Celsuius: " + str(round((int(int(text)) * 9/5) + 32)))
return None
def clear_label():
# No need to destroy - just change the value
labelvalue.set("")
window = Tk()
window.geometry = ('400x200')
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
w.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
# The text displayed in mylabel will be the contents of labelvalue
labelvalue = StringVar()
mylabel = Label(window, textvariable=labelvalue)
mylabel.pack()
window.mainloop()
In principle, you don't have to delete and re-create the Label, just clear the fields in the Label and in the Entry:
def clear_label():
mylabel.config(text="")
entry1.delete(0, 'end')
I work on a program that calculates the macros of each meal. You can enter a value in gram and it calculates for each aliment your intake. I would like now to add these values together when I push multiple buttons. Then I'll display the value somewhere and maybe I could do a graph after.
Here I show what my program looks like :
import tkinter as tk
def value_kiwi():
value = ent_quantity.get()
formula = (float(value)/100)
cal = 53
pro = 1.6
glu = 11.1
li = 0.3
Calories = (cal) * formula
Protéines = (pro) * formula
Glucides = (glu) * formula
Lipides = (li) * formula
lbl_cal["text"] =f"{Calories}"
lbl_prot["text"] = f"{Protéines}"
lbl_glu["text"] = f"{Glucides}"
lbl_lip["text"] = f"{Lipides}"
def value_banane():
value = ent_quantity.get()
formula = (float(value)/100)
cal = 90
pro = 1.5
glu = 20.1
li = 0
Calories = (cal) * formula
Protéines = (pro) * formula
Glucides = (glu) * formula
Lipides = (li) * formula
lbl_cal["text"] =f"{Calories}"
lbl_prot["text"] = f"{Protéines}"
lbl_glu["text"] = f"{Glucides}"
lbl_lip["text"] = f"{Lipides}"
window = tk.Tk()
window.title("Calculateur de Calories et Nutriments")
frm_entry = tk.Frame(master=window)
ent_quantity = tk.Entry(master=frm_entry, width=5)
ent_quantity.grid(row=1, column=0,)
lbl_cal = tk.Label(master=window)
lbl_cal.grid(row=1, column=1,)
lbl_prot = tk.Label(master=window)
lbl_prot.grid(row=1, column=2)
lbl_glu = tk.Label(master=window)
lbl_glu.grid(row=1, column=3)
lbl_lip = tk.Label(master=window)
lbl_lip.grid(row=1, column=4)
btn_kiwi = tk.Button(
master=window,
text="Kiwi",
command=value_kiwi,
)
btn_banane = tk.Button(
master=window,
text="Banane",
command=value_banane,
)
lbl_calories = tk.Label(master=window, text="Calories",)
lbl_proteines = tk.Label(master=window, text="Protéines")
lbl_glucides = tk.Label(master=window, text="Glucides")
lbl_lipides = tk.Label(master=window, text="Lipides")
lbl_fruits = tk.Label(master=window, text="Fruits")
frm_entry.grid(row=1, column=0, padx=10)
lbl_calories.grid(row=0,column=1, padx=5, sticky="w")
lbl_proteines.grid(row=0, column=2, padx=10)
lbl_glucides.grid(row=0, column=3, padx=10)
lbl_lipides.grid(row=0,column =4, padx=10)
lbl_fruits.grid(row=1,column =5, padx=10)
btn_kiwi.grid(row=2, column=5, pady=10)
btn_banane.grid(row=3, column=5, pady=10)
window.mainloop()
Ok, I think I improved Your code:
from tkinter import Tk, Button, Entry, Label
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
self.title('Nutrient calculator')
# entry
Label(self, text='Amount').grid(row=0, column=0)
self.amount = Entry(self, width=5, bg='light grey')
self.amount.grid(row=1, column=0)
# calories
Label(self, text='Calories').grid(row=0, column=1)
self.calories = Label(self)
self.calories.grid(row=1, column=1)
# proteins
Label(self, text='Proteins').grid(row=0, column=2)
self.proteins = Label(self)
self.proteins.grid(row=1, column=2)
# glucose
Label(self, text='Glucose').grid(row=0, column=3)
self.glucose = Label(self)
self.glucose.grid(row=1, column=3)
# lipids
Label(self, text='Lipids').grid(row=0, column=4)
self.lipids = Label(self)
self.lipids.grid(row=1, column=4)
# list of all labels
self.data_labels = [self.calories, self.proteins, self.glucose, self.lipids]
# error label for if no value is entered or it cannot be converted
self.error_label = Label(self, text='Use integer or float value!')
# stuff for adding multiple foods
self.do_add = False
self.nutrient_list = []
self.plus_btn = Button(self, text='Add', command=self.add)
self.plus_btn.grid(row=3, column=0, columnspan=4, sticky='nwes')
def display_values(self, value_list):
self.nutrient_list.append(value_list)
if len(self.nutrient_list) == 2 and not self.do_add:
self.nutrient_list.pop(0)
elif len(self.nutrient_list) > 2 and not self.do_add:
self.nutrient_list = [self.nutrient_list[-1]]
print(self.nutrient_list)
if self.do_add:
value_list = []
for i in range(len(self.nutrient_list[0])):
total_value = 0
for item in self.nutrient_list:
total_value += item[i]
value_list.append(total_value)
for text, label in zip(value_list, self.data_labels):
label.config(text=f'{text:.2f}')
self.do_add = False
def handle_value_error(self):
self.error_label.grid(row=2, column=0, columnspan=4)
def add(self):
self.do_add = True
self.amount.delete(0, 'end')
class Values:
def __init__(self, name, row, column, calories, proteins, glucose, lipids):
self.parent = root
self.name = name
self.row = row
self.column = column
self.calories = calories
self.proteins = proteins
self.glucose = glucose
self.lipids = lipids
self.stuff_list = [self.calories, self.proteins, self.glucose, self.lipids]
self.button = Button(self.parent, text=self.name, command=self.set_values)
self.button.grid(row=self.row, column=self.column, sticky='nwse')
def set_values(self):
value_list = []
value_ = self.parent.amount.get()
try:
formula = float(value_) / 100
self.parent.error_label.grid_forget()
for item in self.stuff_list:
item *= formula
value_list.append(item)
self.parent.display_values(value_list)
except ValueError:
self.parent.handle_value_error()
root = MainWindow()
kiwi = Values('Kiwi', 2, 4, calories=53, proteins=1.6, glucose=11.1, lipids=0.3)
banana = Values('Banana', 3, 4, calories=90, proteins=1.5, glucose=20.1, lipids=0)
root.mainloop()
it is not necessarily better however a few benefits from using this code are:
better organization (IMO) since it uses classes which make it pretty neat (however You have to have an understanding over them)
takes less space - what I mean is that now, to define a new food, You just have to initiate the Values class and give it the necessary arguments. You can take an example from the given instances.
possibly easier to expand (both because better organization and takes less space)
I edited the code so now it should have that functionality, the way it works is You choose an amount , then fruit and if You want to add more, press add button, then choose amount, press food and it will display the total so far, then again, if You want to add more press add and then put in an amount and press the fruit, currently the way to 'clear' is to press any food button and it should then reset the whole list and keep only the one that was just pressed and then repeat.
It got executed once but I add some features and now it doesn't work anymore...
I'm a beginner at python and this is my first project. I'd like to create a game (which works perfectly in the console) but I have some troubles to put it with tkinter
If someone could take a look at this, it would be nice, thanks
Here's my code, I might have mistyped something or I don't know but I'm stucked with this and I can't find the mistake.
import tkinter as tk
from tkinter import Tk, Label, Canvas, Button, Frame, Toplevel, Entry
from random import randrange
num = randrange(0, 50)
money = 100
root = Tk()
root.geometry("750x750")
root["bg"]="beige"
label = Label(root, text="Welcome to the Casino")
label.place(width=180, x=300, y=300)
def csn(x, y, z, i):
if y < 50 and y >= 0 and z <= i :
if y == x:
i += z * 3
return "Well guess. You have %d" %(i)
elif (x % 2 == 0 and y % 2 == 0) or ( x % 2 != 0 and y % 2 != 0):
i += z * 0.5
return "Not so ba. You have %d" %(i)
else:
i -= z
return "Oops, Try again, you loose %d. You now have %d" %(z, i)
else:
return "Try again..."
def submit(master):
label1 = Label(master, text="try again...")
label1.place(width=180, x=300, y=300)
def casino():
top = Toplevel()
top['bg']= 'blue'
top.geometry = ('700x700')
root.withdraw
while money > 0:
try:
number_label = Label(top, text="Chose a nombre : ")
number_label.place(width=180, x=100, y=300)
nentry= Entry(top)
nentry.place(width=180, x=200, y=300)
number = int(nentry.get())
mise_label = Label(top, text="Entre the price you want to mise : ")
mise_label.place(width=180, x=100, y=400)
mise_entry = Entry(top)
mise_entry.place(width=180, x=200, y=400)
mise = float(mise_entry.get())
except ValueError:
btn3 = Button(top, text="submit", command=lambda : submit(top))
btn3.place(width=180, x=300, y=300)
btn = Button(top, text="submit", command= lambda : csn(num, number, mise, money))
btn.place(width=180, x=300, y=500)
else:
label2= Label(top, text="you lose")
label2.place(width=180, x=300, y=500)
btn1 = Button(top, text="Quit", command=top.quit)
btn1.place(width=180, x=300, y=400)
btn2 = Button(top, text="try again", command=casino)
btn2.place(width=180, x=200, y=400)
enter code here
button = Button(root, text="play!", relief='groove', command=casino)
button.place(width=180, x=300, y=400)
root.mainloop()
https://github.com/Rodneyst/lv100roxas-gmail.com/blob/master/finalproject
Can look over the full code here. The link goes to the full code, I pull all the answer with one button using stringvar. Please answer I have 2 days left and haven't had any luck.
# Username widget
self.prompt_label5 = tkinter.Label(self.top_frame,
text='Enter your Name:' ,bg="red", fg="yellow", font="none 12 bold")
self.name_entry = tkinter.Entry(self.top_frame,
width=10)
# weight widget
self.prompt_label1 = tkinter.Label(self.top_frame,
text='Enter your weight(lbs):' ,bg="red", fg="yellow", font="none 12 bold")
self.weight_entry = tkinter.Entry(self.top_frame,
width=10)
def getworkout(self):
weight = float(self.weight_entry.get())
height = float(self.height_entry.get())
How would I validate these user inputs? Please help — I cannot figure it out. I want to get a pop-up window to show when the user inputs an integer for name and when they enter a string for weight and height, ValueErrors. Please help!
Code is messy, so make it look better :) But I think it does, what you asked about. I edited it in a hurry. Name also accept more signs then just letters (excluding integers) - it's easy to validate if necessery.
import tkinter
from tkinter import ttk
from tkinter import messagebox
import random
# GUI
class WorkoutGUI:
def __init__(self):
# Main window
self.main_window = tkinter.Tk()
self.main_window.title("Workout Generator")
self.main_window.geometry('1200x600')
# Frames
self.top_frame = tkinter.Frame()
self.mid_frame = tkinter.Frame()
self.bottom_frame = tkinter.Frame()
validation1 = self.top_frame.register(entry_validation_1)
validation2 = self.top_frame.register(entry_validation_2)
# TOP FRAME
# username widget
self.prompt_label1 = tkinter.Label(self.top_frame,
text='Enter your Name:', bg="red", fg="yellow", font="none 12 bold")
self.name_entry = tkinter.Entry(self.top_frame,
width=10, validate='key', validatecommand=(validation1, '%S'))
# weight widget
self.prompt_label2 = tkinter.Label(self.top_frame,
text='Enter your weight(lbs):', bg="red", fg="yellow", font="none 12 bold")
self.weight_entry = tkinter.Entry(self.top_frame,
width=10, validate='key', validatecommand=(validation2, '%S'))
# height widget
self.prompt_label3 = tkinter.Label(self.top_frame,
text='Enter your height(in):', bg="red", fg="yellow",
font="none 12 bold")
self.height_entry = tkinter.Entry(self.top_frame,
width=10, validate='key', validatecommand=(validation2, '%S'))
# gender widget
self.prompt_label4 = tkinter.Label(self.top_frame,
text='Select your gender:', bg="red", fg="yellow",
font="none 12 bold")
self.gender_entry = tkinter.IntVar()
self.gender_entry.set(1)
# radio buttons for gender choice
self.rb1 = tkinter.Radiobutton(self.top_frame,
text='Male',
variable=self.gender_entry,
value=1)
self.rb2 = tkinter.Radiobutton(self.top_frame,
text='Female',
variable=self.gender_entry,
value=2)
# goal widget
self.prompt_label5 = tkinter.Label(self.top_frame,
text='Select your goal:', bg="red", fg="yellow",
font="none 12 bold")
self.goal_entry = tkinter.IntVar()
self.goal_entry.set(1)
# radio buttons for goal choice
self.rb3 = tkinter.Radiobutton(self.top_frame,
text='Lose Weight',
variable=self.goal_entry,
value=1)
self.rb4 = tkinter.Radiobutton(self.top_frame,
text='Maintain',
variable=self.goal_entry,
value=2)
self.rb5 = tkinter.Radiobutton(self.top_frame,
text='Build Muscle Mass',
variable=self.goal_entry,
value=3)
# packing widgets
self.prompt_label1.pack(side='top')
self.name_entry.pack(side='top')
self.prompt_label2.pack(side='top')
self.weight_entry.pack(side='top')
self.prompt_label3.pack(side='top')
self.height_entry.pack(side='top')
self.prompt_label4.pack(side='top')
self.rb1.pack(side='top')
self.rb2.pack(side='top')
self.prompt_label5.pack(side='left')
self.rb3.pack(side='left')
self.rb4.pack(side='left')
self.rb5.pack(side='left')
# MIDDLE FRAME
self.descr_label = tkinter.Label(self.mid_frame,
text='Workout for you:')
self.value = tkinter.StringVar()
self.workout_label = tkinter.Label(self.mid_frame,
textvariable=self.value,
width=250, height=20, bg="white")
# packing widgets
self.descr_label.pack(side='top')
self.workout_label.pack(side='bottom')
# BOTTOM FRAME
# buttons
self.display_button = tkinter.Button(self.bottom_frame,
text='Get Workout!',
command=self.getworkout)
self.quit_button = tkinter.Button(self.bottom_frame,
text='Quit',
command=self.main_window.destroy)
# pack the buttons
self.display_button.pack(side='left')
self.quit_button.pack(side='right')
# packing frames
self.top_frame.pack()
self.mid_frame.pack()
self.bottom_frame.pack()
# fucnction to get outputs
def getworkout(self):
# Gather User information
name = str(self.name_entry.get())
gymSerial = random.randint(0, 10000)
weight = float(self.weight_entry.get())
height = float(self.height_entry.get())
gender = (self.gender_entry.get())
goal = (self.goal_entry.get())
def entry_validation_1(x):
if x.isdecimal():
messagebox.showwarning("Wrong input!", "Name must be a string - not integer.")
return False
else:
return True
def entry_validation_2(y):
if y.isdecimal():
return True
else:
messagebox.showwarning("Wrong input!", "Weight and height must be a numerical value - not string")
return False
def main():
root = tkinter.Tk()
ex = WorkoutGUI()
root.mainloop()
if __name__ == '__main__':
main()
Link is not working, but I wrote my own code as an example. I think it's very close to what you need.
The method is called entry validation and you can find some more info here:
https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/entry-validation.html
Feel free to ask if you have any concerns :)
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
# tkinter main window
root = tk.Tk()
root.title('Validation')
root.geometry('300x300')
def entry_validation_1(x):
if x.isdecimal():
messagebox.showwarning("Wrong input!", "Name must be a string - not integer.")
return False
else:
return True
def entry_validation_2(y):
if y.isdecimal():
return True
else:
messagebox.showwarning("Wrong input!", "Weight and height must be a numerical value - not string")
return False
validation1 = root.register(entry_validation_1)
validation2 = root.register(entry_validation_2)
name = tk.Entry(root, width='9', justify='center', validate='key', validatecommand=(validation1, '%S'))
weight_or_height = tk.Entry(root, width='9', justify='center', validate='key', validatecommand=(validation2, '%S'))
label_name = tk.Label(root, text='name - INTEGER NOT ACCEPTED')
label_weight_or_height = tk.Label(root, text='weight or height - STRING NOT ACCEPTED')
name.grid(row=0, column=0, padx=0, pady=0)
label_name.grid(row=0, column=1, padx=0, pady=0)
weight_or_height.grid(row=1, column=0, padx=0, pady=0)
label_weight_or_height.grid(row=1, column=1, padx=0, pady=0)
tk.mainloop()