How to create Checkbuttons with Integer value in for loop? - python

I am creating a project for my college class. I am creating a gui with python tkinter of a pizza restaurant. I have created 5 checkbuttons displaying 5 different pizzas with a different price on each pizza. I have created a calculate button. How can I create a function for the calculate button to display the price of each pizza depending on which are selected? If multiple are selected it would say 'pepperoni price is: $', 'cheese price is: $',...etc? How can I give each pizza a different onvalue in for loop?
Code is here:
from tkinter import *
root = Tk()
root.title('Pizza Restaurant')
root.geometry('500x500')
pizza = [['cheese',5], ['pepperoni',10], ['sausage',15], ['BBQ',20], ['hawaiian',25]]
var_list = ['pizza1', 'pizza2', 'pizza3', 'pizza4', 'pizza5']
for i in range(5):
button = Checkbutton(root, text=pizza[i][0], variable=var_list[i], onvalue=pizza[i][1], offvalue=0).grid(row=i, column=0)
var_list[i] = IntVar()
def calc():
for var in var_list:
if var.get() != 0:
label = Label(root, text=var.get()).grid(row=2, column=8)
'''for e in range(5):
button_list.append(Checkbutton(root, text=pizza[e][0], variable=var_list[e], onvalue=pizza[e][1],))
labels.append(Label(root, text=pizza[e][1]))
button_list[e].grid(row=e, column=0, sticky=W)
labels[e].grid(column=1, row=e)
total = 0
def calc():
for i in range(5):
if i == pizza[i][1]:
label = Label(root, text=pizza[i][1]).grid(row=1, column=10)
'''

How does something like this work for you
from tkinter import *
def calc():
priceList = ""
for pizza,var in zip(pizzas,var_list):
if var.get() != 0:
priceList += ("{0} costs ${1}\n".format(pizza[0],pizza[1]))
priceStr.set(priceList)
root = Tk()
root.title('Pizza Restaurant')
root.geometry('500x500')
pizzas = [['cheese',5], ['pepperoni',10], ['sausage',15], ['BBQ',20], ['hawaiian',25]]
var_list = [IntVar(root) for _ in pizzas]
for i,(pizza,var) in enumerate(zip(pizzas,var_list)):
button = Checkbutton(root, text=pizza[0], variable=var, onvalue=pizza[1], offvalue=0, command=calc).grid(row=i, column=0)
priceStr = StringVar(root)
priceLabel = Label(root,textvariable=priceStr)
priceLabel.grid(row=len(pizzas)+1,column=0)
root.mainloop()
When you click on each checkbox it will run the calc function to populate the label that appears below the checkboxes. I'm using enumerate rather than range to iterate over each item in the pizzas list while still getting an index that can be used to set the row number.
Also using zip so that I can iterate over both the pizzas and var_list at the same time.
The calc function isn't too different to your own one, it just adds a new part to a string if a checkbox for a pizza has been selected.

Related

Displaying values of checkbuttons in python tkinter

I have created a list of 5 checkbuttons, displaying 5 different pizzas to choose. When one or more buttons are clicked it will calculate the total price of pizzas. I have a function with for loop and if statement excuting the price of pizza when clicked. How can I make the output display the total price of pizzas if one or more pizzas are clicked but also display "you have ordered no pizza" when none have been clicked? In my if statement it is displaying the total price of pizzas clicked but also displaying "you have ordered no pizza" due to the other choices not being clicked. I need it to display "you ordered no pizza" when only no buttons have been clicked.
def total():
top = Toplevel()
tot = 0
name = entry1.get()
address = entry2.get()
for pizza,var in zip(pizzas,var_list):
if var.get() != 0:
tot = tot + var.get()
label = Label(top, text="Your total cost of pizza is ${}\nShipping to {},\n at this address: {}".format(tot, name, address), font='helvetica, 32').grid(row=9, column=0)
else:
label1 = Label(top, text='you ordered no pizza').grid(row=11, column=0)
button = Button(top, text='Exit', command=top.destroy).grid(row=10, column=0)
You need to check whether tot > 0 after the for loop to determine which message to be shown:
def total():
top = Toplevel()
tot = 0
name = entry1.get()
address = entry2.get()
for pizza,var in zip(pizzas, var_list):
price = var.get()
if price != 0:
tot += price
if tot > 0:
Label(top, text="Your total cost of pizza is ${}\nShipping to {},\n at this address: {}".format(tot, name, address), font='helvetica, 32').grid(row=9, column=0)
else:
Label(top, text='you ordered no pizza').grid(row=11, column=0)
Button(top, text='Exit', command=top.destroy).grid(row=10, column=0)
Note that assigning Label(...).grid(...) (always None) to a variable is meaningless.

