time.sleep skips multiple lines in my script - python

def fctCountdown():
t = 3
countdown = Label(Pong, text = "3", font = ("Fixedsys", 30), bg = "#CB997E", fg = 'black')
countdown.place(x = 387, y = 300)
while t >= 0:
if t == 2:
countdown.config(text = "2")
if t == 1:
countdown.config(text = "1")
if t == 0:
countdown.config(text = "Start !")
sleep(1)
t -= 1
countdown.place_forget()
def fctGoDown():
global x1, y1
def fctGameMenu():
background_image = PhotoImage(master = Pong, file = "fondpong0.png")
background_label = Label(Pong, image = background_image)
background_label.place(x = 0, y = 0)
background_label.image = background_image
def fctStartGame(evt):
global state
if state == 0:
state = 1
fctGameMenu()
sleep(1)
fctCountdown()
Hi guys ! I'm asking you for help because the sleep(1) line in fctStartGame is executed before the fctGameMenu() and i don't understand why. Because of it my countdown doesn't work.

Related

tkinter countdown app stop and reset button not working

I have written a first attempt at a tkinter countdown app and I'm struggling with the stop and reset buttons as well as parts of the interface design.
My stop button does nothing at all whereas my reset button resets the values, but then continues the countdown immediately. I suspect it's because I have set self.running to True in the init method and that my app loops through those lines again and again. How do I prevent that from happening?
The other issue is that my width argument in all of my entry fields gets seemingly ignored. How can I assign the same width to all three fields?
Thanks for your help.
from tkinter import *
import time
from tkinter import messagebox
class Application(Frame):
def __init__(self,master):
super(Application,self).__init__(master)
self.place()
self.widgets()
self.running = True
def widgets(self):
self.hour = StringVar()
self.hour.set("00")
# Why is the width ignored?
self.hour_entry = Entry(width = 7, font=("Calibri",14,""), textvariable = self.hour)
self.hour_entry.place(x = 10, y = 10)
self.minute = StringVar()
self.minute.set("00")
self.minute_entry = Entry(width = 7, font=("Calibri",14,""), textvariable = self.minute)
self.minute_entry.place(x = 30, y = 10)
self.second = StringVar()
self.second.set("00")
self.seconds_entry = Entry(width = 7, font=("Calibri",14,""), textvariable = self.second)
self.seconds_entry.place(x = 50, y = 10)
self.start_btn = Button(text = "Start", command=self.clock)
self.start_btn.place(x = 30, y = 100)
self.stop_btn = Button(text = "Stop", command=self.stop)
self.stop_btn.place(x = 70, y = 100)
self.reset_btn = Button(text = "Reset", command=self.reset)
self.reset_btn.place(x = 110, y = 100)
def clock(self):
if self.running == True:
self.time_total = int(self.hour_entry.get())*3600 + int(self.minute_entry.get())*60 + int(self.seconds_entry.get())
while self.time_total > -1:
# returns 3600/60 = 60 with 0 left: so that's 60 min, 0 seconds
self.mins, self.secs = divmod(self.time_total,60)
self.hours = 0
if self.mins > 60:
self.hours, self.mins = divmod(self.mins, 60)
self.hour.set("{0:02d}".format(self.hours))
self.minute.set("{0:02d}".format(self.mins))
self.second.set("{0:02d}".format(self.secs))
self.time_total -= 1
root.update()
time.sleep(1)
if self.time_total == 0:
messagebox.showinfo("Time Countdown", "Time's up!")
def start(self):
self.running = True
self.clock()
def stop(self):
self.running = False
def reset(self):
self.running = False
self.hour.set("00")
self.minute.set("00")
self.second.set("00")
if __name__ == '__main__':
root = Tk()
app = Application(root)
mainloop()
For the timer, use the after method instead of sleep.
The entry widths are being used, but the place method puts one entry on top of another.
Also - Call the start method from the button click to reset the running flag.
Try this code:
from tkinter import *
import time
from tkinter import messagebox
class Application(Frame):
def __init__(self,master):
super(Application,self).__init__(master)
self.place()
self.widgets()
self.running = False
def widgets(self):
self.hour = StringVar()
self.hour.set("00")
# Why is the width ignored?
self.hour_entry = Entry(width = 4, font=("Calibri",14,""), textvariable = self.hour)
self.hour_entry.place(x = 10, y = 10)
self.minute = StringVar()
self.minute.set("00")
self.minute_entry = Entry(width = 4, font=("Calibri",14,""), textvariable = self.minute)
self.minute_entry.place(x = 60, y = 10)
self.second = StringVar()
self.second.set("00")
self.seconds_entry = Entry(width = 4, font=("Calibri",14,""), textvariable = self.second)
self.seconds_entry.place(x = 110, y = 10)
self.start_btn = Button(text = "Start", command=self.start)
self.start_btn.place(x = 30, y = 100)
self.stop_btn = Button(text = "Stop", command=self.stop)
self.stop_btn.place(x = 70, y = 100)
self.reset_btn = Button(text = "Reset", command=self.reset)
self.reset_btn.place(x = 110, y = 100)
def clock(self):
if self.running == True:
# returns 3600/60 = 60 with 0 left: so that's 60 min, 0 seconds
self.mins, self.secs = divmod(self.time_total,60)
self.hours = 0
if self.mins > 60:
self.hours, self.mins = divmod(self.mins, 60)
self.hour.set("{0:02d}".format(self.hours))
self.minute.set("{0:02d}".format(self.mins))
self.second.set("{0:02d}".format(self.secs))
root.update()
#time.sleep(1)
root.after(1000, self.clock) # wait 1 second, re-call clock
if self.time_total == 0:
self.running = False
messagebox.showinfo("Time Countdown", "Time's up!")
self.time_total -= 1
def start(self):
self.time_total = int(self.hour_entry.get())*3600 + int(self.minute_entry.get())*60 + int(self.seconds_entry.get())
self.running = True
self.clock()
def stop(self):
self.running = False
def reset(self):
self.running = False
self.hour.set("00")
self.minute.set("00")
self.second.set("00")
if __name__ == '__main__':
root = Tk()
app = Application(root)
mainloop()

