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.
Related
My program has an entry widgets called pizza and sandwich. If the user begins typing in the pizza box the sandwich box should be disabled. If the user begins typing in the sandwich box then the pizza box should be disabled. Box entry boxes should take a float value. The user can pick either box to type the price when they finish typing they should click the submit button and the price should print out. I am trying to figure out how to check for empty floats so the if else statement can change state.
import tkinter as tk
root = tk.Tk()
root.geometry("600x400")
pizza = tk.DoubleVar()
sandwich = tk.DoubleVar()
def click(event):
if pizza.get() != '':
sandwich_entry.config(state=tk.DISABLED)
pizza_entry.config(state=tk.NORMAL)
if sandwich.get() != '':
pizza_entry.config(state=tk.DISABLED)
sandwich_entry.config(state=tk.NORMAL)
if pizza.get() == '' and sandwich.get() == "":
sandwich_entry.config(state=tk.NORMAL)
pizza_entry.config(state=tk.NORMAL)
print("price: " + str(pizza))
print("price: " + str(sandwich))
pizza_label = tk.Label(root, text='pizza')
pizza_entry = tk.Entry(root, textvariable=pizza)
pizza_entry.bind('<KeyRelease>', click)
sandwich_label = tk.Label(root, text='sandwich')
sandwich_entry = tk.Entry(root, textvariable=sandwich)
sandwich_entry.bind('<KeyRelease>', click)
button = tk.Button(root, text='Submit',)
pizza_label.grid(row=0, column=0)
pizza_entry.grid(row=0, column=1)
sandwich_label.grid(row=1, column=0)
sandwich_entry.grid(row=1, column=1)
button.grid(row=2, column=0)
root.mainloop()
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.
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)
I'm trying to create a factorial calculator GUI.
The program works fine, but the problem I'm having is that when there are too many numbers coming in from the output, the screen automatically increases in width. I've tried using tk.Text to create a limit to the size of the textbox and so the text continues to the next row when the columns are filled.
But when I had to input text in to the tk.Text it didn't work since the variable I used is being processed in the function that gets called when the button is pressed. I have tried googling this problem but I couldn't find anything, I did find some people explaining how to use variables that get created/processed inside of a function, but that didn't work so I think I have done something wrong in my code.
Note: I am using lambda to call my function (not sure if this is important or not).
TLDR: Text gets too long when too much information is outputted. tk.Text didn't work for me since I couldn't figure out how to use the variable that is created/processed inside of a function that is only called when the button is pressed.
Here is my entire code: https://pastebin.com/1MkdRjVE
Code for my function:
def start_calc():
output_array = ["placehold"]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
output_msg.set("Output: " + output_array_str)
print(output_array_str) #This is just so I know if it's working or not in the terminal
Code for my output:
output_msg = tk.StringVar()
output_text = tk.Label(root, textvariable=output_msg, font="Raleway")
output_msg.set("Output: ")
output_text.grid(columnspan=3, column=0, row=14)
I think this is what you are looking for:
#Imports
import tkinter as tk
#Variables
root = tk.Tk()
#Tkinter GUI setup basic
canvas = tk.Canvas(root, width= 400, height=400)
canvas.grid(columnspan=3, rowspan=120)
#Title
text = tk.Label(root, text="Calculating factorials", font="Raleway")
text.grid(column=1, row=1)
#Function
def start_calc():
output_array = ["", ""]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
# Change the output
output_text.config(state="normal")
# delete last output:
output_text.delete("0.0", "end")
# insert new output:
output_text.insert("end", output_array_str)
output_text.config(state="disabled")
print(output_array_str) #This is just so I know if it's working or not in the terminal
#input
tk.Label(root, text="Number :").grid(row=10)
tk.Label(root, text="Factorial :").grid(row=11)
e1 = tk.Entry(root)
e2 = tk.Entry(root)
e1.grid(row=10, column=1)
e2.grid(row=11, column=1)
#Error message if the input is invalid
error_message = tk.StringVar()
error_text = tk.Label(root, textvariable=error_message, font="Raleway")
error_message.set(" ")
error_text.grid(column=1, row=12)
#Startbutton
start_text = tk.StringVar()
start_btn = tk.Button(root, textvariable=start_text, command=start_calc, font="Raleway", bg="#20bebe", fg="white", height=2, width=15)
start_text.set("Start!")
start_btn.grid(column=1, row=13, pady=10)
#output
output_text = tk.Text(root, height=1, width=20, wrap="none", font="Raleway")
output_text.insert("end", "Output")
output_text.config(state="disabled")
output_text.grid(columnspan=3, column=0, row=14, sticky="news")
#Adding a scrollbar
scrollbar = tk.Scrollbar(root, orient="horizontal", command=output_text.xview)
scrollbar.grid(columnspan=3, column=0, row=15, sticky="news")
output_text.config(xscrollcommand=scrollbar.set)
#disclaimer message
disclaimer_text = tk.Label(root, text="Disclaimer: The factorials will be printed from 1 to the number you entered.")
disclaimer_text.grid(columnspan=3, column=0, row=110)
root.mainloop()
I used a <tkinter.Text> widget with wrap="none", height=1 and width=20 to make the output box. I disabled the entry so that the user can't change the results but can still copy it.
I am trying to make a 'guess the number' game with Pyhon tkinter but so far I have not been able to retrieve the input from the user.
How can I get the input in entry when b1 is pressed?
I also want to display a lower or higher message as a clue to the player but I am not sure if what I have is right:
import time
import random
import decimal
import tkinter as tk
root = tk.Tk()
randomnum = float(decimal.Decimal(random.randrange(100,10000))/100)
guess = 0
def get(entry):
guess = entry.get()
return guess
def main():
b1 = tk.Button(root, text="Guess", command=get)
entry = tk.Entry()
b1.grid(column=1, row=0)
entry.grid(column=0, row=0)
root.mainloop()
print(guess)
if guess < randomnum:
l2 = tk.Label(root, text="Higher!")
l2.grid(column=0, row=2)
elif guess > randomnum:
l3 = tk.Label(root, text="Lower!")
l3.grid(column=0, row=2)
while guess != randomnum:
main()
l4 = tk.Label(root, text="Well guessed")
time.sleep(10)
You could define get inside main, so that you can access the entry widget you created beforehand, like this:
entry = tk.Entry()
def get():
guess = entry.get()
return guess # Replace this with the actual processing.
b1 = tk.Button(root, text="Guess", command=get)
You've assembled random lines of code out of order. For example, the root.mainloop() should only be called once after setting up the code but you're calling it in the middle of main() such that anything after won't execute until Tk is torn down. And the while guess != randomnum: loop has no place in event-driven code. And this, whatever it is, really should be preceded by a comment:
randomnum = float(decimal.Decimal(random.randrange(100,10000))/100)
Let's take a simpler, cleaner approach. Rather than holding onto pointers to the the various widgets, let's use their textvariable and command properties to run the show and ignore the widgets once setup. We'll use StringVar and IntVar to handle input and output. And instead of using sleep() which throws off our events, we'll use the after() feature:
import tkinter as tk
from random import randint
def get():
number = guess.get()
if number < random_number:
hint.set("Higher!")
root.after(1000, clear_hint)
elif number > random_number:
hint.set("Lower!")
root.after(1000, clear_hint)
else:
hint.set("Well guessed!")
root.after(5000, setup)
def setup():
global random_number
random_number = randint(1, 100)
guess.set(0)
hint.set("Start Guessing!")
root.after(2000, clear_hint)
def clear_hint():
hint.set("")
root = tk.Tk()
hint = tk.StringVar()
guess = tk.IntVar()
random_number = 0
tk.Entry(textvariable=guess).grid(column=0, row=0)
tk.Button(root, text="Guess", command=get).grid(column=1, row=0)
tk.Label(root, textvariable=hint).grid(column=0, row=1)
setup()
root.mainloop()
Here is a tkinter version on the number guessing game.
while or after are not used!
Program checks for illegal input (empty str or words) and reports error message. It also keeps track of the number of tries required to guess the number and reports success with a big red banner.
I've given more meaningful names to widgets and used pack manager instead of grid.
You can use the button to enter your guess or simply press Return key.
import time
import random
import tkinter as tk
root = tk.Tk()
root.title( "The Number Guessing Game" )
count = guess = 0
label = tk.Label(root, text = "The Number Guessing Game", font = "Helvetica 20 italic")
label.pack(fill = tk.BOTH, expand = True)
def pick_number():
global randomnum
label.config( text = "I am tkinking of a Number", fg = "black" )
randomnum = random.choice( range( 10000 ) )/100
entry.focus_force()
def main_game(guess):
global count
count = count + 1
entry.delete("0", "end")
if guess < randomnum:
label[ "text" ] = "Higher!"
elif guess > randomnum:
label[ "text" ] = "Lower!"
else:
label.config( text = f"CORRECT! You got it in {count} tries", fg = "red" )
root.update()
time.sleep( 4 )
pick_number()
count = 0
def get( ev = None ):
guess = entry.get()
if len( guess ) > 0 and guess.lower() == guess.upper():
guess = float( guess )
main_game( guess )
else:
label[ "text" ] = "MUST be A NUMBER"
entry.delete("0", "end")
entry = tk.Entry(root, font = "Helvetica 15 normal")
entry.pack(fill = tk.BOTH, expand = True)
entry.bind("<Return>", get)
b1 = tk.Button(root, text = "Guess", command = get)
b1.pack(fill = tk.BOTH, expand = True)
pick_number()
root.geometry( "470x110" )
root.minsize( 470, 110 )
root.mainloop()
Correct way to write guess number.
I write a small script for number guessing game in Python in
get_number() function.
Used one widget to update Label instead of duplicating.
I added some extra for number of turns that you entered.
Code modified:
import time
import random
import decimal
import tkinter as tk
root = tk.Tk()
randomnum = float(decimal.Decimal(random.randrange(100,10000))/100)
print(randomnum)
WIN = False
GUESS = 0
TURNS = 0
Vars = tk.StringVar(root)
def get_number():
global TURNS
while WIN == False:
Your_guess = entry.get()
if randomnum == float(Your_guess):
guess_message = f"You won!"
l3.configure(text=guess_message)
number_of_turns = f"Number of turns you have used: {TURNS}"
l4.configure(text=number_of_turns)
l4.grid(column=0, row=3, columnspan=3, pady=5)
WIN == True
break
else:
if randomnum > float(Your_guess):
guess_message = f"Your Guess was low, Please enter a higher number"
else:
guess_message = f"your guess was high, please enter a lower number"
l3.configure(text=guess_message)
l3.grid(column=0, row=2, columnspan=3, pady=5)
TURNS +=1
return Your_guess
label = tk.Label(root, text="The Number Guessing Game", font="Helvetica 12 italic")
label.grid(column=0, row=0, columnspan=3, sticky='we')
l2 = tk.Label(root, text='Enter a number between 1 and 100',
fg='white', bg='blue')
l2.grid(row=1, column=0, sticky='we')
entry = tk.Entry(root, width=10, textvariable=Vars)
entry.grid(column=1, row=1, padx=5,sticky='w')
b1 = tk.Button(root, text="Guess", command=get_number)
b1.grid(column=1, row=1, sticky='e', padx=75)
l3 = tk.Label(root, width=40, fg='white', bg='red' )
l4 = tk.Label(root, width=40, fg='white', bg='black' )
root.mainloop()
while guess:
time.sleep(10)
Output for enter floating numbers:
Output after the guess was high:
Output after the guess was low:
Output You won and number of turns: