#python #user-interface #tkinter
#python #пользовательский интерфейс #tkinter
Вопрос:
Я пытаюсь написать графический интерфейс, который эмулирует игру Hangman, используя Tkinter. До сих пор я получил графический интерфейс для создания метки, которая обновляется на основе букв, которые пользователь угадал правильно, но терминал по-прежнему выдает ошибку: «TypeError: аргумент типа’StringVar’ не является итеративным». Я рассмотрел другие решения этой ошибки, но не смог понять, как решить проблему.
Это еще не сделано, но пока что это код:
import randomword
# from PyDictionary import PyDictionary
from tkinter import *
root = Tk()
playerWord: str = randomword.get_random_word()
word_guess: str = ''
guesses = ''
def returnEntry(arg=None):
global word_guess
global guesses
global wordLabel
word_guess = ''
# dictionary = PyDictionary()
failed = 0
incorrect = 10
result = myEntry.get()
while incorrect > 0:
if not result.isalpha():
resultLabel.config(text="that's not a letter")
elif len(result) != 1:
resultLabel.config(text="that's not a letter")
else:
resultLabel.config(text=result)
assert isinstance(END, object)
myEntry.delete(0, END)
guesses = result
for char in playerWord:
if char in guesses:
# Print the letter they guessed
word_guess = char
elif char not in guesses:
# Print "_" for every letter they haven't guessed
word_guess = "_ "
failed = 1
if guesses[len(guesses) - 1] not in playerWord:
resultLabel.config(text="wrong")
incorrect -= 1
wordLabel = Label(root, updateLabel(word_guess))
myEntry.delete(0, END)
resultLabel = Label(root, text="")
resultLabel.pack(fill=X)
myEntry = Entry(root, width=20)
myEntry.focus()
myEntry.bind("<Return>", returnEntry)
myEntry.pack()
text = StringVar()
text.set("your word is: " ("_ " * len(playerWord)))
wordLabel = Label(root, textvariable=text)
wordLabel.pack()
def updateLabel(word):
text.set("your word is: " word)
return text
mainloop()
проблема возникает, когда я запускаю функцию для wordLabel: «wordLabel = Label(root, updateLabel (word_guess))» для сброса метки. Любые предложения о том, как я могу обновить метку до word_guess после итерации цикла while?
Комментарии:
1. Можете ли вы включить обратную трассировку python, чтобы мы могли видеть полный текст ошибки плюс строку с ошибкой?
Ответ №1:
Эта строка вызывает ошибку:
wordLabel = Label(root, updateLabel(word_guess))
Вы переоценили это. Это должно быть просто так:
updateLabel(word_guess)
У вас также есть еще одна серьезная ошибка. Эта строка:
while incorrect > 0:
Приведет к блокировке вашей программы. Вам нужно изменить его на это:
if incorrect > 0:
Ответ №2:
wordLabel = Label(root, updateLabel(word_guess))
Вы пытаетесь создать новый Label
и сделать глобальную wordLabel
ссылку на новую метку вместо старой. Даже если бы он работал правильно, это не привело бы к обновлению вашего графического интерфейса, поскольку новая метка не упакована.
Причина, по которой он прерывается, заключается в том, что, хотя updateLabel
он изменяет содержимое StringVar
имени text
и возвращает его обратно, он не используется в качестве textvariable
новой метки. Помимо указания родительского виджета, вы должны использовать только аргументы ключевого слова для конструктора, иначе аргумент, вероятно, будет интерпретироваться иначе, чем вы ожидаете. (Честно говоря, я удивлен, что вы вообще можете вызывать функцию таким образом; я бы ожидал a TypeError
в момент вызова.)
В любом случае, все, что вам нужно сделать, поскольку text
оно также является глобальным, — это напрямую .set
преобразовать его в новый текст. Это автоматически обновит внешний вид wordLabel
(по модулю любого материала tkinter, необходимого для обновления отображения в целом) — в этом смысл класса контейнера StringVar (в отличие от простого использования простой строки).