Я пытаюсь закодировать «камень-ножницы-бумага» в tkinter python, но моя команда кнопки сброса выдает ошибку:
Traceback (most recent call last):
File "C:\Python36\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "c:/Users/---------/OneDrive - -------------/python/rock paper scissors.py", line 26, in reset
run()
File "c:/Users/-----------/OneDrive - ---------------/python/rock paper scissors.py", line 186, in run
choose_player_number()
File "c:/Users/--------------/OneDrive - -----------------/python/rock paper scissors.py", line 181, in choose_player_number
one_player.grid(column= 2, row=1)
File "C:\Python36\lib\tkinter\__init__.py", line 2220, in grid_configure
+ self._options(cnf, kw))
_tkinter.TclError: bad window path name ".!button5"
PS C:\Users\N.Westrich>
Я не знаю, как получить доступ к библиотеке tkinter, поэтому не знаю, что сбивает программу. Мой код здесь:
import random
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.geometry("1400x860")
window.title = "Rock paper scissors"
result = Label(window, text= "result will appear here", bg = "green")
player_number = ""
list_of_integers = ["1", "2", "3"]
title = Label(window, text = "Rock paper scissors" , bg= "blue", fg = "white", font= "Times")
title.grid(column=3, row=0)
def reset():
filler.destroy
filler2.destroy
filler3.destroy
title.destroy
result.destroy
rock.destroy
paper.destroy
scissors.destroy
reset1.destroy
run()
reset1 = Button(window, text = "Reset", command= reset, fg = "blue", bg = "yellow")
def evaluate_rock():
global computer_input
if computer_input == "3":
win()
elif computer_input == "2":
loose()
else:
draw()
def evaluate_scissors():
global computer_input
if computer_input == "2":
win()
elif computer_input == "1":
loose()
else:
draw()
def evaluate_paper():
global computer_input
if computer_input == "1":
win()
elif computer_input == "3":
loose()
else:
draw()
def computer_choice(input):
global computer_input
computer_input = random.choice(list_of_integers)
if computer_input == "1":
computer_value = "Rock"
elif computer_input == "2":
computer_value = "paper"
else:
computer_value = "scissors"
computer_result = Label(window, text= "the computer's choice was: " + computer_value , fg = "blue", bg = "green")
computer_result.grid(column=3, row=3)
if input == "rock":
evaluate_rock()
elif input == "scissors":
evaluate_scissors()
else:
evaluate_paper()
return computer_input
rock = Button(window, text = "Rock", command= lambda: computer_choice("rock"), fg = "green", bg = "blue")
scissors = Button(window, text = "Scissors", command = lambda: computer_choice("scissors"), fg = "black", bg = "blue")
paper = Button(window, text = "paper", command = lambda: computer_choice("paper"), fg = "green", bg = "blue")
player_1 = Label(window, text = "Player 1", fg = "blue", bg = "red")
player_2 = Label(window, text= "Player 2", fg= "blue", bg= "red")
def evaluate():
if player1input == player2input:
result.configure(text= "Draw")
elif player1input == "rock" and player2input == "scissors":
result.configure(text= "Player 1 wins")
elif player1input == "rock" and player2input == "paper":
result.configure(text= "player 2 wins")
elif player2input == "rock" and player1input == "scissors":
result.configure(text= "Player 2 wins")
elif player2input == "rock" and player1input == "paper":
result.configure(text= "Player 1 wins")
elif player1input == "paper" and player2input == "scissors":
result.configure(text= "player 2 wins")
elif player2input == "paper" and player1input == "scissors":
result.configure(text= "Player 1 wins")
reset1.grid(column= 3, row= 5)
def player_2_input(p2i):
global player2input
player2input = p2i
rock.destroy
paper.destroy
scissors.destroy
player_2.destroy
evaluate()
return player2input
def player2():
player_1.destroy
player_2.grid(column= 3, row= 2)
rock.configure(command = lambda: player_2_input("rock"))
paper.configure(command= lambda: player_2_input("paper"))
scissors.configure(command= lambda: player_2_input("scissors"))
def player_1_input(p1i):
global player1input
player1input = p1i
player2()
return player1input
def win():
result.configure(text= "You Win")
reset1.grid(column= 3, row= 5)
def loose():
result.configure(text= "You loose")
reset1.grid(column= 3, row= 5)
def draw():
result.configure(text= "Draw")
reset1.grid(column= 3, row= 5)
def place_buttons():
result.grid(column=3, row=1)
if player_number == 1:
rock.grid(column=2, row=2)
scissors.grid(column = 4, row=2)
paper.grid(column = 3, row=2)
elif player_number == 2:
player_1.grid(column= 3, row= 2)
rock.configure(command = lambda: player_1_input("rock"))
paper.configure(command= lambda: player_1_input("paper"))
scissors.configure(command= lambda: player_1_input("scissors"))
rock.grid(column=2, row=3)
scissors.grid(column = 4, row=3)
paper.grid(column = 3, row=3)
one_player = Button(window, text = "One Player", command = lambda: [oneplayer(), place_buttons()])
two_players = Button(window, text= "Two players", command = lambda: [twoplayers(), place_buttons()])
def oneplayer():
title.configure(text = "One player")
title.grid(column=3, row=0)
global player_number
player_number = 1
one_player.destroy()
two_players.destroy()
def twoplayers():
title.configure(text = "Two players")
title.grid(column=3, row=0)
global player_number
player_number = 2
one_player.destroy()
two_players.destroy()
def add_fillers():
global filler
filler = Label(window, text = " ")
filler.grid(column=1, row=0)
global filler2
filler2 = Label(window, text = " ")
filler2.grid(column=0, row=0)
global filler3
filler3 = Label(window, text = " ")
filler3.grid(column=2, row=0)
def choose_player_number():
one_player.grid(column= 2, row=1)
two_players.grid(column= 4, row=1)
def run():
add_fillers()
choose_player_number()
run()
window.mainloop()
Я не нашел никаких решений в Интернете, поскольку все они были специфичными для каждого конкретного случая.
Если у кого-то есть решение, мне бы хотелось знать, как наконец завершить код.
это не решает проблему, поскольку виджеты не уничтожаются. он также не перезапускает программу, чего я и хочу добиться с помощью кнопки сброса
Здесь вы найдете решение, но оно, на мой взгляд, не самое лучшее stackoverflow.com/a/41655930/12621346. Замените эти две строки вместо run().
def сброс(): filler.destroy filler2.destroy filler3.destroy title.destroy result.destroy rock.after(3, rock.destroy) paper.after(3, paper.destroy) scissors.after(3, scissors.destroy) Computer_result.after(3, Computer_result.destroy) result.after(3, result.destroy) сброс1.after(3, reset1.destroy) run()
def oneplayer(): title.configure(text = "Один игрок") title.grid(столбец=3, строка=0) global player_number player_number = 1 one_player.grid_forget() two_players.grid_forget() rock.grid_forget() paper. Grid_forget() scissors.grid_forget() reset1.grid_forget() Computer_result.grid_forget() result.grid_forget()
То же, что и twoplayer().
После этого все еще появляется ошибка _tkinter.TclError: неправильное имя пути к окну ".!button2" Попробуйте сами.
computer_result = Label(window, fg = "blue", bg = "green")
должно быть вне функции. И computer_result.configure(text= "the computer's choice was: " + computer_value)
внутри computer_choice()
функции.
Вот скриншот [![введите описание изображения здесь][1]][1] [1]: i.sstatic.net/bDBqL3Ur.gif
Можете ли вы попробовать переименовать путь к окну из файла init.py библиотеки tkinter. Я думаю, это поможет вам, или вы можете использовать «_» после слов вашего пути.
Ваш ответ можно улучшить, добавив дополнительную вспомогательную информацию. Пожалуйста, отредактируйте , добавив дополнительную информацию, например цитаты или документацию, чтобы другие могли подтвердить правильность вашего ответа. Более подробную информацию о том, как писать хорошие ответы, вы можете найти в справочном центре.
Ваш импорт:
import tkinter as tk
Поэтому ваши кнопки, метки и другие виджеты называются, например. tk.Label(….)
:
reset1 = tk.Button(window, text = "Reset", command= reset, fg = "blue", bg = "yellow")
Рекомендую вам прочитать документ
Та же ошибка, что и у ОП.
Я не понимаю, что мне следует изменить.
Вы уничтожаете две кнопки one_player
и two_players
внутри oneplayer()
и twoplayers()
, поэтому, когда choose_player_numbers()
выполняется снова при нажатии кнопки reset1
, будет возбуждено исключение.
Измените строки:
one_player.destroy()
two_players.estroy()
внутри oneplayer()
и twoplayers()
, чтобы:
one_player.grid_forget()
two_players.grid_forget()
Обратите внимание, что даже после устранения этой проблемы в вашем коде все равно останутся другие проблемы.
знаете ли вы, почему другие виджеты не уничтожаются? Спасибо за помощь, я ценю это!
@neo Потому что xxxx.destroy
не выполняет функцию destroy
в виджете xxxx
. Вместо этого вам нужно вызвать xxxx.destroy()
.
Ваша проблема заключается в вызове в строке 26 run(). Закомментируйте #run()