How to pass a changing value through lambda in a "KeyRelease" function? - python

I would like to change the score label every time the user types in the correct answer but when I type in the correct answer the score increases to 10 but the expected new answer of the next equation generated won't change and stays at the initial value it started at because the "check" function receives the "ans" variable which is assigned before.
How can I fix that problem?
def check(ans, text:tkinter.Text,score,current_stage,q_num,eq, event=None):
ans = calc(eq)
print(f"real answear = {ans}")
temp = str(text.get("0.0", "end").strip())
print(f"my answear = {temp}")
if str(text.get("0.0", "end").strip()) == str(ans):
is_correct = True
else:
is_correct = False
if is_correct:
ans = calc(eq)
score += 10
q_num += 1
inputtxt.delete(1.0,END)
eq = generate_equation(stage=current_stage)
ans = calc(eq)
score_label_new = tkinter.Label(master=master, text=f"Score: {score}").grid(row=0, column=1, sticky=W)
question_label_new = tkinter.Label(master=master, text=f"{q_num}: {eq}").grid(row=0, column=0, sticky=W)
stage_label_new = tkinter.Label(master = master,text=f"Stage: {current_stage}").grid(row=0, column= 3,sticky=W)
if score % 100 == 0:
current_stage += 1
else:
inputtxt.grid()
master = tkinter.Tk()
master.title("Math")
master.geometry('400x400')
eq = generate_equation(stage=current_stage)
ans = calc(eq)
score_label = tkinter.Label(master=master, text=f"score: {score}").grid(row=0, column=1, sticky=W)
question_label = tkinter.Label(master=master, text=f"{q_num}: {eq}").grid(row=0, column=0, sticky=W)
stage_label = tkinter.Label(master = master,text=f"Stage: {current_stage}").grid(row=0, column= 3,sticky=W)
inputtxt = tkinter.Text(master=master, height=5, width=20)
inputtxt.bind("<KeyRelease>",
lambda
ans=ans,
text=inputtxt,
score = score,
current_stage = current_stage,
q_num=q_num,
eq = eq:
#linked ==>
check(ans, text,score,current_stage,q_num,eq))
inputtxt.grid()
master.mainloop()