Python Tkinter Menu System. Unable to get prices totaled and displayed

New to python & I have been tryna to build a small Menu with Tkinter, my idea is when I select an item from the menu the name of it appears in the larger screen and the total of the items selected appears in the smaller screen, my function is called fireFood. I'm currently seeing my prices run on a line instead of being totaled and I've been stuck on this for a couple days, hope someone can point me in the right direction.
rom tkinter import ttk
import tkinter as tk
root = tk.Tk()
root.geometry('500x300')
root.title('Server Window')
root.wm_resizable(width=False, height=False)
# Create display area for selected items
display = tk.Text(root, height=10, width=30, bg='Orange', bd=4)
display.grid(row=1, column=3)
price_display = tk.Text(root, height=3, width=15, bg='Orange', bd=4)
price_display.grid(row=3, column=3)
#====================== Functions =================================
def fireFood():
# Every time a new item is selected i want a new total to be calculated and displayed
global menu
global price_display
global display
global select_option
total = 0
prices = []
# this inserts food item onto display
display.insert(tk.END,options.get())
prices.append([options.get(), menu[options.get()]])
for x in prices:
total = total + float(x[1])
# this shows price on lower display
price_display.insert(tk.END, total)
total += float(menu[options.get()])
def addList(arr):
cost = 0
arr.remove('\n')
total = [sum(float(x) for x in arr)]
for x in total:
cost += x
return cost
#======================================================================
# Create a Dictionary of items to be displayed in Combobox
menu = {'fries ':5, 'Burger ':10, 'Pizza ':15, 'Chicken ':8, 'Fish ':7.50}
menu_list = [x for x in menu.keys()]
menu_prices = [y for y in menu.values()]
options = ttk.Combobox(values=menu_list)
# Set default value for the combobox to 'Menu' to function as a pseudo label
options.set('Menu')
options.grid(row=0, column=0)
# Create a button that when pressed will get the value of combobox
select_option = ttk.Button(root, text='Select', command=fireFood)
select_option.grid(row=0, column=1)
root.mainloop()
This works for me.
price_display = tk.Text(root, height=3, width=15, bg='Orange', bd=4)
price_display.grid(row=3, column=3)
total = 0
#====================== Functions =================================
def fireFood():
# Every time a new item is selected i want a new total to be calculated and displayed
global menu
global price_display
global display
global select_option
global prices
global total # make total global
prices = []
# this inserts food item onto display
display.insert(tk.END,options.get())
# this shows price on lower display
total += float(menu[options.get()])
price_display.delete('1.0', 'end') # delete previous text
price_display.insert(tk.END, total)

How to add a new entry box when clicking a button (Python, Tkinter)

Hi i want to add a new entry box when clicking a button. How can i do that ?
What've done is im able to "for loop" a group of entry boxes. But i want the entry boxes to appear one by one by clicking a button.
What've done
My code:
import tkinter as tk
from tkinter import *
root = Tk()
root.title("Entry box")
root.geometry("700x500")
my_entries = []
def something():
entry_list = ''
for entries in my_entries:
entry_list = entry_list + str(entries.get()) + '\n'
my_label.config(text=entry_list)
print(my_entries[0].get())
for x in range(5):
my_entry = Entry(root)
my_entry.grid(row=0, column=x, pady=20, padx=5)
my_entries.append(my_entry)
my_button = Button(root, text="Click Me!", command=something)
my_button.grid(row=1, column=0, pady=20)
There is not much of work here, create a variable to keep track of the columns you are inserting the widget into and then just insert it based on that number, like:
# Rest of your code..
my_entries = []
count = 0 # To keep track of inserted entries
def add():
global count
MAX_NUM = 4 # Maximum number of entries
if count <= MAX_NUM:
my_entries.append(Entry(root)) # Create and append to list
my_entries[-1].grid(row=0,column=count,padx=5) # Place the just created widget
count += 1 # Increase the count by 1
Button(root, text='Add', command=add).grid(row=1, column=1, padx=10) # A button to call the function
# Rest of your code..
Though I am not sure about your other function and its functionality, but it should work after you create entries and then click that button.

