Tkinter keyboard simulator - python

I need the dif () function to compose text of different lengths from a dictionary depending on the complexity.
More precisely, I need to somehow change k when choosing the complexity.
def dif():
global start_time
message.pack()
text_widget.pack()
start_time = time.time()
global test_text
with open("words.txt", "r") as words:
test_words1 = choices(list(words), k)
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(root, 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()
The command1 () function is executed if the start button is pressed
def command1():
if var.get() == 0:
k=10
dif()
elif var.get() == 1:
k=15
dif()
elif var.get() == 2:
k=20
dif()
root.deiconify()
top.destroy()

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()

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

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()

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()

How do I run two pieces of Python code simultaneously?

My A-level project is an alarm system I have built using Tkinter that calculates the nearby traffic and changes your alarm time depending on how much the traffic will slow down or increase your journey.
I have calculated all the times I need, however, now I face the problem of having to constantly poll the current time to check it against my own, but this stops my tkinter functions from running. I am now fearing I should have used a different object orientated language.
How can I run these functions at the same time?
My code is below (I'm sure it is very inefficient).
def __init__(self, master = None): #initialising the frame setup for windows
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
global lb,a,n
self.master.title("Alarm")
self.pack(fill=BOTH, expand =1)
newButton = Button(self, text="New Alarm", command=self.new_window) #create buttons and link to commands
newButton.place(x=50, y=50)
deleteButton = Button(self, text="Delete Alarm", command = self.alarmDelete)
deleteButton.place(x=250, y=50)
n=0 #loop through to find out how many rows are in the database
for row in c.execute('SELECT Start Destination FROM stocks '):
n = n + 1
i=0
remove=")"
removed="("
removing=","
remover="'"
a = [[0] * 14 for i in range(n)] #load database into multidimensional array
for row in c.execute('SELECT Start Destination FROM stocks '):
a[i][0]= row
temp=""
for j in str(a[i][0]): #remove unwanted characters from vars
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][0]=temp
i = i + 1
i=0
for row in c.execute('SELECT End Destination FROM stocks '):
a[i][1]= row
temp=""
for j in str(a[i][1]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][1]=temp
i = i + 1
i=0
for row in c.execute('SELECT hArrival FROM stocks '):
a[i][2]= row
temp=""
for j in str(a[i][2]):
if j==remove or j == removed or j == removing or j==remover :
null=""
else:
temp=temp + str(j)
a[i][2]=temp
i = i + 1
i=0
for row in c.execute('SELECT mArrival FROM stocks '):
a[i][3]= row
temp=""
for j in str(a[i][3]):
if j==remove or j == removed or j == removing or j == remover:
null=""
else:
temp=temp + str(j)
a[i][3]=temp
i = i + 1
i=0
for row in c.execute('SELECT Preperation Time FROM stocks '):
a[i][4]= row
temp=""
for j in str(a[i][4]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][4]=temp
i = i + 1
i=0
for row in c.execute('SELECT Day Date FROM stocks '):
a[i][5]= row
temp=""
for j in str(a[i][5]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][5]=temp
i = i + 1
i=0
for row in c.execute('SELECT Month Date FROM stocks '):
a[i][6]= row
temp=""
for j in str(a[i][6]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][6]=temp
i = i + 1
i=0
for row in c.execute('SELECT Year Date FROM stocks '):
a[i][7]= row
temp=""
for j in str(a[i][7]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][7]=temp
i = i + 1
i=0
for row in c.execute('SELECT AlarmName FROM stocks '):
a[i][10]= row
temp=""
for j in str(a[i][10]):
if j==remove or j == removed or j == removing or j ==remover :
null=""
else:
temp=temp + str(j)
a[i][10]=temp
i = i + 1
i=0
for i in range(n):#convert times and dates to timestamp and datestamps
a[i][8] = int(a[i][2])*3600 + int(a[i][3])*60
a[i][9] = str(a[i][6]) + "/" + str(a[i][5]) + "/" + str(a[i][7])
i=i+1
i=0
for i in range(n): #set all boolean value to true for later validation in calc
a[i][12] = "00:00"
a[i][12] = datetime.strptime(a[i][12], '%H:%M').time()
i=i+1
for i in range(n): #set all boolean value to true for later validation in calc
a[i][13] = 0
i=i+1
i=0
lb=Listbox(root) #create listbox and insert values
lb.pack()
for i in range(n):
for item in [str(a[i][10])]:
lb.insert(END, item)
i=i+1
lb.bind('<Double-Button-1>', Window.alarmInfo) #if list item is double clicked call alarmInfo
Window.alarmCalc(self) #call calculations
def alarmInfo(self): #finds out which listbox item was selcted and prints info about it
global lb,a,n
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
window = Toplevel(root)
window.geometry("200x150")
Label(window, text="Start Destination:").grid(row=0, sticky=W)
Label(window, text=a[i][0]).grid(row=0,column=1, sticky=W)
Label(window, text="End Destination:").grid(row=1, sticky=W)
Label(window, text=a[i][1]).grid(row=1,column=1, sticky=W)
Label(window, text="Arrival Time:").grid(row=2, sticky=W)
Label(window, text=a[i][2] + ":" + a[i][3]).grid(row=2,column=1, sticky=W)
Label(window, text="Preperation Time:").grid(row=3, sticky=W)
Label(window, text=a[i][5]).grid(row=3,column=1, sticky=W)
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
Label(window, text=a[i][9]).grid(row=4,column=1, sticky=W)
Label(window, text="Alarm Name:").grid(row=5, sticky=W)#
Label(window, text=a[i][10]).grid(row=5,column=1, sticky=W)
def alarmDelete(self):
global a,n,lb
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
for row in c.execute('SELECT AlarmName FROM stocks '): #deletes selected item from database
temp = row
if listName in temp:
c.execute('DELETE FROM stocks WHERE AlarmName=?', (listName,))
conn.commit()
break
def new_window(self): #create new window, and initialise layout
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
window = Toplevel(root)
window.geometry("550x300")
Label(window, text="Start Destination").grid(row=0, sticky=W)
Label(window, text="End Destination").grid(row=1, sticky=W)
Label(window, text="Arrival Time").grid(row=2, sticky=W)
Label(window, text=":").grid(row=2, column=2, sticky=W)
Label(window, text="Preperation Time").grid(row=3, sticky=W)
Label(window, text="Alarm Name").grid(row=5, sticky=W)#
eSd = Entry(window, width=5)
eEd = Entry(window,width=5)
eAth = Spinbox(window, from_=0, to=23)
eAtm = Spinbox (window, from_=0, to=59)
eDd = Spinbox (window, from_=1, to=31)
eDm = Spinbox (window, from_=1, to=12)
eDy = Spinbox (window, from_=2017, to=2019)
ePt = Entry(window,width=5)
eAn = Entry(window, width=20)
eSd.grid(row=0, column=1, sticky=W)
eEd.grid(row=1, column=1, sticky=W)
eAth.grid(row=2, column=1, sticky=W)
eAtm.grid(row=2,column=3, sticky=W)
ePt.grid(row=3, column=1, sticky=W)
eAn.grid(row=5, column=1, sticky=W)#
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
eDd.grid(row = 4,column=3, sticky=W)
Label(window, text="/").grid(row = 4,column=2, sticky=W)
eDm.grid(row = 4,column=1, sticky=W)
Label(window, text="/").grid(row = 4,column=4, sticky=W)
eDy.grid(row = 4,column=5, sticky=W)#
createButton = Button(window, text ="Create", command = self.create) #link to def create()
createButton.place(x =50,y=150)
def create(self):
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an
val1 = False
val2 = False
val3 = True
error=""
sd = eSd.get()
ed = eEd.get()
ath = eAth.get()
atm = eAtm.get()
pt = ePt.get()
Dd = eDd.get()
Dm = eDm.get()
Dy = eDy.get()
an = eAn.get()#
with open('zipcode.csv') as csvfile: #check through csv file to validate zipfiles
reader = csv.reader(csvfile)
for row in reader:
for col in row:
if col == sd:
val1= True
if col ==ed:
val2 = True
if len(pt) < 5: #validate pt
try:
val3 = int(pt)
except ValueError:
val3 = False
else:
val3 = False
if val1 == False and val2 == False and val3 == False: #Compare boolean values to generate correct error message
error = "Invalid Prep Time and Zipcodes"
elif val1 == False and val3 == False :
error = "Invalid Prep Time and Start Zipcode"
elif val1 == False and val2 == False :
error = "Invalid Zipcodes"
elif val2==False and val3==False:
error= "Invalid Prep Time and End Zipcode"
elif val1 == False:
error="Invalid Start Zipcode"
elif val2==False:
error="Invalid End Zipcode"
elif val3==False:
error = "Invalid Prep Time"
if val1 == False or val2 == False or val3 == False: #call different function depending on errors
Window.valEr(self,error)
else:
Window.addList(self)
def valEr(self, error): #displays error message
window = Toplevel(root)
window.geometry("100x100")
Label(window, text=error).place(x=40, y=40)
def addList(self):
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an#
if len(ath)< 2: #add preceeding 0's to single values to make calculations easier
ath = "0" + ath
if len(atm) < 2:
atm = "0" + atm
if len(Dm) < 2:
Dm = "0" + Dm
if len(Dd) <2:
Dd = "0" + Dd
pt = int(pt) * 60
writeTo = (sd,ed,ath,atm,pt,Dd,Dm,Dy,an) #create tuple to make writing to database easier
c.execute("INSERT INTO stocks VALUES(?,?,?,?,?,?,?,?,?)", writeTo) #insert data into database
conn.commit()
#################################################################################
def alarmCalc(self):
global a,n
x=1000000000000000000000000
i=0
nowDate = date.today()
temp =""
temp2 = ""
nowDate = str(nowDate.month) + "/" + str(nowDate.day) + "/" + str(nowDate.year) #get todays date
for i in range(n):
if nowDate == a[i][9]:
Link= 'https://www.mapquestapi.com/directions/v2/route?key=YCGaovp1Y6fRO5f1RVWv2c1Qs9F4qF1N&from='+str(a[i][0])+'%2C+NY&to='+str(a[i][1])+'%2C+NY&outFormat=json&routeType=fastest&avoidTimedConditions=true&narrativeType=none'
response = requests.get(Link)
data = json.loads(response.text)
rawtravelTime =int( data["route"]["time"]) #request and retrieve correct time
#print(rawtravelTime)
a[i][11]= int(a[i][8]) - int(a[i][4]) - rawtravelTime #calculate time in seconds
#print(a[i][11])
m, s = divmod(a[i][11], 60) # convert seconds to time using quotients
h, m = divmod(m, 60)
a[i][11]= str("%d:%02d:%02d" % (h, m, s))
a[i][11] = a[i][11][:-3] #validation of time string
if len(a[i][11]) < 5:
a[i][11] = "0" + a[i][11]
a[i][11] = datetime.strptime(a[i][11], '%H:%M').time() #turn into datetime object
#print(a[i][11])
nowTime = datetime.now().strftime('%H:%M') #get current time
nowTime = datetime.strptime(nowTime, '%H:%M').time()
#print(nowTime)
if a[i][11] < nowTime or a[i][11] == nowTime or x < (10*3600) : #if alarm time = or exceeds current time call alarmTrig
Window.alarmTrig(self)
else:
#print("NO")
a[i][12] = datetime.combine(date.min, a[i][11]) - datetime.combine(date.min, nowTime)
temp = str(a[i][12])
print(temp)
if len(temp) > 7: # gets time left in seconds
temp2 = temp[4:6]
temp = temp[:2]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
else:
temp2 = temp[2:4]
temp = temp[:1]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
# i=i+1
else:
# i=i+1
print("not date")
for i in range(n): #finds smallest time
if int(a[i][13]) < int(x):
x=int(a[i][13])
print(x)
time.sleep(x/2) #make it wait half the time before recalc
Window.alarmCalc
def alarmTrig(self):
print("TRIG")
winsound.PlaySound("*", winsound.SND_ALIAS)
#Delete alarm

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"])

Categories

Resources