Variable not printing after being set with OptionMenu (tkinter) - python

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'"

Related

Tkinter: Problems having access to text input in text widget

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.

Why Is Tkinter Outputting Before I Push The Button [duplicate]

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.

Python TKinter: How do I achieve the same effect as input() in the GUI?

I started learning python a month and a half ago. So please forgive my lack of everything.
I'm making a text based adventure game. The game has been written and playable in terminal. I'm now adding a GUI as an after thought.
In one file, I have:
class Parser():
def __init__(self):
self.commands = CommandWords()
def get_command(self):
# Initialise word1 and word2 to <None>
word1 = None
word2 = None
input_line = input( "> " )
tokens = input_line.strip().split( " " )
if len( tokens ) > 0:
word1 = tokens[0]
if len( tokens ) > 1:
word2 = tokens[1]
This is called whenever the user is expected to enter text, it will then call another function to compare the input with known commands to move the game along.
However, when I tried to replace the input() with entry_widget.get(), it doesn't recognise entry_widget.
so I imported my file containing the GUI script, which is a circular importing error.
I tried to store the input as a string variable, but the program doesn't stop and wait for the user input, so it gets stuck the moment the program start to run not knowing what to do with the empty variable. (that is assuming input() stops the program and wait for user input? )
Any solutions? Or better ways of doing this?
Thanks.
import tkinter as tk
To create an Entry widget: entry = tk.Entry(root)
After you have that, you can get the text at any time: text = entry.get()
To make the program wait you need to create a tkinter variable: wait_var = tk.IntVar()
and then create a button that changes the value of the variable when pressed: button = tk.Button(root, text="Enter", command=lambda: wait_var.set(1))
Now you can tell tkinter to wait until the variable changes:button.wait_variable(wait_var)
Simple example:
import tkinter as tk
def callback():
print(entry.get())
wait_var.set(1)
root = tk.Tk()
wait_var = tk.IntVar()
entry = tk.Entry(root)
button = tk.Button(root, text="Enter", command=callback)
entry.pack()
button.pack()
print("Waiting for button press...")
button.wait_variable(wait_var)
print("Button pressed!")
root.mainloop()

How to handle a click button event in python module tkinter

I am trying to make a question game in python using tkinter. I am struggling to define a function that can check the answer that the player clicked on and add to a score that is then printed out below the answers.
The outcome of the code whenever I click is that the score is 0 and the question and answers don't change. Also, if I click repeatedly, it prints 0 as a label below each other.
I only included all of my code so that if someone wanted to test the code out for themselves, it wouldn't throw up any errors.
import tkinter
import random
from random import shuffle
score = 0
def check_answer(answer):
if answer == answers[s][0] or answer == answers[s][1]:
global score
score += 1
lbl = tkinter.Label(window, text=score)
lbl.pack()
#This sets up a window and names it "The Hunt" but doesn't generate the window
window = tkinter.Tk()
window.title("The Hunt!")
#This sets the background colour
window.configure(background="#1C3F95")
#This generates labels and buttons that are the same or similar colour to the background
welcome = tkinter.Label(window, text="Welcome to the Hunt!", bg="#1C3F95")
begin = tkinter.Button(window, text="Click here to begin", bg="#1C7C95")
#This is my code for the question generation. As I made that for a pygame window, I obviously had to change it slightly
questions = ["What species of bird is also a nickname for New Zealand?", "Which Twins can you play as in Assassin's Creed Syndicate?",
"Which year was 'Killing In The Name' Christmas Number one?"]
answers = [["kiwi", "Kiwi", "Falcon", "Sparrow", "Crow"], ["frye", "Frye", "Bank", "Green", "Bundy"], ["2009", "2009",
"1999", "1993",
"2004"]]
#I had to do it in two separate lists as it's easier to work with later on
# Also I made the correct answers non-case sensitive to make it easier to test.
r = len(questions)
score = 0
s = random.randrange(0, r, 1)
#This generates a random number within the range of how many questions there are
# and then prints out that question
#This generates a label that displays the randomly generated question
question = tkinter.Label(window, text=questions[s])
list = answers[s]
output = []
for i in range(1, 5):
output.append(answers[s][i])
shuffle(output)
# this takes the answers that correspond with the randomly generated question and shuffles the answers
# I did this as otherwise, the answer would always be the first answer to appear and the player could exploit this
#This code is what displays the labels and buttons on the window. It lets the computer decide where the best place for
#each component is
welcome.pack()
begin.pack()
question.pack()
for i in output:
answer = tkinter.Button(window, text=i, command=lambda answer = i: check_answer(i))
answer.pack()
#I had decided to pack the answers like this as it was easier than typing out each element of the list and also
#more efficent
window.mainloop()
#this is the code that actually generates the window
Starting at the top, let's change your check_answer definition to not create a new label every time:
def check_answer(answer):
if answer == answers[s][0] or answer == answers[s][1]:
global score
score += 1
lbl["text"] = score
Next, we need one small change in your for loop: we want to send answer, not i:
for i in output:
answer = tkinter.Button(window, text=i, command=lambda answer = i: check_answer(answer))
answer.pack()
lbl = tkinter.Label(window, text=score)
lbl.pack()
Lastly, we'll add that label that we removed earlier down to the bottom where you had it initially. You can change the location of this by packing it sooner in the code for aesthetics. Your code still doesn't cycle to a new question once one is answered (correctly or otherwise), but at least now you can see when the user answers correctly.
Hope this helps.
First of all, you did a small error in the lambda callback:
command=lambda answer=i: check_answer(answer)
It should be.
Then for the many labels, create one label and just change the text:
def check_answer(answer):
print(answer)
if answer == answers[s][0] or answer == answers[s][1]:
global score
score += 1
lbl.configure(text=str(score))
(much code i did not copy)
for i in output:
answer = tkinter.Button(window, text=i, command=lambda answer=i: check_answer(answer))
answer.pack()
lbl = tkinter.Label(window, text=score)
lbl.pack()