Maximum recursion error depth causing crash?

I'm making Minesweeper with tkinter. I want to have it so that when a button with 0 mines surrounding it is clicked, all the buttons around that one are automatically clicked. However, when I run this and click on a button with 0, the program crashes. (originally it gave me the error of "maximum recursion depth exceeded"). How do I fix this? Here is the full code:
import tkinter as tk
import sys
import random
from tkinter import messagebox
from PIL import Image, ImageTk
from types import FunctionType
from copy import copy
app = tk.Tk()
app.geometry("432x468")
app.title("Minesweeper")
sys.setrecursionlimit(999999999)
colors = ['#FFFFFF', '#0000FF', '#008200', '#FF0000', '#000084', '#840000', '#008284', '#840084', '#000000']
# create lists
def createlists():
global buttonlist
global mylist
global numberlist
global panelist
global rightlist
global flaglist
global rowlist
global columnlist
global abomb
global adic
global secondlist
secondlist = []
abomb = []
adic = {}
buttonlist = []
mylist = [0]
numberlist = []
panelist = []
rightlist = []
flaglist = []
rowlist = []
columnlist = []
for a in range(1,18):
mylist.append(18*a)
for i in range(1,325):
button = "b" + str(i)
flag = 'flag' + str(i)
row = 'row' + str(i)
column = 'column' + str(i)
buttonlist.append(button)
numberlist.append(i)
secondlist.append(i)
flaglist.append(flag)
rowlist.append(row)
columnlist.append(column)
# randomly select bombs
def selectbombs():
for i in range(0,50):
x = "panel" + str(bomblist[i])
panelist.append(x)
for i in bomblist:
n = "a" + str(i)
abomb.append(n)
secondlist.remove(i)
# create function for when a bomb is clicked
def mine():
global bomblist
for i in range(0,50):
panelist[i] = tk.Label(app, image = bomb)
for x in mylist:
for i in range(x,x+18):
if i+1 in bomblist:
thing = bomblist.index(i+1)
panelist[thing].grid(row=mylist.index(x)+1, column=i-x+1, columnspan=1)
MsgBox = tk.messagebox.askquestion ('Game Over', 'You clicked on a bomb! Game Over. Would you like to play again?')
if MsgBox == 'no':
app.destroy()
else:
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
# create grid of buttons
def buttons():
for i in range(0,324):
if i+1 in bomblist:
buttonlist[i] = tk.Button(app, text="", width=2, height=1, command=mine)
else:
buttonlist[i] = tk.Button(app, text="", width=2, height=1)
for x in mylist:
for i in range(x,x+18):
buttonlist[i].grid(row=mylist.index(x)+1, column=i-x+1, columnspan=1)
rowlist[i] = mylist.index(x)+1
columnlist[i] = i-x+1
# determine the number of bombs adjacent to each button
def numbers():
for i in range(1,325):
adic.update({"a"+str(i) : 0})
alist = list(adic)
for i in bomblist:
for x in numberlist:
if rowlist[x-1] in range(rowlist[numberlist.index(i)]-1, rowlist[numberlist.index(i)]+2) and columnlist[x-1] in range(columnlist[numberlist.index(i)]-1, columnlist[numberlist.index(i)]+2):
adic[alist[x-1]] = adic[alist[x-1]] + 1
for i in bomblist:
del adic[alist[numberlist.index(i)]]
alist = list(adic)
for i in adic:
buttonlist[secondlist[alist.index(i)]-1].bind("<Button-1>", lambda event, x=secondlist[alist.index(i)]-1, y=adic[i] : num(x, y))
# number functions
def num(x, y):
a = rowlist[x]
b = columnlist[x]
if y==0:
buttonlist[x].config(bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
if a != 1 and b != 1:
num(x-19, adic["a"+str(x-18)])
if a != 1:
num(x-18, adic["a"+str(x-17)])
if a != 1 and b != 18:
num(x-17, adic["a"+str(x-16)])
if b != 1:
num(x-1, adic["a"+str(x)])
if b != 18:
num(x+1, adic["a"+str(x+2)])
if a != 18 and b != 1:
num(x+17, adic["a"+str(x+18)])
if a != 18:
num(x+18, adic["a"+str(x+19)])
if a != 18 and b != 18:
num(x+19, adic["a"+str(x+20)])
else:
buttonlist[x].config(text = y, disabledforeground = colors[y], bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
# create function to place a flag
im = Image.open("flag.png")
im = im.resize((20,20), Image.ANTIALIAS)
flag = ImageTk.PhotoImage(im)
def flags():
for i in range(0,324):
buttonlist[i].bind("<Button-3>", lambda event, x=i : right(event, x))
def right(event, x):
if buttonlist[x]["state"] == "normal":
flaglist[x] = tk.Button(app, text = "", width=18, height=19, image = flag)
flaglist[x].grid(row=rowlist[x], column=columnlist[x], columnspan=1)
flaglist[x].bind("<Button-1>", lambda event: flaglist[x].destroy())
# check if the game has been won
def checkwin():
disnum = 0
for i in secondlist:
if buttonlist[i-1]["state"] == "disabled":
disnum = disnum + 1
if disnum == 274:
MsgBox = tk.messagebox.askquestion ('Game Won', 'You have won the game! Would you like to play again?')
if MsgBox == 'no':
app.destroy()
else:
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
# open images
img = Image.open("bomb.png")
img = img.resize((20,20), Image.ANTIALIAS)
bomb = ImageTk.PhotoImage(img)
createlists()
bomblist = random.sample(numberlist, 50)
selectbombs()
buttons()
numbers()
flags()
app.mainloop()
the specific part which is causing the program to crash:
def num(x, y):
a = rowlist[x]
b = columnlist[x]
if y==0:
buttonlist[x].config(bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
if a != 1 and b != 1:
num(x-19, adic["a"+str(x-18)])
if a != 1:
num(x-18, adic["a"+str(x-17)])
if a != 1 and b != 18:
num(x-17, adic["a"+str(x-16)])
if b != 1:
num(x-1, adic["a"+str(x)])
if b != 18:
num(x+1, adic["a"+str(x+2)])
if a != 18 and b != 1:
num(x+17, adic["a"+str(x+18)])
if a != 18:
num(x+18, adic["a"+str(x+19)])
if a != 18 and b != 18:
num(x+19, adic["a"+str(x+20)])
else:
buttonlist[x].config(text = y, disabledforeground = colors[y], bg = '#FFFFFF')
buttonlist[x]["state"] = "disabled"
The issue is that in the recursion process, the code is backtracking on previous squares. When checking a new square, be sure it has not already be checked.
In the num function, add a line of code to skip squares that have already been disabled:
def num(x, y):
if buttonlist[x]["state"] == "disabled": return # add this line
a = rowlist[x]
b = columnlist[x]

Python Tkinter Entry not placing

In Croatia we have competitions where you make apps. I'm making an app to help 1st and 2nd graders learn and revise math. I just started recently so it doesn't have almost anything.
The problem is that when variable: mode = "number" , entries aren't placed.
Btw when opening the app you will be presented with 4 options.
They are addition, subtraction, multiplication and division.
I translated it from Croatian to English so you can understand.
When you run the program press the Addition button.
Then you will see the task but entries missing.
If you change the value of the variable mode to mode = "result", entries are placed.
I tried everything but couldn't get it to work.
Here's the code:
import tkinter as tk
import random
wn = tk.Tk()
wn.config(width = 550, height = 500)
wn.resizable(False, False)
wn.title("Learn and Revise")
number1_1 = 0
number1_2 = 0
number2_1 = 0
number2_2 = 0
number3_1 = 0
number3_2 = 0
number4_1 = 0
number4_2 = 0
number5_1 = 0
number5_2 = 0
def makeRandomNumbers():
global number1_1, number1_2
global number2_1, number2_2
global number3_1, number3_2
global number4_1, number4_2
global number5_1, number5_2
if mode == "number":
while True:
number1_1 = random.randint(0, 10)
number1_2 = random.randint(0, 10)
if number1_1 > number1_2:
pass
else:
break
while True:
number2_1 = random.randint(0, 10)
number2_2 = random.randint(0, 10)
if number2_1 > number2_2:
pass
else:
break
while True:
number3_1 = random.randint(0, 10)
number3_2 = random.randint(0, 10)
if number3_1 > number3_2:
pass
else:
break
while True:
number4_1 = random.randint(0, 10)
number4_2 = random.randint(0, 10)
if number4_1 > number4_2:
pass
else:
break
while True:
number5_1 = random.randint(0, 10)
number5_2 = random.randint(0, 10)
if number5_1 > number5_2:
pass
else:
break
elif mode == "result":
number1_1 = random.randint(0, 10)
number1_2 = random.randint(0, 10)
number2_1 = random.randint(0, 10)
number2_2 = random.randint(0, 10)
number3_1 = random.randint(0, 10)
number3_2 = random.randint(0, 10)
number4_1 = random.randint(0, 10)
number4_2 = random.randint(0, 10)
number5_1 = random.randint(0, 10)
number6_2 = random.randint(0, 10)
def placeTasks(oper):
global operation
operation = oper
makeTasks()
wipeMenu()
button_check.place(x = 310, y = 225)
label1.place(x = 150, y = 125)
label2.place(x = 150, y = 175)
label3.place(x = 150, y = 225)
label4.place(x = 150, y = 275)
label5.place(x = 150, y = 325)
if mode == "number":
entry1.place(x = 240, y = 130)
entry2.place(x = 240, y = 180)
entry3.place(x = 240, y = 230)
entry4.place(x = 240, y = 280)
entry5.place(x = 240, y = 330)
elif mode == "result":
entry1.place(x = 240, y = 130)
entry2.place(x = 240, y = 180)
entry3.place(x = 240, y = 230)
entry4.place(x = 240, y = 280)
entry5.place(x = 240, y = 330)
task1 = 0
task2 = 0
task3 = 0
task4 = 0
task5 = 0
def makeTasks():
global task1, task2, task3, task4, task5
global label1, label2, label3, label4, label5
makeRandomNumbers()
operation_sign = ""
if operation == "addition":
operation_sign = '+'
elif operation == "subtraction":
operation_sign = '-'
elif operation == "multiplication":
operation_sign = '•'
elif operation == "division":
operation_sign = '÷'
if mode == "result":
task1 = "{} {} {} =".format(number1_1, operation_sign, number1_2)
task2 = "{} {} {} =".format(number2_1, operation_sign, number2_2)
task3 = "{} {} {} =".format(number3_1, operation_sign, number3_2)
task4 = "{} {} {} =".format(number4_1, operation_sign, number4_2)
task5 = "{} {} {} =".format(number5_1, operation_sign, number5_2)
elif mode == "number":
task1 = "{} {} = {}".format(number1_1, operation_sign, number1_2)
task2 = "{} {} = {}".format(number2_1, operation_sign, number2_2)
task3 = "{} {} = {}".format(number3_1, operation_sign, number3_2)
task4 = "{} {} = {}".format(number4_1, operation_sign, number4_2)
task5 = "{} {} = {}".format(number5_1, operation_sign, number5_2)
label1 = tk.Label(wn, text = task1, font = ("Arial", 15))
label2 = tk.Label(wn, text = task2, font = ("Arial", 15))
label3 = tk.Label(wn, text = task3, font = ("Arial", 15))
label4 = tk.Label(wn, text = task4, font = ("Arial", 15))
label5 = tk.Label(wn, text = task5, font = ("Arial", 15))
operation = ""
mode = "number"
button_check = tk.Button(wn, width = 20, text = "Check")
label1 = tk.Label(wn, text = task1, font = ("Arial", 15))
entry1 = tk.Entry(wn, width = 7)
label2 = tk.Label(wn, text = task2, font = ("Arial", 15))
entry2 = tk.Entry(wn, width = 7)
label3 = tk.Label(wn, text = task3, font = ("Arial", 15))
entry3 = tk.Entry(wn, width = 7)
label4 = tk.Label(wn, text = task4, font = ("Arial", 15))
entry4 = tk.Entry(wn, width = 7)
label5 = tk.Label(wn, text = task5, font = ("Arial", 15))
entry5 = tk.Entry(wn, width = 7)
def placeMenu():
menu_label1.place(x = 175, y = 75)
button1.place(x = 200, y = 150)
button2.place(x = 200, y = 200)
button3.place(x = 200, y = 250)
button4.place(x = 200, y = 300)
def wipeMenu():
menu_label1.destroy()
button1.destroy()
button2.destroy()
button3.destroy()
button4.destroy()
menu_label1 = tk.Label(wn, text = "Revise", font = ("Arial", 35))
button1 = tk.Button(wn, width = 20, text = "Addition", command = lambda: placeTasks("addition"))
button2 = tk.Button(wn, width = 20, text = "Subtraction")
button3 = tk.Button(wn, width = 20, text = "Multiplication")
button4 = tk.Button(wn, width = 20, text = "Division")
placeMenu()
wn.mainloop()
TL;DR
Postavi font prilikom inicijalizacije entrya, preimenuj if statement i ukloni globalnu varijablu te koristi lokalnu (oper)
Prvo što vidim je mnoštvo ponavljanja. Napravi funkciju s više parametara na kojima ćeš izvršavati for loopove - kod će biti kraći i čitljiviji 20 puta. Tkinter je jednostavan, ali nije praktičan ukoliko nije objektno orijentiran (preporučujem tk.Toplevel klase za prebacivanje prozora, onda samo switchaš screenove i nema potrebe za brisanjem i postavljanjem, što dodatno ubrzava izvrašavanje). Idealno bi bilo kreirati class za svaku aritmetičku operaciju i uz to ne koristiti (spore) lambda anonimne funkcije samo za pozivanje s atributima.
Dakle, kod bi izgledao otprilike ovako:
for (akcija, klasa) in zip(["Addition", "Substraction", ...], lista_klasi):
button = tk.Button(wn, width=20, text=akcija, command=klasa);
...
button.pack() # Izbjegavaj .place(), uvijek samo pack() ili grid()
...
class Solution(tk.Toplevel):
def __init__(self, atributi):
super().__init__()
self.attributes("-topmost", False)
self.solution = tk.Canvas(self, bg="white" ...)
self.solution.pack()
...
# Za najbolji izgled postavljaj widgete na canvas...
self.solution.create_window(w, h, window=atribut[neki])
# Također, ako želiš ostati u istom prozoru, spremi widgete i koristi:
self.canvas.delete("all")
Osobno koristim pack jer je najjednostavniji, u početku nezgodan jer ne dobivaš izgledom točno kako zamišljaš ali kad pohvataš sve ne bi se nikad vratio na place(), osim ako nije nužno :)
Zasad prvo prouči sve pojašnjene primjere ovdje.
Tek kad savladaš tkinter kreni na kivy ako misliš stvarno rasturit na natjecanju.

How to allow Tkinter GUI to detect key presses when not selected

I am trying to make a full GUI, for A game borderlands 2, however it only detects my key presses when the tkinter box is selected (in focus). In a game this is not happening, so I need a way for tkinter to detect my key presses while not selected.
This is the code so far. It is not finished, ignore the "Auto Exec" and "Auto Exit" the problem is "Auto Reload". Clicking once will turn it ON and again will turn it OFF. Just choose any number (1-4) for the weapon slot, does not affect the error.
from easygui import *
from pyautogui import *
from time import *
import os
from tkinter import *
count = 1
slot = "0"
allowReload, allowExit = False, False
def poop():
sleep(3)
print("poop")
def countdown(count):
autoexecB.config(text = count)
if count == 2:
autoexecB.config(bg = "orange")
if count == 1:
autoexecB.config(bg = "yellow")
if count == 0:
autoexecB.config(text = "Running...", bg = "#44ff00")
if count > -1:
root.after(1000, countdown, count-1)
else:
for i in range(1, 3):
sleep(1)
press("'")
sleep(0.5)
type("exec Patch.txt")
press("enter")
press("esc")
press("enter")
sleep(4)
press("esc")
pressMult("down", 4)
press("enter")
press("up")
press("enter")
sleep(1)
press("'")
sleep(0.5)
type("exec STV.txt")
press("enter")
press("esc")
autoexecB.config(text = "Auto Exec", bg = "red")
def type(text):
typewrite(text)
def pressMult(key, amount):
for i in range(1, amount+1):
press(key)
def autoexec():
countdown(3)
def info():
msgbox("Auto Exec: Runs Mods automaticly\nAuto Exit: Exits the game automaticly to the main menu using INSERT\nAuto Reload: Automaticly reloads your gun using LEFT SHIFT")
def exit():
global count
count = 1
press("esc")
pressMult("down", 4)
press("enter")
press("up")
press("enter")
sleep(2.1)
press("enter")
if choose == "FARM at Hero's Pass":
sleep(3)
keyDown("w")
sleep(0.7)
keyUp("w")
keyDown("d")
sleep(1)
keyUp("d")
keyDown("ctrl")
sleep(0.5)
press("e")
keyUp("ctrl")
count += 1
def reloadslot():
global allowReload, slot
while True:
if allowReload == True:
break
slot = str(integerbox("Enter in the weapon's slot to be reloaded"))
if slot not in ("1","2","3","4"):
msgbox("A weapon can only be in slot 1, 2, 3 or 4")
else:
break
if allowReload == True:
allowReload = False
else:
allowReload = True
def on_press(event):
print(event.keysym)
if event.keysym == "Insert" and allowExit == True:
print("exit")
exit()
if event.keysym == "Shift_L" and allowReload == True:
print("running reload")
press(";")
press("e")
press(slot)
print("done")
root = Tk()
root.bind('<KeyPress>', on_press)
root.geometry("378x134")
root.config(bg = "blue")
autoexecB = Button(text = "Auto Exec", bg = "red", font = ("calibri","13"), height = 3, width = 13, command = lambda: autoexec())
autoexitB = Button(text = "Auto Exit", bg = "red", font = ("calibri","13"), height = 3, width = 13)
autoreloadB = Button(text = "Auto Reload", bg = "red", font = ("calibri","13"), height = 3, width = 13, command = lambda: reloadslot())
infoB = Button(text = "INFO", bg = "blue", width = 26, height = 3, command = lambda: info())
exitB = Button(text = "EXIT", bg = "blue", width = 25, height = 3, command = lambda: root.destroy())
autoexecB.place(x = 0, y = 0)
autoexitB.place(x = 126, y = 0)
autoreloadB.place(x = 252, y = 0)
infoB.place(x = 0, y = 78)
exitB.place(x = 193, y = 78)
root.mainloop()
root.mainloop()
I need a way for tkinter to detect my key presses while not selected
You can't use tkinter for that. It can only detect keyboard events when it has the keyboard focus. You will have to use some platform-specific library to do what you want.

A loop within tkinter - HELP!

this is my first time using this forum, hopefully, i can get a quick response with a detailed explanation.
Running:
Python 3.2
Tkinter 8.5 & Windows7 x64
My code:
from tkinter import *
import tkinter.messagebox
class Application(Frame):
def __init__(self, master):
super(Application, self).__init__(master)
self.grid()
self.lvl_one_att = 4
self.bttn_clicks = 2
self.bttn_clicks2 = 2
self.bttn_clicks3 = 1
self.bttn_clicks4 = 2
self.bttn_clicks5 = 1
self.bttn_clicks6 = 2
self.bttn_clicks7 = 1
self.bttn_clicks8 = 2
self.bttn_clicks9 = 2
self.level_one()
def level_one(self):
self.lbl1 = Label(self, text = "You must flip all the boxes to show the same colour!")
self.lbl1.grid(row = 0, column = 0, columnspan = 3)
self.levellbl = Label(self, text = "Level 1")
self.levellbl.grid(row = 4, column = 1, sticky = W, columnspan = 2)
self.rulesbttn = Button(self, text = "Instructions", command = self.rules)
self.rulesbttn.grid(row = 4, column = 0, sticky = W, columnspan = 1)
self.tlbttn = Button(self, bg = "red", width = 20, height = 10, command = self.callback1)
self.tlbttn.grid(row = 1, column = 0, columnspan = 1)
self.tmbttn = Button(self, bg = "red", width = 20, height = 10, command = self.callback2)
self.tmbttn.grid(row = 1, column = 1, columnspan = 1)
self.trbttn = Button(self, bg = "blue", width = 20, height = 10, command = self.callback3)
self.trbttn.grid(row = 1, column = 2, columnspan = 1)
self.mlbttn = Button(self, bg = "red", width = 20, height = 10, command = self.callback4)
self.mlbttn.grid(row = 2, column = 0, columnspan = 1)
self.mmbttn = Button(self, bg = "blue", width = 20, height = 10, command = self.callback5)
self.mmbttn.grid(row = 2, column = 1, columnspan = 1)
self.mrbttn = Button(self, bg = "red", width = 20, height = 10, command = self.callback6)
self.mrbttn.grid(row = 2, column = 2, columnspan = 1)
self.blbttn = Button(self, bg = "blue", width = 20, height = 10, command = self.callback7)
self.blbttn.grid(row = 3, column = 0, columnspan = 1)
self.bmbttn = Button(self, bg = "red",width = 20, height = 10, command = self.callback8)
self.bmbttn.grid(row = 3, column = 1, columnspan = 1)
self.brbttn = Button(self, bg = "red", width = 20, height = 10, command = self.callback9)
self.brbttn.grid(row = 3, column = 2, columnspan = 1)
def callback1(self):
self.lvl_one_att -= 1
self.color_change1()
self.color_change2()
self.color_change4()
self.color_change5()
def callback2(self):
self.lvl_one_att -= 1
self.color_change1()
self.color_change2()
self.color_change3()
self.color_change5()
self.color_change4()
self.color_change6()
def callback3(self):
self.lvl_one_att -= 1
self.color_change2()
self.color_change3()
self.color_change6()
self.color_change5()
def callback4(self):
self.lvl_one_att -= 1
self.color_change1()
self.color_change2()
self.color_change4()
self.color_change5()
self.color_change7()
self.color_change8()
def callback5(self):
self.lvl_one_att -= 1
self.color_change1()
self.color_change2()
self.color_change3()
self.color_change6()
self.color_change9()
self.color_change4()
self.color_change5()
self.color_change7()
self.color_change8()
def callback6(self):
self.lvl_one_att -= 1
self.color_change3()
self.color_change2()
self.color_change6()
self.color_change5()
self.color_change9()
self.color_change8()
def callback7(self):
self.lvl_one_att -= 1
self.color_change4()
self.color_change5()
self.color_change7()
self.color_change8()
def callback8(self):
self.lvl_one_att -= 1
self.color_change4()
self.color_change5()
self.color_change6()
self.color_change7()
self.color_change8()
self.color_change9()
def callback9(self):
self.lvl_one_att -= 1
self.color_change5()
self.color_change6()
self.color_change9()
self.color_change8()
def color_change1(self):
self.bttn_clicks += 1
if self.bttn_clicks == 3:
self.bttn_clicks = 1
if self.bttn_clicks == 1:
self.tlbttn.configure(bg = "blue")
else:
self.tlbttn.configure(bg = "red")
def color_change2(self):
self.bttn_clicks2 += 1
if self.bttn_clicks2 == 3:
self.bttn_clicks2 = 1
if self.bttn_clicks2 == 1:
self.tmbttn.configure(bg = "blue")
else:
self.tmbttn.configure(bg = "red")
def color_change3(self):
self.bttn_clicks3 += 1
if self.bttn_clicks3 == 3:
self.bttn_clicks3 = 1
if self.bttn_clicks3 == 1:
self.trbttn.configure(bg = "blue")
else:
self.trbttn.configure(bg = "red")
def color_change4(self):
self.bttn_clicks4 += 1
if self.bttn_clicks4 == 3:
self.bttn_clicks4 = 1
if self.bttn_clicks4 == 1:
self.mlbttn.configure(bg = "blue")
else:
self.mlbttn.configure(bg = "red")
def color_change5(self):
self.bttn_clicks5 += 1
if self.bttn_clicks5 == 3:
self.bttn_clicks5 = 1
if self.bttn_clicks5 == 1:
self.mmbttn.configure(bg = "blue")
else:
self.mmbttn.configure(bg = "red")
def color_change6(self):
self.bttn_clicks6 += 1
if self.bttn_clicks6 == 3:
self.bttn_clicks6 = 1
if self.bttn_clicks6 == 1:
self.mrbttn.configure(bg = "blue")
else:
self.mrbttn.configure(bg = "red")
def color_change7(self):
self.bttn_clicks7 += 1
if self.bttn_clicks7 == 3:
self.bttn_clicks7 = 1
if self.bttn_clicks7 == 1:
self.blbttn.configure(bg = "blue")
else:
self.blbttn.configure(bg = "red")
def color_change8(self):
self.bttn_clicks8 += 1
if self.bttn_clicks8 == 3:
self.bttn_clicks8 = 1
if self.bttn_clicks8 == 1:
self.bmbttn.configure(bg = "blue")
else:
self.bmbttn.configure(bg = "red")
def color_change9(self):
self.bttn_clicks9 += 1
if self.bttn_clicks9 == 3:
self.bttn_clicks9 = 1
if self.bttn_clicks9 == 1:
self.brbttn.configure(bg = "blue")
else:
self.brbttn.configure(bg = "red")
def rules(self):
tkinter.messagebox.showinfo("Instructions", "The idea of the game, is to make sure all the boxes on the screen are the same colour. By pressing a button it will flip, all colours touching it, including diagonally. ")
def round_win(self):
self.lbl1.grid_forget()
self.rulesbttn.grid_forget()
self.tlbttn.grid_forget()
self.tmbttn.grid_forget()
self.trbttn.grid_forget()
self.mlbttn.grid_forget()
self.mmbttn.grid_forget()
self.mrbttn.grid_forget()
self.blbttn.grid_forget()
self.bmbttn.grid_forget()
self.brbttn.grid_forget()
self.win()
def win(self):
self.lbl2 = Label(self, text = "CONGRATULATIONS!", font=("Helvetica", 40))
self.lbl2.grid(row = 0, column = 0)
root = Tk()
root.title("Program")
app = Application(root)
root.mainloop()
What i can work out how to do, is somehow use a loop so that when all 9 squares are the Red that it runs the round_win() function.
im unsure where to put the loop, and how to write it (for loop, while loop, if, but, else, etc)
Thanks heaps guys for any help you may be able to provide :)
You can put the original buttons into a list:
def level_one(self):
...
self.game_buttons = []
for btn_index in range(9):
bg = "red" # change this to something based on the index
next_button = Button(self, bg = bg, width = 20, height = 10)
next_button['command'] = (lambda index=btn_index: self.callback(index))
row = index/3 + 1
column = index % 3
next_button.grid(row = row, column = column, columnspan = 1)
self.game_buttons.append(next_button)
def callback1(self, index):
button = self.game_buttons[index]
# add the appropriate code here
def color_change(self, index):
# add the appropriate code here
Also, you can change the following code:
self.bttn_clicks2 += 1
if self.bttn_clicks2 == 3:
self.bttn_clicks2 = 1
to
self.bttn_clicks2 = self.bttn_clicks2 % 3 + 1

Categories