Python tkinter error return self.func(*args) , return self._configure('configure', cnf, kw)
Question:
this is my code for tic tac game (X O) in python using Tkinter and I was building with two stages of game
1- play with pc
2- play with player 2
and I think the statements and conditions well be good
but it show me some of error I can’t solve it ..
Error :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init_.py", line 1705, in call
return self.func(*args)
File "C:UsersazooopythonCS492XOtkintermain.py", line 169, in
button3 = Button(f4, text=" ", command=lambda: gameplay(3))
File "C:UsersazooopythonCS492XOtkintermain.py", line 95, in gameplay
pt(player,choice)
File "C:UsersazooopythonCS492XOtkintermain.py", line 83, in pt
turnlabel.config(text=f'{p2} chance’)
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init_.py", line 1485, in configure
return self.configure(‘configure’, cnf, kw)
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
KeyboardInterrupt
Code :
from tkinter import *
import random
player = 1
gt = 0
gg = 0
retry = 0
Win = 1
Running = 0
Game = Running
Mark = 'X'
board = {1: " ", 2: " ", 3: " ", 4: " ", 5: " ", 6: " ", 7: " ", 8: " ", 9: " "}
def CheckPosition(x):
if board[x] == ' ':
return True
else:
return False
def CheckWin():
global Game
# Horizontal winning condition
if board[1] == board[2] and board[2] == board[3] and board[1] != ' ':
Game = Win
elif board[4] == board[5] and board[5] == board[6] and board[4] != ' ':
Game = Win
elif board[7] == board[8] and board[8] == board[9] and board[7] != ' ':
Game = Win
# Vertical Winning Condition
elif board[1] == board[4] and board[4] == board[7] and board[1] != ' ':
Game = Win
elif board[2] == board[5] and board[5] == board[8] and board[2] != ' ':
Game = Win
elif board[3] == board[6] and board[6] == board[9] and board[3] != ' ':
Game = Win
# Diagonal Winning Condition
elif board[1] == board[5] and board[5] == board[9] and board[5] != ' ':
Game = Win
elif board[3] == board[5] and board[5] == board[7] and board[5] != ' ':
Game = Win
# Match Tie or Draw Condition
elif (board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[
6] != ' ' and board[7] != ' ' and board[8] != ' ' and board[9] != ' '):
Game = retry
else:
Game = Running
def retryG():
for i in range(0,10):
board[i] = " "
button[i].config(text=" ")
# gg (0)=with pc , gg(1)=with player2
# gt (0)= easy , gt(1)=hard
# player(1)= player first, player(2)=pc first
# postion= button postion
def turn(player):
global p1, p2
if gg == 0:
if player == 1:
p1 = "User"
p2 = "PC"
else:
p1 = "PC"
p2 = "User"
elif gg == 1:
p1 = "Player 1 "
p2 = "Player 2 "
return p1, p2
def pt(player,choice):
global Mark
if player % 2 != 0:
turnlabel.config(text=f'{p1} chance')
Mark = 'X'
if p1 == "PC" and gt == 0:
choice = random.randrange(1, 9)
elif p1 == "PC" and gt == 1:
pass
elif player % 2 == 0:
turnlabel.config(text=f'{p2} chance')
Mark = 'O'
if p2 == "PC" and gt == 0:
choice = random.randrange(1, 9)
elif p1 == "PC" and gt == 1:
pass
return Mark,choice
def gameplay(choice):
global gg, gt, player, p1, p2
turn(player)
while (Game == Running):
pt(player,choice)
if CheckPosition(choice):
board[choice] = Mark
button[choice].config(text=str(Mark))
player += 1
CheckWin()
if Game != Running:
break
if Game == retry:
retryG()
elif Game == Win:
player -= 1
if player % 2 != 0:
print(f'{p1} Won')
turnlabel.config(text=f'{p1} Won')
else:
print(f'{p2} Won')
turnlabel.config(text=f'{p2} Won')
def raise_frame(frame):
frame.tkraise()
root = Tk()
f1 = Frame(root)
f2 = Frame(root)
f3 = Frame(root)
f4 = Frame(root)
for frame in (f1, f2, f3, f4):
frame.grid(row=0, column=0, sticky='news')
root.geometry("350x350")
root.title("X O Game")
# frame 1
welcome_label = Label(f1, text="Welcome to X O Game", font=20, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
playlabel = Label(f1, text="Play with : ", font=20, padx=10, pady=10).grid(row=1, column=0, rowspan=2)
PCg = Button(f1, text="PC", command=lambda gg=0: raise_frame(f2)).grid(row=1, column=1, padx=5, pady=5, ipadx=10,
ipady=10)
Pl2g = Button(f1, text="Player 2", command=lambda gg=1: [raise_frame(f4)]).grid(row=2, column=1, padx=5, pady=5,
ipadx=10, ipady=10)
exbut = Button(f1, text="exit", command=lambda: exit()).grid(row=3, column=1, ipadx=5, ipady=5, sticky="nsew")
# frame 2
xolabel1 = Label(f2, text="X O Game", font=30, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
fturnlabel = Label(f2, text="Who want to play first ? ", font=20, padx=10, pady=10).grid(row=1, column=0, columnspan=2)
PCtbut = Button(f2, text="PC", command=lambda player=2: raise_frame(f3)).grid(row=2, column=0, padx=5, pady=5, ipadx=10,
ipady=10)
YOUtbut = Button(f2, text="You", command=lambda player=1: raise_frame(f3)).grid(row=2, column=1, padx=5, pady=5,
ipadx=10, ipady=10)
backbut1 = Button(f2, text="back to menue", command=lambda: raise_frame(f1)).grid(row=3, column=0, ipadx=5, ipady=5,
columnspan=2)
# FRAME 3
xolabel2 = Label(f3, text="X O Game", font=30, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
typelabel = Label(f3, text="Choose game type ", font=20, padx=10, pady=10).grid(row=1, column=0, columnspan=2)
Hbut = Button(f3, text="Hard", command=lambda gt=1: raise_frame(f4)).grid(row=2, column=0, padx=5, pady=5, ipadx=10,
ipady=10) # gt means game type
Ebut = Button(f3, text="Easy", command=lambda gt=0: raise_frame(f4)).grid(row=2, column=1, padx=5, pady=5, ipadx=10,
ipady=10)
backbut2 = Button(f3, text="back to menue", command=lambda: raise_frame(f1)).grid(row=3, column=0, ipadx=5, ipady=5,
columnspan=2)
# frame 4
toplabel = Label(f4, text="X O Game", font=20, padx=10, pady=10).grid(row=0, column=0, columnspan=3)
turnlabel = Label(f4, text=" ", font=16)
turnlabel.grid(row=1, column=0, columnspan=2)
button1 = Button(f4, text=" ", command=lambda: gameplay(1))
button1.grid(row=2, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button2 = Button(f4, text=" ", command=lambda: gameplay(2))
button2.grid(row=2, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button3 = Button(f4, text=" ", command=lambda: gameplay(3))
button3.grid(row=2, column=2, padx=5, pady=5, ipadx=10, ipady=10)
button4 = Button(f4, text=" ", command=lambda: gameplay(4))
button4.grid(row=3, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button5 = Button(f4, text=" ", command=lambda: gameplay(5))
button5.grid(row=3, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button6 = Button(f4, text=" ", command=lambda: gameplay(6))
button6.grid(row=3, column=2, padx=5, pady=5, ipadx=10, ipady=10)
button7 = Button(f4, text=" ", command=lambda: gameplay(7))
button7.grid(row=4, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button8 = Button(f4, text=" ", command=lambda: gameplay(8))
button8.grid(row=4, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button9 = Button(f4, text=" ", command=lambda: gameplay(9))
button9.grid(row=4, column=2, padx=5, pady=5, ipadx=10, ipady=10)
buttonretry = Button(f4, text="Retry").grid(row=5, column=0, padx=5, pady=5, ipadx=10, ipady=10, columnspan=3)
backbut = Button(f4, text="back to menue", command=lambda: raise_frame(f1)).grid(row=6, column=0, ipadx=5, ipady=5,columnspan=3)
button = ["", button1, button2, button3, button4, button5, button6, button7, button8, button9]
raise_frame(f1)
root.mainloop()
Answers:
It seems that the issue is caused by the line turnlabel.config(text=f'{p2} chance')
. You should make sure that the turnlabel
object exists and that it has the config
method.
Also, you need to define p1
and p2
before you use them in the pt
function.
Here is a corrected version of your code:
from tkinter import *
import random
player = 1
gt = 0
gg = 0
retry = 0
Win = 1
Running = 0
Game = Running
Mark = 'X'
board = {1: " ", 2: " ", 3: " ", 4: " ", 5: " ", 6: " ", 7: " ", 8: " ", 9: " "}
p1 = ""
p2 = ""
def CheckPosition(x):
if board[x] == ' ':
return True
else:
return False
I think you need to take a look at your game’s logic flow. Ignoring the formatting concerns, your buttons initiate the gameplay()
function when it is clicked.
This launches a while loop with the condition of Game == Running
. Within this while loop, the only time Game
is changed is within CheckWin()
, and unless there’s a win or a tie, Game
is always changed to Running
.
There is no way for it to exit this loop on the first few clicks. Something to consider is why the loop is required in the first place, or if it is even required at all? Also, even if it is necessary, having if Game != Running: break
is unnecessary. If Game != Running
at that position in the code, it would fail the while condition and exit the loop anyway.
def gameplay(choice):
global gg, gt, player, p1, p2
turn(player)
pt(player,choice)
if CheckPosition(choice):
board[choice] = Mark
button[choice].config(text=str(Mark))
player += 1
CheckWin()
if Game == retry:
retryG()
elif Game == Win:
player -= 1
if player % 2 != 0:
print(f'{p1} Won')
turnlabel.config(text=f'{p1} Won')
else:
print(f'{p2} Won')
turnlabel.config(text=f'{p2} Won')
Removing the while loop will get it to work, but there are still a lot of problems with the code. For example, in retryG()
you are looping through button[i].config(...)
for i in range(0,10)
. However, your button[0] is a string and has no .config()
. Because of how tkinter works this won’t terminate your program, but it is throwing exceptions back. Also, the use of global variables when they are unnecessary can make your code more difficult to debug.
Lastly, for code readability, refer to the PEP 8 style guide so the code is more consistent and readable.
this is my code for tic tac game (X O) in python using Tkinter and I was building with two stages of game
1- play with pc
2- play with player 2
and I think the statements and conditions well be good
but it show me some of error I can’t solve it ..
Error :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init_.py", line 1705, in call
return self.func(*args)
File "C:UsersazooopythonCS492XOtkintermain.py", line 169, in
button3 = Button(f4, text=" ", command=lambda: gameplay(3))
File "C:UsersazooopythonCS492XOtkintermain.py", line 95, in gameplay
pt(player,choice)
File "C:UsersazooopythonCS492XOtkintermain.py", line 83, in pt
turnlabel.config(text=f'{p2} chance’)
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init_.py", line 1485, in configure
return self.configure(‘configure’, cnf, kw)
File "C:Program Files (x86)Microsoft Visual StudioSharedPython37_64libtkinter_init.py", line 1476, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
KeyboardInterrupt
Code :
from tkinter import *
import random
player = 1
gt = 0
gg = 0
retry = 0
Win = 1
Running = 0
Game = Running
Mark = 'X'
board = {1: " ", 2: " ", 3: " ", 4: " ", 5: " ", 6: " ", 7: " ", 8: " ", 9: " "}
def CheckPosition(x):
if board[x] == ' ':
return True
else:
return False
def CheckWin():
global Game
# Horizontal winning condition
if board[1] == board[2] and board[2] == board[3] and board[1] != ' ':
Game = Win
elif board[4] == board[5] and board[5] == board[6] and board[4] != ' ':
Game = Win
elif board[7] == board[8] and board[8] == board[9] and board[7] != ' ':
Game = Win
# Vertical Winning Condition
elif board[1] == board[4] and board[4] == board[7] and board[1] != ' ':
Game = Win
elif board[2] == board[5] and board[5] == board[8] and board[2] != ' ':
Game = Win
elif board[3] == board[6] and board[6] == board[9] and board[3] != ' ':
Game = Win
# Diagonal Winning Condition
elif board[1] == board[5] and board[5] == board[9] and board[5] != ' ':
Game = Win
elif board[3] == board[5] and board[5] == board[7] and board[5] != ' ':
Game = Win
# Match Tie or Draw Condition
elif (board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[
6] != ' ' and board[7] != ' ' and board[8] != ' ' and board[9] != ' '):
Game = retry
else:
Game = Running
def retryG():
for i in range(0,10):
board[i] = " "
button[i].config(text=" ")
# gg (0)=with pc , gg(1)=with player2
# gt (0)= easy , gt(1)=hard
# player(1)= player first, player(2)=pc first
# postion= button postion
def turn(player):
global p1, p2
if gg == 0:
if player == 1:
p1 = "User"
p2 = "PC"
else:
p1 = "PC"
p2 = "User"
elif gg == 1:
p1 = "Player 1 "
p2 = "Player 2 "
return p1, p2
def pt(player,choice):
global Mark
if player % 2 != 0:
turnlabel.config(text=f'{p1} chance')
Mark = 'X'
if p1 == "PC" and gt == 0:
choice = random.randrange(1, 9)
elif p1 == "PC" and gt == 1:
pass
elif player % 2 == 0:
turnlabel.config(text=f'{p2} chance')
Mark = 'O'
if p2 == "PC" and gt == 0:
choice = random.randrange(1, 9)
elif p1 == "PC" and gt == 1:
pass
return Mark,choice
def gameplay(choice):
global gg, gt, player, p1, p2
turn(player)
while (Game == Running):
pt(player,choice)
if CheckPosition(choice):
board[choice] = Mark
button[choice].config(text=str(Mark))
player += 1
CheckWin()
if Game != Running:
break
if Game == retry:
retryG()
elif Game == Win:
player -= 1
if player % 2 != 0:
print(f'{p1} Won')
turnlabel.config(text=f'{p1} Won')
else:
print(f'{p2} Won')
turnlabel.config(text=f'{p2} Won')
def raise_frame(frame):
frame.tkraise()
root = Tk()
f1 = Frame(root)
f2 = Frame(root)
f3 = Frame(root)
f4 = Frame(root)
for frame in (f1, f2, f3, f4):
frame.grid(row=0, column=0, sticky='news')
root.geometry("350x350")
root.title("X O Game")
# frame 1
welcome_label = Label(f1, text="Welcome to X O Game", font=20, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
playlabel = Label(f1, text="Play with : ", font=20, padx=10, pady=10).grid(row=1, column=0, rowspan=2)
PCg = Button(f1, text="PC", command=lambda gg=0: raise_frame(f2)).grid(row=1, column=1, padx=5, pady=5, ipadx=10,
ipady=10)
Pl2g = Button(f1, text="Player 2", command=lambda gg=1: [raise_frame(f4)]).grid(row=2, column=1, padx=5, pady=5,
ipadx=10, ipady=10)
exbut = Button(f1, text="exit", command=lambda: exit()).grid(row=3, column=1, ipadx=5, ipady=5, sticky="nsew")
# frame 2
xolabel1 = Label(f2, text="X O Game", font=30, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
fturnlabel = Label(f2, text="Who want to play first ? ", font=20, padx=10, pady=10).grid(row=1, column=0, columnspan=2)
PCtbut = Button(f2, text="PC", command=lambda player=2: raise_frame(f3)).grid(row=2, column=0, padx=5, pady=5, ipadx=10,
ipady=10)
YOUtbut = Button(f2, text="You", command=lambda player=1: raise_frame(f3)).grid(row=2, column=1, padx=5, pady=5,
ipadx=10, ipady=10)
backbut1 = Button(f2, text="back to menue", command=lambda: raise_frame(f1)).grid(row=3, column=0, ipadx=5, ipady=5,
columnspan=2)
# FRAME 3
xolabel2 = Label(f3, text="X O Game", font=30, padx=10, pady=10).grid(row=0, column=0, columnspan=4, )
typelabel = Label(f3, text="Choose game type ", font=20, padx=10, pady=10).grid(row=1, column=0, columnspan=2)
Hbut = Button(f3, text="Hard", command=lambda gt=1: raise_frame(f4)).grid(row=2, column=0, padx=5, pady=5, ipadx=10,
ipady=10) # gt means game type
Ebut = Button(f3, text="Easy", command=lambda gt=0: raise_frame(f4)).grid(row=2, column=1, padx=5, pady=5, ipadx=10,
ipady=10)
backbut2 = Button(f3, text="back to menue", command=lambda: raise_frame(f1)).grid(row=3, column=0, ipadx=5, ipady=5,
columnspan=2)
# frame 4
toplabel = Label(f4, text="X O Game", font=20, padx=10, pady=10).grid(row=0, column=0, columnspan=3)
turnlabel = Label(f4, text=" ", font=16)
turnlabel.grid(row=1, column=0, columnspan=2)
button1 = Button(f4, text=" ", command=lambda: gameplay(1))
button1.grid(row=2, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button2 = Button(f4, text=" ", command=lambda: gameplay(2))
button2.grid(row=2, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button3 = Button(f4, text=" ", command=lambda: gameplay(3))
button3.grid(row=2, column=2, padx=5, pady=5, ipadx=10, ipady=10)
button4 = Button(f4, text=" ", command=lambda: gameplay(4))
button4.grid(row=3, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button5 = Button(f4, text=" ", command=lambda: gameplay(5))
button5.grid(row=3, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button6 = Button(f4, text=" ", command=lambda: gameplay(6))
button6.grid(row=3, column=2, padx=5, pady=5, ipadx=10, ipady=10)
button7 = Button(f4, text=" ", command=lambda: gameplay(7))
button7.grid(row=4, column=0, padx=5, pady=5, ipadx=10, ipady=10)
button8 = Button(f4, text=" ", command=lambda: gameplay(8))
button8.grid(row=4, column=1, padx=5, pady=5, ipadx=10, ipady=10)
button9 = Button(f4, text=" ", command=lambda: gameplay(9))
button9.grid(row=4, column=2, padx=5, pady=5, ipadx=10, ipady=10)
buttonretry = Button(f4, text="Retry").grid(row=5, column=0, padx=5, pady=5, ipadx=10, ipady=10, columnspan=3)
backbut = Button(f4, text="back to menue", command=lambda: raise_frame(f1)).grid(row=6, column=0, ipadx=5, ipady=5,columnspan=3)
button = ["", button1, button2, button3, button4, button5, button6, button7, button8, button9]
raise_frame(f1)
root.mainloop()
It seems that the issue is caused by the line turnlabel.config(text=f'{p2} chance')
. You should make sure that the turnlabel
object exists and that it has the config
method.
Also, you need to define p1
and p2
before you use them in the pt
function.
Here is a corrected version of your code:
from tkinter import *
import random
player = 1
gt = 0
gg = 0
retry = 0
Win = 1
Running = 0
Game = Running
Mark = 'X'
board = {1: " ", 2: " ", 3: " ", 4: " ", 5: " ", 6: " ", 7: " ", 8: " ", 9: " "}
p1 = ""
p2 = ""
def CheckPosition(x):
if board[x] == ' ':
return True
else:
return False
I think you need to take a look at your game’s logic flow. Ignoring the formatting concerns, your buttons initiate the gameplay()
function when it is clicked.
This launches a while loop with the condition of Game == Running
. Within this while loop, the only time Game
is changed is within CheckWin()
, and unless there’s a win or a tie, Game
is always changed to Running
.
There is no way for it to exit this loop on the first few clicks. Something to consider is why the loop is required in the first place, or if it is even required at all? Also, even if it is necessary, having if Game != Running: break
is unnecessary. If Game != Running
at that position in the code, it would fail the while condition and exit the loop anyway.
def gameplay(choice):
global gg, gt, player, p1, p2
turn(player)
pt(player,choice)
if CheckPosition(choice):
board[choice] = Mark
button[choice].config(text=str(Mark))
player += 1
CheckWin()
if Game == retry:
retryG()
elif Game == Win:
player -= 1
if player % 2 != 0:
print(f'{p1} Won')
turnlabel.config(text=f'{p1} Won')
else:
print(f'{p2} Won')
turnlabel.config(text=f'{p2} Won')
Removing the while loop will get it to work, but there are still a lot of problems with the code. For example, in retryG()
you are looping through button[i].config(...)
for i in range(0,10)
. However, your button[0] is a string and has no .config()
. Because of how tkinter works this won’t terminate your program, but it is throwing exceptions back. Also, the use of global variables when they are unnecessary can make your code more difficult to debug.
Lastly, for code readability, refer to the PEP 8 style guide so the code is more consistent and readable.