This does what you want. You do NOT want to capture any of those globals in your lambda; you always want to refer to the globals themselves. It might be better to store your state info in a state class of some kind, so that you aren't literally using globals, but this works. Note that I had to fake your calc and generate_equation functions, since you didn't give us a complete, runnable example:
import tkinter
from tkinter import W,END
import random
def calc(eq):
return int(eq)
def generate_equation(stage=0):
return str(random.randint(0,100))
current_stage = 1
score = 0
q_num = 1
def check(text:tkinter.Text, event=None):
global eq
global score
global q_num
global current_stage
ans = calc(eq)
print(f"real answear = {ans}")
temp = str(text.get("0.0", "end").strip())
print(f"my answear = {temp}")
if str(text.get("0.0", "end").strip()) == str(ans):
is_correct = True
else:
is_correct = False
if is_correct:
score += 10
q_num += 1
inputtxt.delete(1.0,END)
eq = generate_equation(stage=current_stage)
score_label_new = tkinter.Label(master=master, text=f"Score: {score}").grid(row=0, column=1, sticky=W)
question_label_new = tkinter.Label(master=master, text=f"{q_num}: {eq}").grid(row=0, column=0, sticky=W)
stage_label_new = tkinter.Label(master = master,text=f"Stage: {current_stage}").grid(row=0, column= 3,sticky=W)
if score % 100 == 0:
current_stage += 1
else:
inputtxt.grid()
master = tkinter.Tk()
master.title("Math")
master.geometry('400x400')
eq = generate_equation(stage=current_stage)
ans = calc(eq)
score_label = tkinter.Label(master=master, text=f"score: {score}").grid(row=0, column=1, sticky=W)
question_label = tkinter.Label(master=master, text=f"{q_num}: {eq}").grid(row=0, column=0, sticky=W)
stage_label = tkinter.Label(master = master,text=f"Stage: {current_stage}").grid(row=0, column= 3,sticky=W)
inputtxt = tkinter.Text(master=master, height=5, width=20)
inputtxt.bind("<KeyRelease>", lambda ev: check(inputtxt,ev))
inputtxt.grid()
master.mainloop()
Here's a version that uses a simple class. I also changed it to update the text in your three labels instead of creating new controls each time.
import tkinter
from tkinter import W,END
import random
def calc(eq):
return int(eq)
def generate_equation(stage=0):
return str(random.randint(0,100))
class State:
current_stage = 1
score = 0
q_num = 1
eq = generate_equation(stage=current_stage)
def check(self, text:tkinter.Text, event=None):
ans = calc(self.eq)
print(f"real answer = {ans}")
temp = text.get("0.0", "end").strip()
print(f"my answer = {temp}")
is_correct = text.get("0.0", "end").strip() == str(ans)
if is_correct:
self.score += 10
self.q_num += 1
inputtxt.delete(1.0,END)
self.eq = generate_equation(stage=self.current_stage)
score_label.configure(text=f"Score: {state.score}")
question_label.configure(text=f"{state.q_num}: {state.eq}")
stage_label.configure(text=f"Stage: {state.current_stage}")
if self.score % 100 == 0:
self.current_stage += 1
else:
inputtxt.grid()
state = State()
master = tkinter.Tk()
master.title("Math")
master.geometry('400x400')
score_label = tkinter.Label(master=master, text=f"score: {state.score}")
score_label.grid(row=0, column=1, sticky=W)
question_label = tkinter.Label(master=master, text=f"{state.q_num}: {state.eq}")
question_label.grid(row=0, column=0, sticky=W)
stage_label = tkinter.Label(master = master,text=f"Stage: {state.current_stage}")
stage_label.grid(row=0, column= 3,sticky=W)
inputtxt = tkinter.Text(master=master, height=5, width=20)
inputtxt.bind("<KeyRelease>", lambda ev: state.check(inputtxt,ev))
inputtxt.grid()
master.mainloop()

Related

How can I delete a Tkinter label without binding it to a button?