Multiple choice game in Python using Tkinter, Counting correct answers

I am working on a group project where we must create a simple program and we have chosen to make a multiple choice game using Tkinter. We have constructed most of the game already, but are having a problem when keeping a count of the correct answers. We are using Radiobuttons to list the answers for each question, however if the user clicks the button more than once it keeps incrementing the count as many times as they click it. Here is the code that we have. Please excuse the messiness, as we have not quite gone through to clean it up, as well as it is a bit of a beginner project and we are not the most experienced group of programmers.
(I am purposefully not including the complete code because the file paths for the images we have are directly linked to the home computer so they would not be able to be used anyways)
root = Tk()
counter = 0
d = ''
var = StringVar()
def next():
global i,img,groups,listanswer, questions, randint, key,d, counter
s = randint(1,4)
key = random.choice(list(questions.keys()))
img = ImageTk.PhotoImage(Image.open(key))
panel = Label(root, image = img)
panel.grid(column=0, row=0)
b = []
c = listanswer.index(str(questions.get(key)))
d = listanswer[c]
b.append(d)
listanswer.remove(d)
def selection():
global counter, d, sel
sel = str(var.get())
if sel == d:
counter +=1
i=1
while i<5:
a=random.choice(listanswer)
b.append(a)
if s!=i:
Radiobutton(root, text=a, padx=20,variable=var,
value=a,command=selection).grid(column=0, row=i)
listanswer.remove(a)
i+=1
R1 = Radiobutton(root, text=d, padx=20,variable=var, value=d,command =
selection).grid(column=0, row=s)
listanswer=listanswer+b
questions.pop(key)
counterlabel.configure(text='%g' %counter)
counterlabel=Label(root,width=8)
counterlabel.grid(column=1, row=5)
counterval=Label(root, width=10, text='Correct:')
counterval.grid(column=0,row=5)
next=Button(root,text='next',command=next)
next.grid(column=2, row=2)
var = IntVar()
label = Label(root)
label.grid()
root.mainloop()
If I understood the correctly every time you click on the radiobutton the code will check if that answer is correct. If it is, you increase the counter.
Instead, I recommend checking all answers when any of the radiobuttons is clicked, and set the counter accordingly (i.e. the counter resets every time you click).
Hopefully this helps!

Categories

Resources