I tried making a simple number checker that shows if the number is correct or wrong.
After some hastily written prototype code, I can't get the fields to clear.
I dug through many questions regarding this topic, but couldn't find an answer.
My attempt is in show_result()
What am I doing wrong?
It should accept the numbers, and with the last number; verify. If it's correct, show accepted-image, else show denied-image and clear Entries after wrong entry. And after 3 seconds remove the image.
I suspect the num_limit() function messes something up, but I can't figure what.
All other files can be found here: https://bytebitten.stackstorage.com/s/JeRD33P92Us4a1Li
from tkinter import *
import time
#####
# Variables
code_check = 0
codeLength = 4
list3 = 123, 456
list4 = 2345, 3452
#####
# System
root = Tk()
root.title('Code Verifier')
root.attributes('-fullscreen', True)
root.bind('<Escape>',lambda e: root.quit())
#####
# Functions
# Input limiter function (WIP)
def num_limit(p, this_field):
global codeLength
print("Entry" + this_field + ": " + p)
this_field = int(this_field)
entries = [entry1, entry2, entry3, entry4]
next_field = entries[this_field]
# Check if it's a number
if p.isdigit():
if this_field < codeLength:
# Set focus on next field
next_field.focus_set()
pass
else:
code_checker()
return True
else:
# Check if it's Backspace or del/home/end/PgUp/PgDn
if p!="\x08" and p!="":
return False
else:
if this_field < codeLength:
next_field.focus_set()
else:
return True
def code_checker():
global code_check
global codeLength
print("== Code Check ==")
enteredCode = ''
enteredCode += entry1.get()
enteredCode += entry2.get()
enteredCode += entry3.get()
if codeLength == 3:
if enteredCode in list3:
code_check = 1
else:
code_check = 2
if codeLength == 4:
enteredCode += entry4.get()
if enteredCode in list4:
code_check = 1
else:
code_check = 2
show_result()
def show_result():
global code_check
print("== Show Result ==")
print(code_check)
# If code is correct
if code_check == 1:
# Image code accepted
main_canvas.create_image(width/2, 750, anchor=N, image=codeAccepted)
# If code is wrong
elif code_check == 2:
# Image code denied
main_canvas.create_image(width/2, 750, anchor=N, image=codeDenied)
# Clear fields
entry1.delete(0, END)
entry2.delete(0, END)
entry3.delete(0, END)
entry4.delete(0, END)
# Set focus to first field
entry1.focus_set()
else:
pass
#####
# Screen items
# Load images
codeDenied = PhotoImage(file='Assets/code_denied.png')
codeAccepted = PhotoImage(file='Assets/code_accepted.png')
# Set fullscreen canvas
main_canvas = Canvas(root, bg="#000000", bd=0, highlightthickness=0)
main_canvas.pack(fill="both", expand=True)
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
# Input num limiter command
vcmd = root.register(func=num_limit)
# 3-6 single-digit input fields
entry1 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 1), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry2 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 2), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry3 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 3), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
entry4 = Entry(root, validate='key', validatecommand=(vcmd, '%P', 4), font=("Helvetica", 100), fg="#000000", bg="#ffffff", width=1, bd=0)
# Entry position adjust
field1 = -100
field2 = 0
field3 = 100
field4 = 150
# Entry placing
if codeLength == 3:
entry_window1 = main_canvas.create_window(width+field1, 500, anchor=N, window=entry1)
entry_window2 = main_canvas.create_window(width+field2, 500, anchor=N, window=entry2)
entry_window3 = main_canvas.create_window(width+field3, 500, anchor=N, window=entry3)
elif codeLength == 4:
field1 = field1-50
field2 = field2-50
field3 = field3-50
entry_window1 = main_canvas.create_window(width/2+field1, 500, anchor=N, window=entry1)
entry_window2 = main_canvas.create_window(width/2+field2, 500, anchor=N, window=entry2)
entry_window3 = main_canvas.create_window(width/2+field3, 500, anchor=N, window=entry3)
entry_window4 = main_canvas.create_window(width/2+field4, 500, anchor=N, window=entry4)
else:
pass
#####
root.mainloop()
Inside num_limit(), you should check whether the content of Entry is empty or not, if it is empty return True. Without this validation, you cannot delete content of the Entry as empty string is not a valid input.
Also you called code_checker() before the validation function returns, so you will get empty string from Entry4 inside code_checker(). Use after() to schedule the execution of code_checker() after the validation.
Finally, list3 and list4 are list of integers, but enteredCode is string, so the checking result will always be 2. Convert enteredCode to integer before checking.
Below are modified num_limit() and code_checker():
def num_limit(p, this_field):
global codeLength
### check for empty string
if p == "": return True
print("Entry" + this_field + ": " + p)
this_field = int(this_field)
entries = [entry1, entry2, entry3, entry4]
if this_field < codeLength:
next_field = entries[this_field]
# Check if it's a number
if p.isdigit():
if this_field < codeLength:
# Set focus on next field
next_field.focus_set()
else:
# schedule execution of code_checker() after validation
root.after(100, code_checker)
return True
else:
# Check if it's Backspace or del/home/end/PgUp/PgDn
if p!="\x08" and p!="":
return False
else:
if this_field < codeLength:
next_field.focus_set()
else:
return True
def code_checker():
global code_check
global codeLength
print("== Code Check ==")
enteredCode = ''
enteredCode += entry1.get()
enteredCode += entry2.get()
enteredCode += entry3.get()
if codeLength == 3:
if int(enteredCode) in list3: # convert enteredCode to integer
code_check = 1
else:
code_check = 2
if codeLength == 4:
enteredCode += entry4.get()
if int(enteredCode) in list4: # convert enteredCode to integer
code_check = 1
else:
code_check = 2
show_result()
Related
I did a tkinter window where an user has to select some items in a listbox which displays two radiobuttons. If the user selects one radiobutton and then deselects the item in the listbox, radiobuttons are deleted. The problem is that if user selects the same item as previously, the radiobutton is already selected. I would like they are empty when they are created again.
Thanks in advance
from tkinter import *
import tkinter as tk
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.dictLabel = dict()
self.createWidgets()
def createWidgets(self):
self.ListNumber = ['one', 'two', 'three', 'four']
self.labelListNumber = tk.Label(self, text=' Select a Number : ')
self.labelListNumber.place(x=40, y=30)
self.frame = Frame(self)
self.frame.place(x=200, y=30)
self.list = Listbox(self.frame, exportselection=False,activestyle = tk.NONE, height=5, selectmode="multiple")
self.list.pack(side='left', fill='y')
for each_item in range(len(self.ListNumber)):
self.list.insert(END, self.ListNumber[each_item])
self.scrollbar = Scrollbar(self.frame, orient="vertical", command=self.list.yview)
self.scrollbar.pack(side='right', fill='y')
self.list.config(yscrollcommand=self.scrollbar.set)
self.dictRadioButtonValue = dict()
self.list.bind('<<ListboxSelect>>',self.createRadioButton)
def createRadioButton(self, evt):
index = self.list.curselection() # grab the index
c = 1
if len(index) == 0 or len(self.dictLabel) != 0:
for e in self.dictLabel:
self.dictLabel[e][0].place_forget()
self.dictLabel[e][1].place_forget()
self.dictLabel[e][2].place_forget()
del self.dictLabel
self.dictLabel = dict()
for i in index:
item = self.list.get(i)
if not item in self.dictRadioButtonValue:
if len(self.dictRadioButtonValue) > len(index):
if not item in self.dictLabel[item]:
del self.dictRadioButtonValue[item]
else :
radioButtonValue = tk.IntVar()
radioButtonValue.set(' ')
self.dictRadioButtonValue[item] = radioButtonValue
L = tk.Label(self, text=f"Number selected is {item}")
radiobtn5 = tk.Radiobutton(self, text="Yes", variable = self.dictRadioButtonValue[item], value = 5)
radiobtn7 = tk.Radiobutton(self, text="No", variable = self.dictRadioButtonValue[item], value = 6)
L.place(x=350, y=10+(c * 20))
radiobtn5.place(x=500, y=10 + (c * 20))
radiobtn7.place(x=550, y=10 + (c * 20))
self.dictLabel[item] = L, radiobtn5, radiobtn7
c = c+1
if __name__ == "__main__":
app = Application()
app.geometry("700x250")
app.mainloop()
It is because the deselected item is not removed from self.dictRadioButtonValue.
Create a copy of self.dictRadioButtonValue and then remove the items that are used from the copy. At the end, remove remaining items in copy from self.dictRadioButtonValue:
def createRadioButton(self, evt):
index = self.list.curselection() # grab the index
c = 1
if len(index) == 0 or len(self.dictLabel) != 0:
for e in self.dictLabel:
self.dictLabel[e][0].place_forget()
self.dictLabel[e][1].place_forget()
self.dictLabel[e][2].place_forget()
del self.dictLabel
self.dictLabel = dict()
copy = self.dictRadioButtonValue.copy()
for i in index:
item = self.list.get(i)
if not item in self.dictRadioButtonValue:
# new item selected
radioButtonValue = tk.IntVar(value=' ')
self.dictRadioButtonValue[item] = radioButtonValue
else:
# remove current item from copy
del copy[item]
L = tk.Label(self, text=f"Number selected is {item}")
radiobtn5 = tk.Radiobutton(self, text="Yes", variable = self.dictRadioButtonValue[item], value = 5)
radiobtn7 = tk.Radiobutton(self, text="No", variable = self.dictRadioButtonValue[item], value = 6)
L.place(x=350, y=10+(c * 20))
radiobtn5.place(x=500, y=10 + (c * 20))
radiobtn7.place(x=550, y=10 + (c * 20))
self.dictLabel[item] = L, radiobtn5, radiobtn7
c = c+1
# remove remaining items in copy from self.dictRadioButtonValue
for item in copy:
del self.dictRadioButtonValue[item]
The buttonGuess runs numRandom function when it's pressed and it also runs remainingAttemps function. The problem is if user presses the buttonGues, Attemps value is reasigned again.
import tkinter
import random
window = tkinter.Tk()
window.geometry('600x500')
x = random.randint(1,10)
remainingTime = True
Attempts = 4
def countdown (time_left):
global remainingTime
if remainingTime == True:
lblCrono.configure(text = str(time_left))
if time_left > 0:
time_left = time_left - 1
window.after(1000, countdown, time_left)
else:
remainingTime = False
lblCrono.configure(text = 0)
return remainingTime, gameOver()
else:
return
def numRamdom():
global Attempts
numWritten = int(entryWriteNumber.get())
if numWritten > x:
lblClue.configure(text = 'Its a smaller number')
return remainingAttempts(Attempts)
if numWritten < x:
lblClue.configure(text = 'Its a bigger number')
return remainingAttempts(Attempts)
if numWritten == x:
lblClue.configure(text = 'Congratulations ;)')
remainingTime = False
return remainingTime, countdown(0)
def gameOver():
if remainingTime == False and Attempts != 0:
lblClue.configure(text = '¡Time\'s up!')
else:
lblClue.configure(text = 'No attempts')
def remainingAttempts(countAtempts):
Attempts = countAtempts
if Attempts == 0:
return remainingTime, countdown(0), Attempts, gameOver()
else:
Attempts = Attempts - 1
entryWriteNumber = tkinter.Entry(window)
entryWriteNumber.grid(column = 0, row = 1, padx = 10, pady = 10)
lblNumber = tkinter.Label(window, text = 'Number', font = 'Comic 13 bold')
lblNumber.grid(column = 0, row = 0, padx = 10, pady = 10, sticky = tkinter.W )
buttonGuess = tkinter.Button(window, text = 'Guess', bg = 'light grey', padx = 20, command = numRamdom)
buttonGuess.grid(column = 0, row = 2, sticky = tkinter.W, padx = 10, pady = 10)
lblClue = tkinter.Label(window, text = 'Clue', font = 'Comic 13 bold')
lblClue.grid(column = 0, row = 3, padx = 10, pady = 10, sticky = tkinter.W )
lblCrono = tkinter.Label(window, text = '', bg = 'white', fg = 'red', font = 'Comic 20', padx = 50, pady = 5)
lblCrono.grid(column = 1, row = 5, sticky = tkinter.S, padx = 100, pady = 150)
countdown(30)
window.mainloop()
It's all much easier to manage when you get rid of everything that either isn't doing anything or is unnecessary. All your returns are doing nothing. Creating a remainingTime variable when you have a counter is unnecessary. Giving your widgets and functions a bunch of complicated and/or misleading names, isn't helping. You were calling countdown(0) which calls gameOver() and then calling gameOver().
You never put something on row=4, but you put your timer on row=5. This is visibly no different than putting it on 4. You had very repetitive grid options so I homogenized them in a dict and used that dict as **kwargs. Writing your arguments like this -> func(arg1 = value1, arg2 = value2, ...) has no benefit. There's no reason to keep a reference to lblNumber or buttonGuess. You never modify or further reference either, in any way. If you don't specify a column, tkinter will assume you mean column=0. If you don't specify a row, tkinter will assume you mean 1 row greater than the total current rows, regardless of column. Importing tkinter without an alias just gives you more to type.
Below is my edit of your game based on everything I just wrote.
import tkinter as tk
import random
root = tk.Tk()
root.geometry('600x500')
x = random.randint(1,10)
remaining = 4
def countdown(time_left):
global process
chrono['text'] = str(time_left)
if time_left:
process = root.after(1000, countdown, time_left-1)
else:
gameOver()
def check():
global remaining
n = int(guess.get())
if n == x:
gameOver(True)
return
else:
clue['text'] = f'Its a {"smaller" if n > x else "bigger"} number'
remaining -= 1
if not remaining:
gameOver()
def gameOver(win=False):
root.after_cancel(process)
if not win:
clue['text'] = '¡Time\'s up!' if remaining else 'No attempts remain'
else:
clue['text'] = 'Congratulations ;)'
grid = dict(padx=10, pady=10, sticky=tk.W)
tk.Label(root, text='Number', font='Comic 13 bold').grid(**grid)
guess = tk.Entry(root)
guess.grid(**grid)
tk.Button(root, text='Guess', bg='light grey', padx=20, command=check).grid(**grid)
clue = tk.Label(root, text='Clue', font='Comic 13 bold', width=20, anchor='w')
clue.grid(**grid)
chrono = tk.Label(root, text='', bg='white', fg='red', font='Comic 20', padx=50, pady=5)
chrono.grid(column=1, **grid)
countdown(30)
root.mainloop()
I'm trying to make an app in python/tkinter that allows you to create a roster for a hockey team. I want to generate the "new_roster" frame based on the parameter number of players on the team, and have thus managed to create a variable amount of entry boxes for each player, but am not able to extract the values from said entry boxes.
In my current code, a list is generated based on the number of players the user wants on their team by adding a "z" to an empty string. The next function then iterates through the list, sets the string = Entry(frame, xxx), I initially tried with an int, but it doesn't seem to matter. I also tried making the str a StringVar but it didn't work either.
Every time I try to reference the entry boxes after their creation like
a = (player_list[0])
b = a.get
I get the following error:
error: 'str' object has no attribute 'get'
it's kinda long so: https://repl.it/#masoneischens/StableToughTheories
The important parts:
My very convoluted list creation loop (entry2 = number of players on team)
for i in range(int(entry2.get())):
a = "z"
for u in range(i):
a += "z"
player_list.insert(i - 1, a)
The loop that actually creates the entry boxes (pr = appropriate row)
for n in player_list:
pr += 1
a= Entry(edit_roster, width = 15)
a.grid(row = pr, column =3)
The function that saves values to a csv file (fn = filename, s = name w/o ".csv")
def save_new_file(s):
global player_list
fn = str(s) + ".csv"
with open(fn, mode='w') as roster_file:
roster_writer = csv.writer(roster_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
for i in player_list:
b = i.get()
roster_writer.writerow([b, "player 1 "])
Basically I need to be able to create and reference variables using a string as it's name, or some way to convert a string into proper variable name so I can extract values from entry boxes created using said strings.
The Error is occurring because you are calling get() method on strings.
Instead of calling get() method on player_list, do the following:
create a entry_list
global entry_list
entry_list = []
insert entries to entry list
entry_list.append(a)
call get() method on entries from entry_list
global entry_list
for i in entry_list:
print(i.get())
This is updated version of your code. Here I just printed the values from entries:
from tkinter import *
from tkinter import messagebox
from tkinter import simpledialog
import csv
import random
sample = Tk()
sample.geometry("500x500")
# lists
# functions
def switch_newroster():
new_roster.tkraise()
def switch_startpage():
start_page.tkraise()
def switch_loadroster():
load_roster.tkraise()
def get_file():
if entry_getfile_act.get() == "":
messagebox.showerror("ERROR!!", "Please enter a file name")
else:
print("good job")
def create():
global player_list
# ADD_1 Create new global entry_list #####
global entry_list
entry_list = []
player_list = []
number_list = []
pos_list = []
pr = 3
nr = 3
gr = 3
posr = 3
ar = 3
gaar = 3
if entry2.get() == "":
messagebox.showerror("ERROR!!", "Enter number of players")
return False
elif entry1.get() == "":
messagebox.showerror("ERROR!!", "Please enter a team name")
return False
elif int(entry2.get()) > 35 or int(entry2.get()) <= 0:
messagebox.showerror("ERROR!!", "Roster can contain 1-35 players")
else:
o = "we coolin my dude"
for i in range(int(entry2.get())):
a = "z"
for u in range(i):
a += "z"
player_list.insert(i - 1, a)
for i in range(int(entry2.get())):
a = i + 1
number_list.insert(i - 1, a)
for i in range(int(entry2.get())):
a = i + 1
pos_list.insert(i - 1, a)
print(player_list)
team_name = Label(edit_roster, text=entry1.get())
team_name.grid(row=1, column=3)
for n in player_list:
pr += 1
n = StringVar()
a = Entry(edit_roster, width=15, textvariable=n)
a.grid(row=pr, column=3)
# ADD_2 Append entries to entry_list #####
entry_list.append(a)
for n in number_list:
nr += 1
n = Entry(edit_roster, width=2)
n.grid(row=nr, column=1)
for n in pos_list:
posr += 1
pos = StringVar(sample)
pos.set(n + 1)
n = OptionMenu(edit_roster, pos, "G", "LW", "RW", "D")
n.grid(row=posr, column=5)
edit_roster.tkraise()
def editstats():
goal_list = []
assist_list = []
gaa_list = []
player_list = []
number_list = []
pos_list = []
pr = 3
nr = 3
gr = 3
posr = 3
ar = 3
gaar = 3
lbl5 = Label(edit_stats, text="G")
lbl5.grid(row=3, column=6)
lbl6 = Label(edit_stats, text="A")
lbl6.grid(row=3, column=5)
lbl7 = Label(edit_stats, text="GAA")
lbl7.grid(row=3, column=5)
for i in range(int(entry2.get())):
a = i + 1
goal_list.insert(i - 1, a)
for i in range(int(entry2.get())):
a = i + 1
gaa_list.insert(i - 1, a)
for i in range(int(entry2.get())):
a = "z"
for u in range(i + 1):
a += "z"
assist_list.insert(i - 1, a)
for n in goal_list:
gr += 1
n = Entry(edit_roster, width=2)
n.grid(row=gr, column=4)
for n in assist_list:
ar += 1
n = Entry(edit_roster, width=2)
n.grid(row=ar, column=2)
for n in gaa_list:
gaar += 1
n = Entry(edit_roster, width=2)
n.grid(row=gaar, column=1)
edit_roster.tkraise()
def save_new_file(s):
global player_list
# ADD_3 Get values from entries of entry_list #####
global entry_list
for i in entry_list:
print(i.get())
# fn = str(s) + ".csv"
# with open(fn, mode='w') as roster_file:
# roster_writer = csv.writer(roster_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
# roster_writer.writerow(['John Smith', 'Accounting', 'November'])
# roster_writer.writerow(['Erica Meyers', 'IT', 'March'])
# for i in player_list:
# b = i.get()
# roster_writer.writerow([b, "player 1 "])
def get_filename():
global player_list
print()
filename = simpledialog.askstring("input string", "What do you want to call your file?")
print(filename)
save_new_file(filename)
# frames
# start page
start_page = Frame(sample, bg="pink", height="50", width="60")
start_page.grid(row=0, column=0, sticky="nsew")
# new roster
new_roster = Frame(sample, bg="yellow")
new_roster.grid(row=0, column=0, sticky="nsew")
# editable roster
edit_roster = Frame(sample, bg="Blue")
edit_roster.grid(row=0, column=0, sticky="nsew")
# load roster
load_roster = Frame(sample)
load_roster.grid(row=0, column=0, sticky="nsew")
# edit stats
edit_stats = Frame(sample)
edit_stats.grid(row=0, column=0, sticky="nsew")
start_page.tkraise()
# buttons
# start page
new_roster_b = Button(start_page, command=switch_newroster, text="NEW ROSTER", height="2", width="10")
new_roster_b.grid(row=1, column=2)
load_roster_b = Button(start_page, command=switch_loadroster, text="LOAD ROSTER", height="2", width="10")
load_roster_b.grid(row=2, column=2)
# load roster
entry_getfile_b = Button(load_roster, text="Find", command=get_file)
entry_getfile_b.grid(row=2, column=3)
back_b = Button(load_roster, command=switch_startpage, text="Back")
back_b.grid(row=3, column=1)
# new roster
back_b = Button(new_roster, command=switch_startpage, text="Back")
back_b.grid(row=3, column=1)
create_b = Button(new_roster, command=create, text="Create Team")
create_b.grid(row=2, column=5)
# edit roster
save_b = Button(edit_roster, command=get_filename, text="Save")
save_b.grid(row=3, column=6)
# other widgets
# start page
# load roster
entry_lbl_getfile = Label(load_roster, text="Enter File NAME!!!")
entry_lbl_getfile.grid(row=2, column=1)
entry_getfile_act = Entry(load_roster)
entry_getfile_act.grid(row=2, column=2)
# new roster
lbl1 = Label(new_roster, text="Team Name:")
lbl1.grid(row=2, column=1)
lbl8 = Label(new_roster, text="Number of Players:")
lbl8.grid(row=2, column=3)
entry1 = Entry(new_roster)
entry1.grid(row=2, column=2)
entry2 = Entry(new_roster)
entry2.grid(row=2, column=4)
# edit roster
lbl2 = Label(edit_roster, text="#")
lbl2.grid(row=3, column=1)
lbl3 = Label(edit_roster, text="Name")
lbl3.grid(row=3, column=3)
lbl4 = Label(edit_roster, text="Pos.")
lbl4.grid(row=3, column=5)
sample.mainloop()
#!/usr/bin/env python
import tkinter as tk
from tkinter import ttk
import math
import random
#positions are stored in label and number format
LARGE_FONT= ("Verdana", 12)
positions = ['label'+str(i)+str(j) for i in range(8) for j in range(8)]
class Application(tk.Frame):
global positions
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
#The entry screen
#label = tk.Label(self, text="""Begin.""", font=LARGE_FONT)
#label.grid(row=0, column=0, pady=10)
#label = tk.Label(self, text="""Exit.""", font=LARGE_FONT)
#label.grid(row=0, column=1, pady=10)
#button1 = ttk.Button(self, text="Start Game", command=self.start)
#button2 = ttk.Button(self, text="Quit Game", command=quit)
#button1.grid(row=1, column=0, pady=10)
#button2.grid(row=1, column=1, pady=1)
#def start(self):
#self.createWidgets()
self.master = master
app = tk.Frame(self.master, bg="yellow")
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure(1, weight=1)
app.grid_columnconfigure(0, weight=1)
#app.pack(fill="both", expand=True)
# instructions and fonts
self.instructions = "Find the hidden treasure!\n\nUse the arrow keys to select where to look, then press Enter to check. \
There is a 50/50 chance you will be told the distance from the treasure. Keep hunting until you find it. Good luck!"
# create instructions widget
self.info = tk.Text(app, padx=10, pady=10,width=15,bd=0, height=19, bg="yellow")
self.info.insert(1.0,self.instructions)
self.info.grid(row=0,column=0,sticky='N'+'E'+'S'+'W')
# create island widget
self.island = tk.Text(app, bg="cyan", padx=40, pady=40, width=15, height=9, bd=0)
self.island.insert(1.0, "ready")
self.island.grid(row=0,column=1, stick='N'+'E'+'S'+'W', rowspan=3)
# restart button
#self.restart_b = tk.Button(app, text="Restart", bg="red", command=self.begin)
#self.restart_b.grid(row=2, column=0, pady=20)
# score labels and fields
self.score_lbl = tk.Label(app, text="Guesses: 0", bg="yellow")
self.score_lbl.grid(row=1, column=0)
#keep track og gold
self.gold_lbl = tk.Label(app, text="Gold: 0", bg="yellow")
self.gold_lbl.grid(row=3, column=0)
#gold and bandit positions
self.gridrange = 8
self.numchest = 10
self.bandits = 3
self.winscore = 100
# set keydown handler
root.bind("<Key>", self.key_pressed)
# best score variable
self.best_score = 0
# begin game
#self.begin()
#print self.treasure_pos
self.mainMenu()
def mainMenu(self):
self.t = tk.Toplevel(self.master, backgroun='red')
self.t.wm_title("Main Menu")
self.l = tk.Label(self.t, text="Welcome to Treasure Hunt", background='red')
self.l.pack(side="top", fill="both", expand=True, padx=100, pady=100)
self.t.lift(self.master)
#self.t.geometry('640x480+0+0')
self.play = tk.Button(self.t, text="play", bg="purple", command=self.letsplay)
self.play.pack(side='left', expand=True)
self.ops = tk.Button(self.t, text="options", bg="yellow", command=self.ops)
self.ops.pack(side='left', expand=True)
def ops(self):
self.opwin = tk.Toplevel(self.master, backgroun='red')
self.opwin.wm_title("Option Menu")
self.opl = tk.Label(self.opwin, text="Welcome to Treasure Hunt", background='red')
self.opl.pack(side="top", fill="both", expand=True, padx=100, pady=100)
self.opwin.lift()
#self.opwin.geometry('640x480+0+0')
self.appp = tk.Button(self.opwin, text="Apply", bg="purple", command=self.letsplay)
self.appp.pack(side='left', expand=True)
self.gridops = tk.Listbox(self.opwin, selectmode='SINGLE')
self.gridops.pack()
for i in range(6, 14):
self.gridops.insert(tk.END, i)
self.gridrange = self.gridops.curselection()
def letsplay(self):
self.t.destroy()
#self.opwin.destroy()
#self.begin()
self.createWidgets()
root.lift()
def createWidgets(self):
#print (self.gridrange)
root.lift()
root.after_cancel(self.tick)
self.matrix = [["#" for col in range(self.gridrange)] for row in range(self.gridrange)]
self.current_pos = [0,0]
self.treasure_pos = []
self.bandit_pos = []
#times treasure has been found
self.treasures_won = []
self.last_treasure = []
self.gold_found = 0
for i in range(0, self.numchest):
self.gold_xy = self.get_pos()
self.treasure_pos.append(self.gold_xy)
for i in self.treasure_pos:
print (i)
print (len(self.treasure_pos))
for i in range (0, self.bandits):
self.bandit_xy = self.get_pos()
self.bandit_pos.append(self.bandit_xy)
for i in self.bandit_pos:
print (i)
print (len(self.bandit_pos))
#self.treasure_pos = [0,0]
#print self.treasure_pos
self.sett()
top=self.winfo_toplevel()
self.entry_frame = tk.Frame(self)
self.entry_frame.grid(row=0, column=0,rowspan=1,columnspan=8,sticky=tk.N+tk.E+tk.W)
self.pos_frame = tk.Frame(self)
self.pos_frame.grid(row=1, column=0,columnspan=8,sticky=tk.N+tk.S+tk.E+tk.W)
self.entry_frame.rowconfigure(0,weight=2)
screenx=self.pos_frame.winfo_width()
screeny=self.pos_frame.winfo_height()
for i in range(8):
top.rowconfigure(i,weight=1)
top.columnconfigure(i,weight=1)
self.pos_frame.columnconfigure(i,weight=1)
self.pos_frame.rowconfigure(i,weight=1)
self.entry_frame.columnconfigure(i,weight=1)
self.rowconfigure(i,weight=1)
self.columnconfigure(i,weight=1)
self.label_no_of_moves=tk.Label(self.entry_frame,text="MOVES : ")
self.label_no_of_moves.grid(row=0,column=0,sticky=tk.N+tk.S+tk.E+tk.W)
self.moves=tk.StringVar()
self.number_of_moves=tk.Entry(self.entry_frame,textvariable=self.moves)
self.number_of_moves.grid(row=0,column=1,sticky=tk.N+tk.S+tk.E+tk.W)
self.label_direction=tk.Label(self.entry_frame,text="DIRECTION : ")
self.label_direction.grid(row=0,column=2,sticky=tk.N+tk.S+tk.E+tk.W)
#Assume Direction to be U D L R you can also use listbox here but i m not using it for saving time
self.dir=tk.StringVar()
self.direction=tk.Entry(self.entry_frame,textvariable=self.dir)
self.direction.grid(row=0,column=3,sticky=tk.N+tk.S+tk.E+tk.W)
self.direction=tk.Button(self.entry_frame,text='GO',command=self.gomoves)
self.direction.grid(row=0,column=4,sticky=tk.N+tk.S+tk.E+tk.W)
for i in range(8):
for j in range(8):
x='label'+str(i)+str(j)
self.x=tk.Label(self.pos_frame,bg="#"+"F"+str(5*(1+i))[0]+str(4*(i+1))[0]+str(6*(j+2))[0]+str(3*(j+1))[0]+"7",text=str(i)+str(j))
self.x.grid(row=i,column=j,sticky=tk.N+tk.S+tk.E+tk.W)
#For updating the grid if window size is changed
self.bind('<Configure>',self.update)
#For initial Player position
self.start_position=str('label'+generate_initial_position())
self.current_position = self.start_position
print (self.current_position)
#initial position removed from positions(avaliable positions)
print (positions)
positions.remove(str(self.start_position))
#selecting treasure chest from remaining positions
self.treasure_chest_positions=random.sample(positions,10)
#removing treasures chest position from positions(avaliable positions)
for i in positions[:]:
if i in self.treasure_chest_positions:
positions.remove(i)
print (self.treasure_chest_positions)
#selecting bandits position from positions(avaliable positions)
self.bandit_positions =random.sample(positions,5)
def sett(self):
self.blink = False
self.guesses = 0
self.end_tick = False
self.tick()
def get_pos(self):
self.used = False
xy = random.randrange(self.gridrange), random.randrange(self.gridrange)
if xy in self.treasure_pos or xy in self.bandit_pos:
self.used = True
while self.used == True:
xy = (random.randrange(self.gridrange), random.randrange(self.gridrange))
if xy not in self.treasure_pos or xy in self.bandit_pos:
self.used = False
return xy
else:
return xy
def gomoves(self,event=None):
print ('GO MOVES')
#Validate Moves so that the values of moves should lie inside the positions avaliable
print (self.moves.get())
print (self.dir.get())
#On moving update the current position variable
#Please deal with the position written in format label(row_no)(column_no) like label01 for row=0 and column=1 it will not be that difficult
current_row= int(self.current_position[5:6])
current_column=int(self.current_position[6:7])
print (current_row , current_column)
#now update the position based on moves if moves are invalid then pop up tkDialogBox search a little on google you will get help from there
#self.current_position =
def key_pressed(self, event):
if event.keysym == "Right" and self.current_pos[1] < 7:
self.current_pos[1] += 1
print("right")
elif event.keysym == "Left" and self.current_pos[1] > 0:
self.current_pos[1] -= 1
print("left")
elif event.keysym == "Up" and self.current_pos[0] > 0:
self.current_pos[0] -= 1
print("up")
elif event.keysym == "Down" and self.current_pos[0] < 7:
self.current_pos[0] += 1
print("down")
elif event.keysym == "Return":
self.process_guess()
self.display_grid()
self.matrix = [["#" for col in range(8)] for row in range(8)] # is here the best place for this?
def check(self):
if self.current_pos_tuple in self.treasures_won:
self.counts = Counter(self.treasures_won)
print (self.counts)
print (self.counts)[self.current_pos_tuple]
if self.current_pos_tuple in self.last_treasure:
self.gold_found -= 10
self.treasures_won.remove(self.current_pos_tuple)
self.guesses -= 1
self.last_treasure.remove(self.current_pos_tuple)
print (self.last_treasure)
if self.counts[self.current_pos_tuple] > 3:
self.treasure_pos.remove(self.current_pos_tuple)
self.bandit_pos.append(self.current_pos_tuple)
print ('someone was here waiting for me')
self.gold_found -= 10
print (self.gold_found)
if self.gold_found >= self.winscore:
print ('you win')
if len(self.treasure_pos) <= 0:
print ('you lose')
def process_guess(self):
self.guesses += 1
self.score_lbl.config(text="Guesses: " + str(self.guesses))
self.current_pos_tuple = tuple(self.current_pos)
print (self.current_pos_tuple)
if self.current_pos_tuple in self.treasure_pos:
self.check()
print ('i think i see something shiney')
self.gold_found += 10
print (self.gold_found)
self.treasures_won.append(self.current_pos_tuple)
self.last_treasure.append(self.current_pos_tuple)
self.end_tick = True
self.gold_lbl.config(text="Gold: " + str(self.gold_found))
self.matrix[self.current_pos_tuple[0]][self.current_pos_tuple[1]] = "$"
self.display_grid()
elif self.current_pos_tuple in self.bandit_pos:
print ('something looks suspisious')
self.gold_found = 0
#if not (self.current_pos[0] == self.treasure_pos[0] and self.current_pos[1] == self.treasure_pos[1]):
#print "NOT HERE"
else:
randinteger = random.randrange(10)
dist = int(round(math.sqrt((self.current_pos[0] - self.treasure_pos[randinteger][0]) ** 2 + (self.current_pos[1] - self.treasure_pos[randinteger][1]) ** 2)))
self.matrix[self.current_pos[0]][self.current_pos[1]] = str(dist)
self.display_grid()
print (' i cant seem to find anything')
self.end_tick = True
def display_grid(self):
'''Displays current visual game state'''
self.island.delete(1.0, tk.END)
m_str = ""
for row in range(len(self.matrix)):
m_str += (" ".join(self.matrix[row]) + "\n")
self.island.insert(1.0, m_str)
def finish(self):
self.matrix[self.treasure_pos[self.current_pos_tuple][0]][self.treasure_pos[self.current_pos_tuple][1]] = "$"
self.display_grid()
self.island.insert(tk.END, " + 10 Gold!")
self.sett()
def update(self,event=None):
print (event.num)
screenx=self.pos_frame.winfo_width()
screeny=self.pos_frame.winfo_height()
for i in range(8):
for j in range(8):
x='label'+str(i)+str(j)
if x in self.treasure_chest_positions:
try:
self.x=tk.Label(self.pos_frame,bg="#"+"F"+str(5*(1+i))[0]+str(4*(i+1))[0]+str(6*(j+2))[0]+str(2*(j+1))[0]+"7",text='Treasure')
self.x.grid(row=i,column=j,sticky=tk.N+tk.S+tk.E+tk.W)
except:
print("Treasure error")
elif x in self.bandit_positions:
self.x=tk.Label(self.pos_frame,bg="#"+"F"+str(5*(1+i))[0]+str(4*(i+1))[0]+str(6*(j+2))[0]+str(2*(j+1))[0]+"7",text='Bandit')
self.x.grid(row=i,column=j,sticky=tk.N+tk.S+tk.E+tk.W)
elif x==self.current_position:
self.x=tk.Label(self.pos_frame,bg="#"+"F"+str(5*(1+i))[0]+str(4*(i+1))[0]+str(6*(j+2))[0]+str(2*(j+1))[0]+"7",text='Current')
self.x.grid(row=i,column=j,sticky=tk.N+tk.S+tk.E+tk.W)
else:
self.x=tk.Label(self.pos_frame,bg="#"+"F"+str(5*(1+i))[0]+str(4*(i+1))[0]+str(6*(j+2))[0]+str(2*(j+1))[0]+"7",text=str(i)+str(j))
self.x.grid(row=i,column=j,sticky=tk.N+tk.S+tk.E+tk.W)
def tick(self):
'''timer for blinking cursor'''
if self.blink == False:
self.matrix[self.current_pos[0]][self.current_pos[1]] = "#"
elif self.blink == True:
self.matrix[self.current_pos[0]][self.current_pos[1]] = " "
self.blink = not self.blink
self.display_grid()
if not self.end_tick:
root.after(300, self.tick)
else:
self.sett()
def generate_initial_position():
pos=str(random.randint(0,7))+str(random.randint(0,7))
return pos
root = tk.Tk()
app = Application(root)
#app.master.title('Game')
root.mainloop()
I have a big problem because the code does not want to function while self.gridrange=8 is a tuple it needs to be an integer and I dont know what more you can do to make it an integer
This is the error
()
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:\Users\Zero Davila\Desktop\new.py", line 110, in letsplay
self.createWidgets()
File "C:\Users\Zero Davila\Desktop\new.py", line 123, in createWidgets
self.matrix = [["#" for col in range(self.gridrange)] for row in range(self.gridrange)]
TypeError: 'tuple' object cannot be interpreted as an integer
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh() This is just so I could post on stack the h's
Your previous posts were incorrect. You did not assign self.gridrange as
self.gridrange = 8
You assign it as:
self.gridops = tk.Listbox(self.opwin, selectmode='SINGLE')
self.gridops.pack()
for i in range(6, 14):
self.gridops.insert(tk.END, i)
self.gridrange = self.gridops.curselection()
If you read through the information for Listbox.curselection() or the actual source code, you'll find that it returns a tuple. Hence your problem.
However, in the future, please create a Minimal, Complete, and Verifiable Example to help in debugging. It would have helped immensely.
So I'm making a program which calls a function to do some calculations, and there are buttons to press to change the inputs and recalculate.
It works great, except if a button is pressed before the calculations are finished, the new values are calculated and outputted before returning back to the previous values. Basically, the program does what I want, except it returns to the first calculations after button press and completing second calculations (all the variable values return).
A general schematic of the problem:
1. Root mainloop
2. Values inputted
3. Press 'Go'
4. Calculations printed to screen (Monty Carlo sim by the way)
5. Press button to change input values
6. New calculations printed to screen
7. Once new ones finish, calculations for old variable values return until completion
Is there a way to prevent python from returning to the previous variable values like this? My hope is that there is a way to return to the mainloop so that the calculations on the screen stay correct. Thanks!
Edit:
Here's the code (Sorry it's a bit long and this is my first time with tkinter):
from tkinter import *
from tkinter import ttk
from random import *
from statistics import *
from math import *
'''
Prompt user for: number attacking with, number of defenders at each space
Output: n approaching 100000 and error range approaching .3%, probabilities of next roll, probabilities of winning at each spot, average number of pieces lost & stddev,buttons for decreasing defender/attacker
'''
def reset():
attacker_entry.delete(0,END)
for i in range(len(spaces_entry)):
spaces_entry[i].delete(0,END)
update_buttons()
def update_buttons(*args):
buttons = [attacker_2,attacker_1,split_button,defender_1,defender_2]
try:
if int(attacker_entry.get()) > 1:
for button in buttons:
button['state'] = ['normal']
elif int(attacker_entry.get()) == 1:
attacker_2['state'] = ['disabled']
split_button['state'] = ['disabled']
elif int(attacker_entry.get()) == 0:
for button in buttons:
button['state'] = ['disabled']
return
if int(space1_entry.get()) > 1:
defender_2['state'] = ['normal']
elif int(space1_entry.get()) == 1:
defender_2['state'] = ['disabled']
split_button['state'] = ['disabled']
except:
for button in buttons:
button['state'] = ['disabled']
def subtract(label,*args):
if label == "both":
label = "att def 1"
end = int(label[-1:])
if "att" in label:
attacker_amount.set(int(attacker_entry.get()) - end)
if "def" in label:
space1.set(int(space1_entry.get()) - end)
if int(space1_entry.get()) == 0:
attacker_amount.set(int(attacker_entry.get()) - 1)
for i in range(len(spaces)):
try:
spaces[i].set(int(spaces_entry[i+1].get()))
except:
spaces[i].set("")
win_avgs[i].set("")
pieces_left[i].set("")
most_likely[i].set("")
space10.set("")
update_buttons()
go()
def check_if_multiple(list1,list2):
if len(list1)>1 and len(list2)>1:
ret_val = 2
else:
ret_val = 1
return ret_val
def set_rolls(total,limit):
list = []
for i in range(total):
if len(list) < limit:
list.append(randrange(1,7))
return list
def go(*args):
update_buttons()
try:
attacker_total = int(attacker_entry.get())
except:
return
defender_pieces_list = []
for entry in spaces_entry:
try:
new_val = int(entry.get())
if new_val == 0:
None
else:
defender_pieces_list.append(new_val)
except:
None
defender_total_spaces = len(defender_pieces_list)
attacker_total_original = attacker_total
total_trials = 10000
defender_losses = 0
attacker_losses = 0
first_round_defender_total_wins = 0
first_round_attacker_total_wins = 0
first_round_split_total = 0
space1_succ,space2_succ,space3_succ,space4_succ,space5_succ,space6_succ,space7_succ,space8_succ,space9_succ,space10_succ = [],[],[],[],[],[],[],[],[],[]
space1_all,space2_all,space3_all,space4_all,space5_all,space6_all,space7_all,space8_all,space9_all,space10_all = [],[],[],[],[],[],[],[],[],[]
succ_list = [space1_succ,space2_succ,space3_succ,space4_succ,space5_succ,space6_succ,space7_succ,space8_succ,space9_succ,space10_succ]
all_list = [space1_all,space2_all,space3_all,space4_all,space5_all,space6_all,space7_all,space8_all,space9_all,space10_all]
for trial in range(total_trials):
if trial%20 == 0:
for i in range(0,defender_total_spaces):
try:
win_avgs[i].set(round(((len(succ_list[i]))/trial)*100,1))
pieces_left[i].set(str(round(mean(all_list[i]),2)))
most_likely[i].set(mode(all_list[i]))
root.update()
except:
None
attacker_total = attacker_total_original
first_round = True
for i in range(defender_total_spaces):
defender_total = defender_pieces_list[i]
while defender_total>0 and attacker_total > 0:
defender_win = False
attacker_win = False
defender_rolls_list = set_rolls(defender_total,2)
attacker_rolls_list = set_rolls(attacker_total,3)
if len(attacker_rolls_list) == 1:
defender_rolls_list = [randrange(1,7)]
for j in range(check_if_multiple(defender_rolls_list,attacker_rolls_list)):
if max(defender_rolls_list)>=max(attacker_rolls_list):
attacker_total += -1
defender_win = True
else:
defender_total += -1
attacker_win = True
attacker_rolls_list.remove(max(attacker_rolls_list))
defender_rolls_list.remove(max(defender_rolls_list))
if first_round == True:
if defender_win == True and attacker_win == True:
first_round_split_total += 1
elif attacker_win == True:
first_round_attacker_total_wins += 1
elif defender_win == True:
first_round_defender_total_wins += 1
first_round = False
if defender_total == 0:
succ_list[i].append(attacker_total)
all_list[i].append(attacker_total)
if attacker_total == 1:
attacker_total == -1
if attacker_total == 0:
all_list[i].append(attacker_total)
attacker_total += -1
for i in range(0,defender_total_spaces):
try:
win_avgs[i].set(round(((len(succ_list[i]))/trial)*100,1))
pieces_left[i].set(str(round(mean(all_list[i]),2))+"("+str(round(stdev(all_list[i]),1))+")")
most_likely[i].set(mode(all_list[i]))
except:
None
height = 450
width = 600
shape = str(width) + "x" + str(height)
root = Tk()
root.title("Risk Probability Calculator")
root.geometry(shape)
content = ttk.Frame(root)
content.grid(column=0, row=0, sticky=(N, W, E, S))
content.columnconfigure(0, weight=1)
content.rowconfigure(0, weight=1)
title = ttk.Label(content, text="Risk Probability Calculator", relief="ridge", background="gray",font=("TkHeadingFont",20),anchor="center")
title.grid(column=1, row=1, columnspan=8, padx=3, pady=4,sticky=(N,W,E,S))
reset_button = ttk.Button(content, text="Reset", command=reset)
reset_button.grid(column=1, row=2,padx=3, pady=4, sticky=(N, W, E, S))
go_button = ttk.Button(content, text="Go", command=go)
go_button.grid(column=2, row=2,padx=3, pady=4, sticky=(N, W, E, S))
ttk.Label(content, text="Attacking with:").grid(column=1, row=3,padx=3, pady=4, sticky=(NW))
ttk.Label(content, text="Defending with:").grid(column=1, row=4,padx=3, pady=4, sticky=(NW))
for i in range(5,15):
text = "Space " + str(i-4) + ":"
ttk.Label(content, text=text).grid(column=1,padx=3, pady=4, row=i, sticky=(N,E,S))
attacker_amount = StringVar()
attacker_entry = ttk.Entry(content, textvariable=attacker_amount, width=4)
attacker_entry.grid(column=2, row=3,padx=3, pady=4, sticky=(N, W, S))
spaces = []
spaces_entry = []
for i in range(1, 11):
globals()['space'+str(i)] = StringVar()
spaces.append(globals()['space'+str(i)])
globals()['space'+str(i)+'_entry'] = ttk.Entry(content, textvariable=spaces[i-1], width=4)
globals()['space'+str(i)+'_entry'].grid(column=2, row=(i+4),padx=3, pady=4, sticky=(N, W, S))
spaces_entry.append(globals()['space'+str(i)+'_entry'])
attacker_2 = Button(content, text="Attacker -2",command=lambda: subtract("att 2"))
attacker_2.grid(column=4, row=2,padx=3, pady=4, sticky=(N,W,E,S))
attacker_1 = Button(content, text="Attacker -1",command=lambda: subtract("att 1"))
attacker_1.grid(column=5, row=2,padx=3, pady=4, sticky=(N,W,E,S))
split_button = Button(content, text="Split",command=lambda: subtract("both"))
split_button.grid(column=6, row=2,padx=3, pady=4, sticky=(N,W,E,S))
defender_1 = Button(content, text="Defender -1",command=lambda: subtract("def 1"))
defender_1.grid(column=7, row=2,padx=3, pady=4, sticky=(N,W,E,S))
defender_2 = Button(content, text="Defender -2",command=lambda: subtract("def 2"))
defender_2.grid(column=8, row=2,padx=3, pady=4, sticky=(N,W,E,S))
ttk.Separator(content,orient="vertical").grid(column=3,row=2,rowspan=15,padx=3, pady=4,sticky=(N,W,E,S))
results_frame = ttk.Labelframe(content, text='Results:')
results_frame.grid(column=4, row=3, columnspan=5, rowspan=12,padx=3, pady=4, sticky=(N,W,E,S))
pane = ttk.Panedwindow(results_frame, orient='horizontal')
pane.grid(column=1,row=1,columnspan=5,padx=3,sticky=(N,W,E,S))
pane1 = ttk.Labelframe(pane)
pane.add(pane1)
Label(pane1,text="% Win").grid(column=1,row=1,sticky=(N,W,E))
win_avgs = []
for i in range(1,11):
globals()['win_avg'+str(i)] = StringVar()
win_avgs.append(globals()['win_avg'+str(i)])
Label(pane1,textvariable=win_avgs[i-1]).grid(column=1,row=i+1,padx=4, pady=4,sticky=(N,W,S))
pane2 = ttk.Labelframe(pane)
pane.add(pane2)
Label(pane2,text="Pieces Left").grid(column=1,row=1,sticky=(N,W,E))
pieces_left = []
for i in range(1,11):
globals()['pieces_left'+str(i)] = StringVar()
pieces_left.append(globals()['pieces_left'+str(i)])
Label(pane2,textvariable=pieces_left[i-1]).grid(column=1,row=i+1,padx=4, pady=4,sticky=(N,W,S))
pane3 = ttk.Labelframe(pane)
pane.add(pane3)
Label(pane3,text="Most likely # of Pieces Left").grid(column=1,row=1,sticky=(N,W,E))
most_likely = []
for i in range(1,11):
globals()['most_likely'+str(i)] = StringVar()
most_likely.append(globals()['most_likely'+str(i)])
Label(pane3,textvariable=most_likely[i-1]).grid(column=1,row=i+1,padx=4, pady=4,sticky=(N,W,S))
root.mainloop()
The short answer is that it's because you call root.update(). This not only redraws the screen, but processes any pending events. A good rule of thumb is "never call update" for this exact reason. Infrequently you simply must, but usually there's a better way to organize your code. You can sometimes get away with it if you do it in a function that only takes a few ms, but it looks like your function computes a lot of things. If a user presses a key or clicks a button and then you call update, tkinter is going to try to process that event before continuing.
I would recommend first just removing the call and see what happens. If the screen seems to freeze (which it might, given how much code you're trying to run), you can try replacing it with root.update_idletasks(). That won't process any click or button events, only a certain class of event such as "repaint the screen".