My program has a temporary label that needs to be removed when the user types in the first correct answer because a new label is supposed to replace the initial one.
I tried using the "destroy" method without success.
Can someone help me remove the "score_label" inside the "check" function?
def check(text:tkinter.Text, event=None):
global remove_label
global eq
global score
global q_num
global current_stage
ans = calc(eq)
print(f"real answear = {ans}")
temp = str(text.get("0.0", "end").strip())
print(f"my answear = {temp}")
if str(text.get("0.0", "end").strip()) == str(ans):
is_correct = True
remove_label += 1
else:
is_correct = False
if is_correct:
score += 10
q_num += 1
inputtxt.delete(1.0,END)
eq = generate_equation(stage=current_stage)
score_label = tkinter.Label(master=master, text=f"score: {score}",font=my_font,fg="white",bg='#08241c') .grid(row=2, column=2,sticky=W)
question_label = tkinter.Label(master=master, text=f"{q_num}: {eq}",font=my_font,fg="white",bg='#08241c') .grid(row=2, column=5,sticky=W)
stage_label = tkinter.Label(master=master,text=f"Stage: {current_stage}",font=my_font,fg="white",bg='#08241c').grid(row=2, column=3,sticky=W)
inputtxt.grid(row=3,column=4,sticky=W,ANCHOR=CENTER)
if score % 100 == 0:
current_stage += 1
else:
inputtxt.grid(row=3,column=4,sticky=W)
master = tkinter.Tk()
master.title("Math")
master.geometry('800x569')
background_image=tkinter.PhotoImage(file="C:\\Users\\guyzv\\Desktop\\New folder\\greenboard.png")
background_label = tkinter.Label(master, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
eq = generate_equation(stage=current_stage)
ans = calc(eq)
my_font = tkFont.Font(family="Bradley Hand ITC", size=30)
score_label = tkinter.Label(master=master, text=f"score: {score}",font=my_font,fg="white",bg='#08241c').grid(row=2, column=2,sticky=W)
question_label = tkinter.Label(master=master, text=f"{q_num}: {eq}",font=my_font,fg="white",bg='#08241c').grid(row=2, column=5,sticky=W)
stage_label = tkinter.Label(master = master,text=f"Stage: {current_stage}",font=my_font,fg="white",bg='#08241c').grid(row=2, column= 3,sticky=W)
inputtxt = tkinter.Text(master=master, height=1, width=10,font=my_font,fg="white",bg='#08241c')
inputtxt.bind("<KeyRelease>", lambda ev: check(inputtxt,ev))
inputtxt.grid(row=3,column=4,sticky=W)
master.mainloop()

unit testing a tkinter application

Someone can suggest how you can make simple tests here.
This is a simple keyboard trainer on tkinter, a window appears where you can select the difficulty level and start the game.
Or if you can give a link to a resource with explanations
from tkinter import *
import sys
import time
from random import choices
root = Tk() # Создаем основное окно
top = Toplevel() # Создаем окно для выбора сложности
# добавляем виджеты в окно выбора сложности
var = IntVar()
Radiobutton(top, text='Легкая', variable=var, value=0).pack()
Radiobutton(top, text='Нормальная', variable=var, value=1).pack()
Radiobutton(top, text='Сложная', variable=var, value=2).pack()
button1 = Button(top, text="Играть", command=lambda: command()).pack()
button2 = Button(top, text="Выйти", command=lambda: command2()).pack()
def command():
global test_words1
if var.get() == 0:
with open("words.txt", "r") as words:
test_words1 = choices(list(words), k=1)
dif()
elif var.get() == 1:
with open("words.txt", "r") as words:
test_words1 = choices(list(words), k=2)
dif()
elif var.get() == 2:
with open("words.txt", "r") as words:
test_words1 = choices(list(words), k=3)
dif()
pos = 0
b = 0
mistakes = 0
correct_presses = 0
def key_type(e):
if e.keycode != 16:
global pos, text_widget, b, mistakes, correct_presses
if (test_text[pos] != e.char):
text_widget.tag_add("wrong", str(1) + "." + str(b))
mistakes += 1
if (test_text[pos] == e.char):
text_widget.tag_add("correct", str(1) + "." + str(b))
correct_presses += 1
b += 1
pos += 1
if (pos == len(test_text)):
end_time = time.time()
rav=end_time-start_time
label1 = Label(root2,text="NICE!", fg="#eee", bg="#957")
label1.pack()
label2 = Label(root2, text="TIME:", fg="#eee", bg="#957")
label2.pack()
label0 = Label(root2,text=rav, fg="#eee", bg="#957")
label0.pack()
def dif():
root.withdraw()
top.destroy() # Уничтожаем окно выбора сложност
global root2
root2 = Tk() # Создаем основное окно
root2.deiconify() # Показываем основное окно
top.destroy() # Уничтожаем окно выбора сложности
global start_time
start_time = time.time()
global test_text
global text_widget
len_word_list = [len(word.strip()) for word in test_words1]
index_nostrip1 = 6
end_of_line1 = 0
final_word_list1 = []
lines_list1 = []
line1 = ""
for i in range(len(test_words1)):
if end_of_line1 == index_nostrip1 - 1:
final_word_list1.append(test_words1[i])
line1 += test_words1[i].strip()
lines_list1.append(line1)
line1 = ""
end_of_line1 = 0
else:
final_word_list1.append(test_words1[i].strip())
line1 += f"{test_words1[i].strip()} "
end_of_line1 += 1
# create the final string to be used in the test
test_text = " ".join(final_word_list1)
text_widget = Text(root2, height=10, width=100,
padx=20, pady=20, font=("Arial ", 16))
text_widget.insert(END, test_text)
text_widget.configure(state="disabled")
text_widget.tag_config("correct", background="green", foreground="white")
text_widget.tag_config("wrong", background="red", foreground="white")
text_widget.bind("<KeyPress>", key_type)
text_widget.focus()
text_widget.pack()
message = Label(root,
text="Start typing",
font=("Arial ", 24))
message.pack()
root2.mainloop()
# эта команда выполняется по кнопке Выйти
def command2():
top.destroy() # Уничтожаем окно выбора сложности
root.destroy() # Уничтожаем основное окно
sys.exit() # Выходим из программы
root.withdraw() # Скрываем основное окно, пока показываем окно выбора сложности
root.mainloop()
I have already tried to write something similar, but the tests do not pass
class TKinterTestCase(unittest.TestCase):
def setUp(self):
self.root=tkinter.Tk()
self.pump_events()
def tearDown(self):
if self.root:
self.root.destroy()
self.pump_events()
def pump_events(self):
while self.root.mainloop(_tkinter.ALL_EVENTS | _tkinter.DONT_WAIT):
pass
if __name__ == '__main__':
unittest.main()

No matter where I put "score = 0" It ignores it and comes up with an error about local variable used before assignment

On the python debugger the score is read first and I have tried globalising it to see if anything would work. Also I know the code is messy and there are better ways of doing it but I just want to solve this problem first. This is my first time using stack overflow so I don't know how to link the zip folders to the question if you are wanting to run the code. The folders contain PNG images which are named what is in the array. That bit works without any problems. This is also my first time using tkinter.
global score
score = 0
from tkinter import *
from PIL import ImageTk, Image
from random import randint
import os
root = Tk()
root.title("Flashcard")
#root.iconbitmap('c:/')
root.geometry("500x500")
global dir_path
dir_path = os.path.dirname(os.path.realpath(__file__))
def score0():
score = 0
def scoreadd():
score = score+1
def scoreminus():
score = score-1
def checkcorrectcs(comp_questions, random_number,):
answer = answer_input.get()
answer = answer.replace(" ", "")
if answer.lower() == comp_questions[random_number]:
checked = "Correct"
scoreadd()
else:
checked = "Incorrect it was " + comp_questions[random_number].title()
scoreminus()
answer_label.config(text=checked)
def checkcorrectmaths(maths, random_number2,):
answer = answer_input.get()
answer = answer.replace(" ", "")
if answer.lower() == math_questions[random_number2]:
checked = "Correct"
scoreadd()
else:
checked = "Incorrect it was " + math_questions[random_number2].title()
scoreminus()
answer_label.config(text=checked)
def checkcorrectph(physics_questions, random_number3,):
answer = answer_input.get()
answer = answer.replace(" ", "")
if answer.lower() == physics_questions[random_number3]:
checked = "Correct"
scoreadd()
else:
checked = "Incorrect it was " + physics_questions[random_number3].title()
scoreminus()
answer_label.config(text=checked)
def checkcorrectbio(biology_questions, random_number4,):
answer = answer_input.get()
answer = answer.replace(" ", "")
if answer.lower() == biology_questions[random_number4]:
checked = "Correct"
scoreadd()
else:
checked = "Incorrect it was " + biology_questions[random_number4].title()
scoreminus()
answer_label.config(text=checked)
def checkcorrectchem(chemistry_questions, random_number5,):
answer = answer_input.get()
answer = answer.replace(" ", "")
if answer.lower() == chemistry_questions[random_number5]:
checked = "Correct"
scoreadd()
else:
checked = "Incorrect it was " + chemistry_questions[random_number5].title()
scoreminus()
answer_label.config(text=checked)
#Computer science function
def computer_science():
hide_any_windows()
computer_science_window.pack(fill="both",expand=1)
title = Label(computer_science_window, text="Computer science").pack()
comp_questions = ["and", "binary", "denary", "hexadecimal", "or"]
random_number = randint(0, len(comp_questions)-1)
random_comp_question = f"{dir_path}/ComputerScienceQuestionBank/" + comp_questions[random_number] +".png"
global comp_question_photo
comp_question_photo = ImageTk.PhotoImage(Image.open(random_comp_question))
show_comp_question = Label(computer_science_window, image=comp_question_photo)
show_comp_question.pack(pady=15)
#answer box
global answer_input
answer_input = Entry(computer_science_window, font=("Comic Sans", 20))
answer_input.pack(pady = 15)
confirm_button = Button(computer_science_window, text ="Confirm", command=lambda: checkcorrectcs(comp_questions, random_number))
confirm_button.pack(pady=5)
random_button = Button(computer_science_window, text= "New question", command=computer_science)
random_button.pack(pady=10)
global answer_label
answer_label = Label(computer_science_window, text="")
answer_label.pack(pady=15)
#Maths function
def maths():
hide_any_windows()
maths_window.pack(fill="both",expand=1)
title = Label(maths_window, text="Maths").pack()
math_questions = ["144", "test2"]
random_number2 = randint(0, len(math_questions)-1)
random_math_question = f"{dir_path}/MathQuestionBank/" + math_questions[random_number2] +".png"
global math_question_photo
math_question_photo = ImageTk.PhotoImage(Image.open(random_math_question))
show_math_question = Label(maths_window, image=math_question_photo)
show_math_question.pack(pady=15)
#answer box
global answer_input
answer_input = Entry(maths_window, font=("Comic Sans", 20))
answer_input.pack(pady = 15)
confirm_button = Button(maths_window, text ="Confirm", command=lambda: checkcorrectcs(math_questions, random_number2))
confirm_button.pack(pady=5)
random_button = Button(maths_window, text= "New question", command=maths)
random_button.pack(pady=10)
global answer_label
answer_label = Label(maths_window, text="")
answer_label.pack(pady=15)
#Physics function
def physics():
hide_any_windows()
physics_window.pack(fill="both",expand=1)
title = Label(physics_window, text="Maths").pack()
physics_questions = ["9.81", "test3", "quarks", "speedoflight"]
random_number3 = randint(0, len(physics_questions)-1)
random_physics_question = f"{dir_path}/PhysicsQuestionBank/" + physics_questions[random_number3] +".png"
global physics_question_photo
physics_question_photo = ImageTk.PhotoImage(Image.open(random_physics_question))
show_physics_question = Label(physics_window, image=physics_question_photo)
show_physics_question.pack(pady=15)
#answer box
global answer_input
answer_input = Entry(physics_window, font=("Comic Sans", 20))
answer_input.pack(pady = 15)
confirm_button = Button(physics_window, text ="Confirm", command=lambda: checkcorrectph(physics_questions, random_number3))
confirm_button.pack(pady=5)
random_button = Button(physics_window, text= "New question", command=physics)
random_button.pack(pady=10)
global answer_label
answer_label = Label(physics_window, text="")
answer_label.pack(pady=15)
#Biology function
def biology():
hide_any_windows()
biology_window.pack(fill="both",expand=1)
title = Label(biology_window, text="Biology").pack()
biology_questions = ["test3", "test4"]
random_number4 = randint(0, len(biology_questions)-1)
random_biology_question = f"{dir_path}/BiologyQuestionBank/" + biology_questions[random_number4] +".png"
global biology_question_photo
biology_question_photo = ImageTk.PhotoImage(Image.open(random_biology_question))
show_biology_question = Label(biology_window, image=biology_question_photo)
show_biology_question.pack(pady=15)
#answer box
global answer_input
answer_input = Entry(biology_window, font=("Comic Sans", 20))
answer_input.pack(pady = 15)
confirm_button = Button(biology_window, text ="Confirm", command=lambda: checkcorrectbio(biology_questions, random_number4))
confirm_button.pack(pady=5)
random_button = Button(biology_window, text= "New question", command=biology)
random_button.pack(pady=10)
global answer_label
answer_label = Label(biology_window, text="")
answer_label.pack(pady=15)
#Chemistry function
def chemistry():
hide_any_windows()
chemistry_window.pack(fill="both",expand=1)
title = Label(chemistry_window, text="Chemistry").pack()
chemistry_questions = ["jameschadwick", "loweractivationenergy", "mendeleev", "postive", "protondonors",]
random_number5 = randint(0, len(chemistry_questions)-1)
random_chemistry_question = f"{dir_path}/ChemistryQuestionBank/" + chemistry_questions[random_number5] +".png"
global chemistry_question_photo
chemistry_question_photo = ImageTk.PhotoImage(Image.open(random_chemistry_question))
show_chemistry_question = Label(chemistry_window, image=chemistry_question_photo)
show_chemistry_question.pack(pady=15)
#answer box
global answer_input
answer_input = Entry(chemistry_window, font=("Comic Sans", 20))
answer_input.pack(pady = 15)
confirm_button = Button(chemistry_window, text ="Confirm", command=lambda: checkcorrectchem(chemistry_questions, random_number5))
confirm_button.pack(pady=5)
random_button = Button(chemistry_window, text= "New question", command=chemistry)
random_button.pack(pady=10)
global answer_label
answer_label = Label(chemistry_window, text="")
answer_label.pack(pady=15)
def hide_any_windows():
for widget in computer_science_window.winfo_children():
widget.destroy()
for widget in maths_window.winfo_children():
widget.destroy()
for widget in physics_window.winfo_children():
widget.destroy()
for widget in biology_window.winfo_children():
widget.destroy()
for widget in chemistry_window.winfo_children():
widget.destroy()
computer_science_window.pack_forget()
maths_window.pack_forget()
physics_window.pack_forget()
biology_window.pack_forget()
chemistry_window.pack_forget()
#menu
my_menu = Menu(root)
root.config(menu=my_menu)
#Subjects for the menu
subjects_menu = Menu(my_menu)
my_menu.add_cascade(label = "Subjects", menu=subjects_menu)
subjects_menu.add_command(label="Computer science", command=computer_science)
subjects_menu.add_command(label="Maths", command=maths)
subjects_menu.add_command(label="Physics", command=physics)
subjects_menu.add_command(label="Biology", command=biology)
subjects_menu.add_command(label="Chemistry", command=chemistry)
subjects_menu.add_separator()
subjects_menu.add_command(label="Exit", command=root.quit)
#Making the window
computer_science_window = Frame(root, width=500, height=500)
maths_window = Frame(root, width=500, height=500)
physics_window = Frame(root, width=500, height=500)
biology_window = Frame(root, width=500, height=500)
chemistry_window = Frame(root, width=500, height=500)
# all_windows = [computer_science_window, maths_window, physics_window, biology_window, chemistry_window]
root.mainloop()
You can either add a global declaration for the variable score in every function that modifies it. (easy and expedient, but not recommended)
score = 0
def score0():
global score
score = 0
def scoreadd():
global score
score = score + 1
def scoreminus():
global score
score = score - 1
or maybe create a small Score class to keep score: (recommended)
class Score:
def __init__(self):
self.score = 0
def increment(self):
self.score += 1
def decrement(self):
self.score -= 1
def reset(self):
self.score = 0
that you can use as follows:
the_score = Score()
the_score.increment()
the_score.decrement()
the_score.reset()

How can I get the text of a specific button in a list of buttons? I'm using Tkinter

I am currently making a Tic-Tac-Toe game, and I am working on trying to check if someone gets 3 of their pieces in a row, so I can tell them they've won. I'm trying to do that by checking the text of the buttons, to see if I've gotten 3 in a row. However, I don't know how to check the text of a specific button in a list. Does anyone have any ideas, or if there is a better way, can you let me know?
Full Code
import tkinter as tk
class TicTacToe(tk.Tk):
def __init__(self):
super().__init__()
# Vars
self.rounds_played = 0
self.wins = 0
self.losses = 0
self.player = 0
self.turn = 0
self.clicked_buttons = []
# Attributes
self.resizable(False, False)
self.attributes("-toolwindow", True)
# Start
self.game_title = tk.Label(text="Stew's Tic Tac Toe")
self.name_label = tk.Label(text="Choose a name\n(Press the \'Enter\' key to submit)")
self.name_entry = tk.Entry()
self.symbol_label = tk.Label(text="Choose your symbol")
self.symbol_buttons = [tk.Button(text="[X]", command=lambda: self.symbol_select(0)),
tk.Button(text="[O]", command=lambda: self.symbol_select(1))]
self.next = tk.Button(text="Next", command=self.next_button)
self.ready = tk.Button(text="Start", command=self.start_game_button)
self.game_title.grid(row=0)
self.name_label.grid(row=1)
self.name_entry.grid(row=2)
self.name_entry.bind("<Return>", lambda x: self.set_player_name(self.player))
def set_player_name(self, num):
if num == 0:
self.names = [self.name_entry.get()]
if self.names[0] == " ":
self.names = ["Player 1"]
print(self.names[0])
self.symbol_label.grid(row=3,)
self.symbol_buttons[0].grid(row=4, sticky=tk.W, padx=57.5)
self.symbol_buttons[1].grid(row=4, sticky=tk.E, padx=57.5)
elif num == 1:
self.names.append(self.name_entry.get())
if self.names[1] == "" or " ":
self.names.append("Player 2")
self.ready.grid(row=4)
def symbol_select(self, num):
if num == 0:
self.symbol = ["[X]",
"[O]"]
else:
self.symbol = ["[X]",
"[O]"]
self.next.grid(row=5)
def next_button(self):
self.player = 1
self.next.grid_forget()
self.name_entry.delete(0, tk.END)
self.symbol_label.grid_forget()
for x in self.symbol_buttons:
x.grid_forget()
def start_game_button(self):
self.game_title.grid_configure(row=0, column=1, columnspan=3)
self.whos_turn = tk.Label(text="{}\'s turn".format(self.names[0]))
self.whos_turn.grid(row=1, column=1, columnspan=3)
self.ready.grid_forget()
self.name_label.grid_forget()
self.name_entry.grid_forget()
self.game_buttons = [tk.Button(text="[ ]", command=lambda: self.move_update(0)),
tk.Button(text="[ ]", command=lambda: self.move_update(1)),
tk.Button(text="[ ]", command=lambda: self.move_update(2)),
tk.Button(text="[ ]", command=lambda: self.move_update(3)),
tk.Button(text="[ ]", command=lambda: self.move_update(4)),
tk.Button(text="[ ]", command=lambda: self.move_update(5)),
tk.Button(text="[ ]", command=lambda: self.move_update(6)),
tk.Button(text="[ ]", command=lambda: self.move_update(7)),
tk.Button(text="[ ]", command=lambda: self.move_update(8))]
num = 0
for r in range(0,3):
for c in range(0,3):
self.game_buttons[num].grid(row=(r%3 + 2), column=(c%3 + 1))
num = num + 1
self.rounds = tk.Label(text="Rounds Played: {}".format(self.rounds_played))
self.rounds.grid(row=5, column=1, columnspan=3)
def move_update(self, num):
if num not in self.clicked_buttons:
self.clicked_buttons.append(num)
self.turn = self.turn + 1
if self.turn%2 == 1:
self.game_buttons[num].config(text=self.symbol[0])
elif self.turn%2 == 0:
self.game_buttons[num].config(text=self.symbol[1])
# Here is where I am struggling
for x in range(0,8):
if self.game_buttons[x] == "[X]" and self.game_buttons[(x+3)%9]:
if self.game_buttons[(x+6)%9] == "[X]":
print("Winner")
# Here is where it ends
if self.turn == 9:
self.rounds_played = self.rounds_played + 1
self.rounds.configure(text="Rounds Played: {}".format(self.rounds_played))
self.play_again = tk.Button(text="Play Again?", command=self.new_game)
self.play_again.grid(row=6, column=1, columnspan=3)
def new_game(self):
self.turn = 0
game = TicTacToe()
game.mainloop()
Part I am struggling with
for x in range(0,8):
if self.game_buttons[x] == "[X]" and self.game_buttons[(x+3)%9]:
if self.game_buttons[(x+6)%9] == "[X]":
print("Winner")
I realize in this part I'm not finding the text, but I really don't know how to call upon both the specific list item and text.
Calling the element in a list which contains a tkinter Button widget will return the widget itself as if you were calling any other value stored in an element of a list. Meaning that if you wanted the text attribute of the value of the element you could use ["text"] or .cget("text").
See below:
from tkinter import *
root = Tk()
array = [Button(root, text="1"), Button(root, text="2"), Button(root, text="3")]
for i in array:
print(type(i))
print(i.cget("text"))
print(i["text"])

How can i erase contents in a Label?

Sorry for the mess
so I am making a seating chart, and I cant seem to get it working properly... again. I am trying to make the label reset every time i press the run button, any ideas?
#commands: add name , Run
#imports
import random
from time import sleep
from tkinter import *
#Console and background Handlers
Tables = 6
Names = []
def AddNames():
NewNames = e.get("1.0", 'end -1c')
if NewNames in Names:
print("Name Already exists")
elif NewNames == "":
print("Empty")
else:
Names.append(NewNames)
print(Names)
e.delete(1.0, END)
def Random():
RandomNum = random.randrange(Tables)
if RandomNum == 0:
RandomNum = random.randrange(Tables)
return RandomNum
def run():
X = 0
for i in Names:
#print(Names[X])
print("Table: " + str(Random()))
X += 1
#text = Label(popup, text = "")
text = Label(popup, text= Names[X] + "\n" + "Table: " + str(Random()))
text.pack()
#GUI Handler
root = Tk()
root.geometry("1024x768")
e = Text(root, bd = 10, font=("Comic Sans MS", 50) ,width = 15, height = 2)
e.pack()
popup = Toplevel()
popup.title("Seating Chart")
AddNameButton = Button(root, text = ("Add Name"), width = 15, height = 5, command = AddNames)
AddNameButton.pack()
RunButton = Button(root, text = ("Run"), width = 15, height = 5, command = run)
RunButton.pack()
root.mainloop()
I am trying to reset text every time the user presses the run button
import tkinter
from tkinter import ttk
import random
class MyApp:
def __init__(self):
self.root = tkinter.Tk()
self.seatwindow = None
self.root.title('Add Names')
self.currentname = tkinter.StringVar()
self._maxtables = tkinter.StringVar()
self.addednames = []
self.commandframe = ttk.Labelframe(self.root, text='Commands')
self.nameentry = ttk.Entry(self.root, textvariable=self.currentname)
self.addbutton = ttk.Button(self.root, text='Add Name', command=self.addname)
self.maxtablabel = ttk.Label(self.root, text='Tables: ')
self.maxtabentry = ttk.Entry(self.root, textvariable=self._maxtables)
self.genbutton = ttk.Button(self.commandframe, text='Run', command=self.generate)
self.resetbutton = ttk.Button(self.commandframe, text='Reset', command=self.reset)
self._maxtables.set('6')
self.nameentry.grid(row=0, column=0)
self.addbutton.grid(row=0, column=1, sticky='nsew')
self.maxtabentry.grid(row=1, column=1, sticky='nsw')
self.maxtablabel.grid(row=1, column=0, sticky='nse')
self.genbutton.grid(row=0, column=0, sticky='nsew')
self.resetbutton.grid(row=0, column=1, sticky='nsew')
self.commandframe.grid(row=2, column=0, columnspan=2, sticky='nsew')
self.nameentry.bind('<Return>', self.addname)
self.root.bind('<Control-Return>', self.generate)
def addname(self, event=None):
name = self.currentname.get()
if not(name == '' or name in self.addednames):
self.addednames.append(name)
self.currentname.set('')
else:
self.currentname.set('Name already added!')
def generate(self, event=None):
if not self.seatwindow == None:
self.seatwindow.destroy()
self.currentname.set('')
self.seatwindow = tkinter.Toplevel()
random.shuffle(self.addednames)
tables = []
for i in range(self.maxtables):
tableframe = ttk.Labelframe(self.seatwindow, text='Table ' + str(i + 1) + ':')
tableframe.grid(column=i, row=0, sticky='nsew')
tables.append(tableframe)
for index, name in enumerate(self.addednames):
namelabel = ttk.Label(tables[index%self.maxtables], text=name)
namelabel.grid(column=0, row=index//self.maxtables + 1)
def reset(self):
self.currentname.set('')
self.maxtables = 6
self.addednames = []
def run(self):
self.root.mainloop()
#property
def maxtables(self):
return int(self._maxtables.get())
MyApp().run()

Categories

Resources