This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 2 years ago.
I am trying to create a simple "Store App" that will add the item name and cost to a dictionary and then output it, but whenever I go to run my program it adds both items to cart before I have even clicked the buttons. I am not sure if it is a python problem, or something to do with how Tkinter works. Any help would be appreciated.
from tkinter import *
root = Tk()
root.title("Number Sorter")
root.geometry('600x600')
cart_list = {"Item_Name": [], "Price": []}
def purchaseClick(Name, Price):
cart_list["Item_Name"].append(Name)
cart_list["Price"].append(Price)
title1 = Label(root, text="The Solar War by A.G Riddle")
item1_name = "The Solar War"
item1_price = 11.99
title1.pack()
purchasebtn = Button(root, text="Purchase", command = purchaseClick(item1_name, item1_price))
purchasebtn.pack()
title2 = Label(root, text="Elon Musk By Ashlee Vance")
item2_name = "Elon Musk"
item2_price = 9.99
title2.pack()
purchasebtn = Button(root, text="Purchase", command = purchaseClick(item2_name, item2_price))
purchasebtn.pack()
cart_list_show = Label(root, text=cart_list)
cart_list_show.pack()
root.mainloop()
This is happening because Button.command takes a function as an argument, not the output. So, you have to pass just purchaseClick and not purchaseClick(item1, price1).
But in your case you need to pass in arguments too, so change the line from
purchasebtn = Button(root, text="Purchase", command = purchaseClick(item1_name, item1_price))
to this,
purchasebtn = Button(root, text="Purchase", command = lambda : purchaseClick(item1_name, item1_price))
I am fairly sure this is gonna do the work for you.
Related
I'm trying to learn Tkinter, and learning how to set a variable that can be worked on later on in the code from the choice selected from an optionmenu. Only been coding tkinter or python for about 2 days properly now and unsure why this doesn't work.
my code:
root = Tk()
root.title("test")
p1aspVARIABLE = str()
def tellmethevariable():
if p1aspVARIABLE == "AA":
print(p1aspVARIABLE)
else:
print("Not 'AA'")
def tellmeP1Asp(choice):
choice = p1aspCHOICE.get()
print(choice)
p1aspVARIABLE = choice
print(p1aspVARIABLE)
alleles = ["AA", "Ab", "bb"]
p1aspCHOICE = StringVar()
p1aspCHOICE.set(alleles[0])
alleledropdown = OptionMenu(root, p1aspCHOICE, *alleles, command=tellmeP1Asp)
button1 = Button(root, command=tellmethevariable)
alleledropdown.grid(row=0, column=0)
button1.grid(row=0, column=1)
root.mainloop()
I don't understand why the code is able to print out the p1aspCHOICE when ran from the "tellmeP1Asp", but not when done through "tellmethevariable"?
I'm not sure how to get the p1aspVARIABLE to properly change to what was chosen in the OptionMenu list?
I'm not knowledgeable enough of what I'm doing wrong to properly google this, have been trying for a few hours now but to no avail.
What I tried:
I've set this up in countless ways over the last few hours, mostly last night before giving up. This is actually one of the only versions of this code that ran.
What I was expecting:
When the button1 Button is clicked, for it to either print the choice (if it was "AA", so it would print "AA"), or, if it wasn't "AA", it would print "Not 'AA'"
This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed last year.
I'm making a log/chat system in my program (just Tkinter default looks) and i came across a problem where I can't add or change a listbox. Here is what I'm trying to do:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
window = tkinter.Tk()
window.geometry("250x195")
window.title(" ")
window.iconbitmap("icon.ico")
global loglength, log
log = []
loglength = len(log)
inventorylist = []
def sendmessage(event):
chatstring = chatentry.get()
log.append(chatstring)
print(log, loglength)
checknew() #dont worry abt this it works
serverlog = tkinter.Listbox(
width=20,
height=11,
bg="darkgray",
listvariable=log
).place(x=128,y=-2)
I want to add items to the listbox. Here is an image of my program:
When I press enter (the key bound to the function to add the string to the listbox) this happens:
is Listbox like a program u want?
if u want a program that will make u program list in tkinder this is the code :
from tkinter import *
a= Tk()
a.geometry("400x400")
a.title("test")
Lb1 = Listbox(a,bg = "pink", bd = 10, fg = "black",\
font = "Castellar", cursor = "target")
Lb1.insert(1, "lion")
Lb1.insert(2, "tiger")
Lb1.insert(3, "zebra")
Lb1.insert(4, "elephant")
Lb1.insert(5, "deer")
Lb1.insert(6, "fox")
Lb1.insert(7, "Wolf")
Lb1.insert(8, "Gorilla")
Lb1.insert(9, "Jackal")
Lb1.insert(10, "Otter")
Lb1.pack()
a.mainloop()
hope that i helped u.
I tried creating a program that will take in the symptoms of a person and return the disease they have. This is the GUI part of the project.
from tkinter import *
root = Tk()
root.title("Health GUI")
root.geometry("1000x625")
symptoms_list = []
def print_symptoms():
print(symptoms_list)
def typeSymptoms():
gap3 = Label(text="").pack()
symptoms_entry = Text(width=50, height=20)
symptoms_entry.pack()
symptoms_list.append(symptoms_entry.get(1.0, END))
done_symptoms = Button(text="I have written my symptoms", width=25, height=5, command=lol)
done_symptoms.pack()
gap1 = Label(text="").pack()
title = Label(text="HEALTH GUI", font=30).pack()
gap2 = Label(text="").pack()
start_button = Button(text="Click here to start", width=30, height=5, command=typeSymptoms, font=20).pack()
root.mainloop()
Just for simplicity, I tried printing out the symptoms given by the user to the console but it gives me a list with '\n'. Please help. Thanks!(PS: I lerned Tkinter day before yesterday so I don't know much)
At the moment, your variable symptoms_list just holds the contents of the newly created Text widget, since you append this content at startup.
If you want to add the symptoms to the list, you need to have your function lol() that you call when pressing the button.
This function should look something like:
def lol():
symptoms_text = symptoms_entry.get(1.0, END)
symptoms_list = symptoms_text.split('\n')
print_symptoms()
However, your widgets and the symptoms_list would have to be global variables in order for this program to work. It would probably be better, while you are getting acquainted with Tkinter, to learn how to create a dialog as Class with attributes. That makes sharing values between methods so much easier.
This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 2 years ago.
I need to do some basic conditional logic on entries, but I am running into an issue.
There are 2 entries, "dosage" and "week". In both will be entered only numbers (25, 3, etc.). I have a "Get Info" button that activates a function what will preform conditional logic on the entries, although since when the program runs there isn't any text inside of the entries, I run into an error.
ValueError: invalid literal for int() with base 10: ''
Here is my code:
from tkinter import *
import tkinter.font as font
# Window setup
root = Tk()
root.title("Dosage GUI")
root.geometry("330x450")
# Entries
weekEntry = Entry(root)
dosageEntry = Entry(root)
# Labels to describe entries
weekLabel = Label(root, text="Week #")
dosageLabel = Label(root, text="Dosage in mg (enter only a number)")
# Information text
# State = disabled, but when changing text, change to normal, then back to disabled
def setInfoText(textBox, text):
textBox.config(state="normal")
textBox.insert(1.0, text)
textBox.config(state="disabled")
infoTextFont = font.Font(size=8)
infoText = Text(root, height=17, width=30, padx=10,pady=10, state="disabled", font=infoTextFont, bd=5,bg="#e8ebea")
# Get Info button
def getInfo(week, dosage):
# Check what is possible based on the dosage rules
if week > 3:
setInfoText(infoText, "PI may change dosage if needed.")
if week < 3:
setInfoText(infoText, "PI cannot change dosage until week 3.")
getInfoFont = font.Font(size=13,weight="bold")
getInfoBut = Button(root, text="Get Info", padx=20,pady=20,bd=10,bg="#7299ed",activebackground="#729ffc", fg="#40e677", command=getInfo(int(weekEntry.get()), int(dosageEntry.get())))
getInfoBut['font'] = getInfoFont
# Grid
weekEntry.grid(row=0,column=5)
dosageEntry.grid(row=0, column=10)
weekLabel.grid(row=5,column=5)
dosageLabel.grid(row=5,column=10)
getInfoBut.place(x=100,y=70)
infoText.place(x=50,y=170)
# mainloop
root.mainloop()
The command keyword argument needs a function as parameter.
Right now you're passing getInfo(int(weekEntry.get()), int(dosageEntry.get())) - which is the return value of getInfo - which is None (because there are no return statements in that function).
Instead, you may want to pass this a statement inside a lambda - this way you create a function that gets called whenever that button is pressed:
getInfoBut = Button(root, text="Get Info", padx=20,pady=20,bd=10,bg="#7299ed",activebackground="#729ffc", fg="#40e677", command=lambda: getInfo(int(weekEntry.get()), int(dosageEntry.get())))
The reason the error occurs is because Python attempts to evaluate the call to getInfo even before the UI shows - the fields weekEntry anddosageEntry are empty at this point - attempting to convert an empty string to an int results in the error.
I am currently trying to make a GUI to an existing python program using Tkinter. The program gives the user two options from which the user must choose to either accept or decline. Before using Tkinter the options were placed in the terminal and awaited for a raw_input. (y/n). How can I make this so the canvas text updates with the new data and awaits for the users button click?
To make my question more specific: How can I run another programs code while the Tkinter mainloop is running and make these two interact?
Example code below.
from Tkinter import *
root = Tk()
root.resizable(width=False, height=False)
root.geometry('{}x{}'.format(500,550))
root.wm_title("Tkinter test")
BtnFrame = Frame (root)
BtnFrame.pack(side = BOTTOM)
BtnFrame.place(y=450, x=20)
canvas_1 = Canvas(root, width = "200", height ="300")
canvas_2 = Canvas(root, width = "250", height ="300")
canvas_1.pack(side = LEFT)
canvas_2.pack(side = RIGHT)
textfield_1 = canvas_1.create_text(100,50)
textfield_2 = canvas_2.create_text(100,50,)
def update_textfiel_1(text):
global textfield_1
canvas_1.delete(textfield_1)
textfield = canvas.create_text(100,50,text = text)
def update_textfiel_2(text):
global textfield_2
canvas_2.delete(textfield_2)
textfield1 = canvas1.create_text(100,50,text = text)
Accept = Button(BtnFrame, text="Accept", width=25)
Decline = Button(BtnFrame, text="Decline", width=25)
Accept.pack(side = LEFT)
Decline.pack(side = RIGHT)
root.mainloop()
First off you have some inconsistent variable names in your update_textfiel functions, you can greatly simplify it by using .itemconfigure (documentation for methods on canvas widget)
def update_textfiel_1(new_text):
canvas_1.itemconfigure(textfield_1, text=new_text)
def update_textfiel_2(new_text):
canvas_2.itemconfigure(textfield_2, text=new_text)
If I understand correctly you want a way to have a function that will simply wait for the user to press one of the buttons and then return the result, this is very easy with tkMessageBox:
question = """Do you accept {}?
if you say no you will instead get {}"""
#this message can GREATLY be improved
# But I really don't understand what you are using it for...
def user_confirmation(name1, name2):
response = tkMessageBox.askyesno("Accept or Decline",question.format(name1,name2))
print(response)
if response: # == True
return name1
else:
return name2
I have not yet found a way to make a blocking function that works with the window you have currently...