How can I get input from multiple entry widgets created in a loop?

I've hunted through some of the previous answers and got a step closer, but my problem is still that I can not get the value from multiple entry boxes.
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
my_list = []
def get_info():
for each_player in my_list:
tk.Label(window, text=temp_entry.get()).grid()
#number of players is determined by the user.
#In this example, lets say there are 3 players
tk.Label(window, text="Number of Players: ").grid()
num_of_players = ttk.Combobox(window, values=[1, 2, 3])
num_of_players.current(2)
num_of_players.grid(row=0, column=1)
#The code above is only the recreate the user selecting the amount of players from a combobox
#create number of entry boxes for user-determined number of players
for each_player in range(1, int(num_of_players.get()) + 1):
temp_label = tk.Label(window, text="Player {}: ".format(each_player))
temp_entry = tk.Entry(window)
my_list.append(temp_entry)
temp_label.grid(row=each_player, column=0, pady=10)
temp_entry.grid(row=each_player, column=1, pady=10)
button = tk.Button(window, text="Save", command=get_info)
button.grid()
window.mainloop()
It's at the end of the code where I struggle to find out how I could possibly get information from the entry boxes. How can I use the get() method but only after the user has input text?
Your list contains entry widgets, so in your loop you need to reference the loop variable rather than temp_entry:
def get_info():
for each_player in my_list:
print(each_player.get())
Use a button that triggers a method that gets the text for u like:
play = Button(window, text="get_button", command=that_getter_method)
.....
.....
def that_getter_method():
var = field.get()

Tkinter - Retrieve Values from Dynamically Generated Widgets - Callback

I'm trying to make a GUI through Tkinter that will calculate production based on some user input. Based on the number of systems the user selects, I have that number of option menus pop up for the inverter type and that number of entry widgets pop up for modules per string, strings per inverter, and inverters per system. See the picture for an example if the user selects 2 systems.
I'm using a callback function to grab the user selected number of systems real time to dynamically generate the inverter/module widgets discussed above.
My issue is that I'm unable to retrieve the values from these widgets. My attempt is shown in the weather calculation function.
I'm assuming the issue is because I generate the widgets/variables within the callback function. However, I haven't been able to figure out a way to dynamically generate the number of widgets based on user input outside of the callback function.
Any assistance with this would be greatly appreciated!
class Window:
# Define User Inputs:
def __init__(self, master):
master.title('Production Analysis Tool')
# EQUIPMENT PARAMETERS
# callback function to create entry boxes based on number of systems
def callback(*args):
self.system_size = int(self.system_size_raw.get())
# Modules per String
self.L3 = Label(root, text = "Number of Modules Per String").grid(row=20, column=1, sticky=E)
self.modules_string_raw = IntVar(root)
modules_per_string =[]
for i in range(self.system_size):
self.label = Label(root, text = "System {}".format(i+1)).grid(row=21+i, column=1, sticky=E)
self.widget = Entry(root).grid(row=21+i, column=2, sticky=W)
modules_per_string.append(self.widget)
# Number of Systems
self.L1 = Label(root, text = "Number of Systems").grid(row=1, column=1, sticky=E)
self.system_size_raw = IntVar(root)
choices = [1,2,3,4,5,6,7,8,9,10]
self.popupMenu2 = OptionMenu(root, self.system_size_raw, *choices).grid(row=1, column=2, sticky=W)
self.system_size_raw.trace("w", callback)
#Calculation Function
def weather_calculation(self):
# Get Values from User Input
self.mod_strings = np.float(self.modules_string_raw.get())
root = Tk()
root.configure()
window = Window(root)
root.mainloop()
All you need to do is save a reference to your Entry widgets in a list. You can then iterate over that list to get the value of each widget.
It appears that you're already saving the widgets to the list variable modules_per_string. All you need to do is make that global or an object attribute rather than a local variable so other functions can reference it.
As Bryan Oakley said, make list for widgets to store each objects of entries and label in two list.
For Example:
import tkinter as tk
class Demo:
def __init__(self):
self.root = tk.Tk()
self.root.geometry("600x600")
systems_label = tk.Label(self.root, text="No Of Systems:")
systems_label.place(x=100, y=20)
no_Of_System_Ent = tk.Entry(self.root, width=15)
no_Of_System_Ent.place(x=200, y=20)
submit_Button = tk.Button(self.root, text="Submit", command=lambda: self.process(no_Of_System_Ent.get()))
submit_Button.place(x=350,y=20)
def display(self,sys_len):
for i in range(sys_len):
buffer = self.obj_of_entries[i].get()
print(buffer)
def delete(self,sys_len):
for i in range(sys_len):
self.obj_of_entries[i].destroy()
self.obj_of_labels[i].destroy()
def process(self,length_sys):
self.obj_of_entries = []
self.obj_of_labels = []
y_pos = 80
for i in range(int(length_sys)):
#Adding objects of label in list 'obj_of_labels'
self.obj_of_labels.append(tk.Label(self.root,text="System "+str(i)))
self.obj_of_labels[len(self.obj_of_labels)-1].place(x=100,y=y_pos)
#Adding objects of entry in list 'obj_of_entries'
self.obj_of_entries.append(tk.Entry(self.root,width=15))
self.obj_of_entries[len(self.obj_of_entries)-1].place(x=200,y=y_pos)
#Increments Y by 50
y_pos = y_pos + 50
self.delete_Button = tk.Button(self.root, text="Delete All", command=lambda: self.delete(int(length_sys)))
self.delete_Button.place(x=200,y=400)
self.print_Button = tk.Button(self.root, text="Print All", command=lambda: self.display(int(length_sys)))
self.print_Button.place(x=350,y=400)
ob=Demo()
In this example:
I created a entry and button in the init function to take no of systems from user.
def __init__(self):
self.root = tk.Tk()
self.root.geometry("600x600")
systems_label = tk.Label(self.root, text="No Of Systems:")
systems_label.place(x=100, y=20)
no_Of_System_Ent = tk.Entry(self.root, width=15)
no_Of_System_Ent.place(x=200, y=20)
submit_Button = tk.Button(self.root, text="Submit", command=lambda: self.process(no_Of_System_Ent.get()))
submit_Button.place(x=350,y=20)
After clicking submit button,it will go to process function.
Ps: length_sys is the no of systems.
def process(self,length_sys):
self.obj_of_entries = []
self.obj_of_labels = []
y_pos = 80
for i in range(int(length_sys)):
#Adding objects of label in list 'obj_of_labels'
self.obj_of_labels.append(tk.Label(self.root,text="System "+str(i)))
self.obj_of_labels[len(self.obj_of_labels)-1].place(x=100,y=y_pos)
#Adding objects of entry in list 'obj_of_entries'
self.obj_of_entries.append(tk.Entry(self.root,width=15))
self.obj_of_entries[len(self.obj_of_entries)-1].place(x=200,y=y_pos)
#Increments Y by 50
y_pos = y_pos + 50
self.delete_Button = tk.Button(self.root, text="Delete All", command=lambda: self.delete(int(length_sys)))
self.delete_Button.place(x=200,y=400)
It will append the entry and label obj in its respective list and place the current obj in GUI window.
At Last,It will increment y axis by 80 so that next label and entry comes down to the previous one.
If user clicks delete all button,then it will go to delete all list obj of both entries and labels.
Ps: sys_len is the no of systems.
def delete(self,sys_len):
for i in range(sys_len):
self.obj_of_entries[i].destroy()
self.obj_of_labels[i].destroy()
To see the content,use this code:
(It will print in the Python shell so you can see if data is correct or not.)
def display(self,sys_len):
for i in range(sys_len):
buffer = self.obj_of_entries[i].get()
print(buffer)
I think I solved the doubt.
Ciao!

Categories

Resources