Tkinter 问题创建按钮从用户收集文本
Tkinter problem creating button to collect text from user
我是 Tkinter 的新手,正在尝试创建一个刽子手应用程序。我已经创建了一个命令行版本,所以我认为这将是一个不错的开始项目。在学习时,我被告知对 creating/updating 使用 window.mainloop(),但是我的程序包含一个 while 循环,所以这没有用。我根本无法在我创建的文本框中输入内容,当我单击该按钮时,它会给我一个 NameError 提示我的 click() 方法中的 textEntry 未定义。任何有关其他地方的帮助或指导将不胜感激。谢谢!我的代码贴在下面
from tkinter import *
from random import choice
def click():
guess = textEntry.get()
return guess
def main():
input_file = open('hangman_word_list.txt','r')
word_list = input_file.read().split()
window = Tk()
window.title("Play Hangman!")
window.configure(background="black")
p1 = PhotoImage(file='h1.gif')
p2 = PhotoImage(file='h2.gif')
p3 = PhotoImage(file='h3.gif')
p4 = PhotoImage(file='h4.gif')
p5 = PhotoImage(file='h5.gif')
p6 = PhotoImage(file='h6.gif')
Label(window,image=p1,bg="purple").grid(row=0,column=0,columnspan=4)
word = choice(word_list)
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
lives = 6
again = True
nowPhoto = p1
guess = 'empty'
while lettersLeft > 0 and again == True:
Label(window,text="Your word is "+hiddenWord ,bg="gray",fg="purple",font="none 12 bold").grid(row=1,column=0,sticky=W)
Label(window,text="Enter a letter: " ,bg="gray",fg="purple",font="none 12 bold").grid(row=2,column=0,sticky=W)
textEntry = Entry(window,width=5,bg="white")
textEntry.grid(row=2,column=1,sticky=W)
guess = Button(window,text="Guess",width=5,command=click).grid(row=3,column=2,sticky=W)
window.update()
main()
首先,在使用 tkinter 模块时不建议使用 while 循环,因为 window 在主线程上会是 运行。从逻辑上讲,在使用按钮时,可以使用 if 语句,这样直到 lettersLeft > 0 and again == True
才会触发特定的代码部分。并且在函数中使用变量 textEntry
显然对 Python 不可用,因为没有声明它。所以你要么将变量作为参数传递,要么声明一个全局变量。
以下是我的想法:
from tkinter import *
from random import choice
def get_wordlist():
return open("Hangman word list.txt", 'r').read().split("split by something here.")
class Hangman(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title("Hangman")
self.master.configure(bg="black")
self.wordlist = get_wordlist()
self.p1 = PhotoImage(file="h1.gif")
self.word = choice(self.wordlist)
self.hidden_word = list("".join("_" for x in word))
self.wrong_guess = []
self.lives = 6
self.word_display = Label(window, text=str(*(hidden for hidden in hidden_word)), image=p1, bg="purple", fg="white")
self.word_display.grid(row=0, column=0, columnspan=4)
Label(window, text="Enter a letter: ", bg="gray", fg="purple", font="none 12 bold").grid(row=2, column=0, sticky=W)
self.entry = Entry(window, width=5, bg="white")
self.entry.grid(row=2, column=1, sticky="W")
self.guess = Button(window, text="Guess", command=lambda: button_action(self))
self.guess.grid()
self.again = False
def button_action(self):
user_input = self.entry.get()
if len(user_input) == len(word):
for i in range(len(word)):
if word[i] == user_input[i]:
self.hidden_word[i] = word[i]
if "_" not in self.hidden_word:
self.word_display.config(text="You won! The correct word was: " + self.word)
self.after(3000, self.quit())
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
if self.lives <= 0:
self.word_display.config(text="You lost! The correct word was: " + self.word)
self.master.after(3000, self.quit())
请注意两件事:
- 尽量不要创建冗余变量
- 在提问之前,请先看看 python tkinter docs。
mainloop()
会连续侦听您定义的任何挂钩,这意味着您不必为此担心。只需定义正确的钩子,如按钮命令。
我介绍了一种更好的处理图像的方法,即把它们放在一个列表中,然后为每个请求的图像减少列表。这使得更新图像更容易。
然后把所有的处理,比如检查单词中是否有被使用的字母等都放在click()
函数中。
from tkinter import *
window = Tk()
# Make a list of all the pictures
pic_list = ['h6.gif','h5.gif','h4.gif','h3.gif','h2.gif','h1.gif']
img = PhotoImage(file=pic_list.pop()) # Get image from list of images
hangman = Label(window, image=img) # Save reference to the Label as
hangman.grid(row=0,column=0,columnspan=4) # you will update it later
# I simplified the word selection a bit
word = 'Wensleydale'
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
guess = 'empty'
# Build the rest of the GUI
Label(window,text="Your word is " + hiddenWord, bg="gray", fg="purple",
font="none 12 bold").grid(row=1, column=0, sticky=W, columnspan=4)
Label(window,text="Enter a letter: ", bg="gray", fg="purple",
font="none 12 bold").grid(row=2, column=0, sticky=W)
textEntry = Entry(window, width=10, bg="white")
textEntry.grid(row=2, column=1, sticky=W, columnspan=3)
def click(): # Callback function
guess = textEntry.get()
# Put all other processing here.
# Updating the image
img = PhotoImage(file=pic_list.pop()) # Get next image from list
hangman.configure(image=img) # Replace image in label
hangman.image = img # Keep reference to the new image
# Create button and associate it with the command callback function
guess_button = Button(window, text="Guess", width=5,
command=click).grid(row=3, column=2, sticky=W)
window.mainloop() # Will loop continously listening for buttonpress
我是 Tkinter 的新手,正在尝试创建一个刽子手应用程序。我已经创建了一个命令行版本,所以我认为这将是一个不错的开始项目。在学习时,我被告知对 creating/updating 使用 window.mainloop(),但是我的程序包含一个 while 循环,所以这没有用。我根本无法在我创建的文本框中输入内容,当我单击该按钮时,它会给我一个 NameError 提示我的 click() 方法中的 textEntry 未定义。任何有关其他地方的帮助或指导将不胜感激。谢谢!我的代码贴在下面
from tkinter import *
from random import choice
def click():
guess = textEntry.get()
return guess
def main():
input_file = open('hangman_word_list.txt','r')
word_list = input_file.read().split()
window = Tk()
window.title("Play Hangman!")
window.configure(background="black")
p1 = PhotoImage(file='h1.gif')
p2 = PhotoImage(file='h2.gif')
p3 = PhotoImage(file='h3.gif')
p4 = PhotoImage(file='h4.gif')
p5 = PhotoImage(file='h5.gif')
p6 = PhotoImage(file='h6.gif')
Label(window,image=p1,bg="purple").grid(row=0,column=0,columnspan=4)
word = choice(word_list)
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
lives = 6
again = True
nowPhoto = p1
guess = 'empty'
while lettersLeft > 0 and again == True:
Label(window,text="Your word is "+hiddenWord ,bg="gray",fg="purple",font="none 12 bold").grid(row=1,column=0,sticky=W)
Label(window,text="Enter a letter: " ,bg="gray",fg="purple",font="none 12 bold").grid(row=2,column=0,sticky=W)
textEntry = Entry(window,width=5,bg="white")
textEntry.grid(row=2,column=1,sticky=W)
guess = Button(window,text="Guess",width=5,command=click).grid(row=3,column=2,sticky=W)
window.update()
main()
首先,在使用 tkinter 模块时不建议使用 while 循环,因为 window 在主线程上会是 运行。从逻辑上讲,在使用按钮时,可以使用 if 语句,这样直到 lettersLeft > 0 and again == True
才会触发特定的代码部分。并且在函数中使用变量 textEntry
显然对 Python 不可用,因为没有声明它。所以你要么将变量作为参数传递,要么声明一个全局变量。
以下是我的想法:
from tkinter import *
from random import choice
def get_wordlist():
return open("Hangman word list.txt", 'r').read().split("split by something here.")
class Hangman(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title("Hangman")
self.master.configure(bg="black")
self.wordlist = get_wordlist()
self.p1 = PhotoImage(file="h1.gif")
self.word = choice(self.wordlist)
self.hidden_word = list("".join("_" for x in word))
self.wrong_guess = []
self.lives = 6
self.word_display = Label(window, text=str(*(hidden for hidden in hidden_word)), image=p1, bg="purple", fg="white")
self.word_display.grid(row=0, column=0, columnspan=4)
Label(window, text="Enter a letter: ", bg="gray", fg="purple", font="none 12 bold").grid(row=2, column=0, sticky=W)
self.entry = Entry(window, width=5, bg="white")
self.entry.grid(row=2, column=1, sticky="W")
self.guess = Button(window, text="Guess", command=lambda: button_action(self))
self.guess.grid()
self.again = False
def button_action(self):
user_input = self.entry.get()
if len(user_input) == len(word):
for i in range(len(word)):
if word[i] == user_input[i]:
self.hidden_word[i] = word[i]
if "_" not in self.hidden_word:
self.word_display.config(text="You won! The correct word was: " + self.word)
self.after(3000, self.quit())
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
if self.lives <= 0:
self.word_display.config(text="You lost! The correct word was: " + self.word)
self.master.after(3000, self.quit())
请注意两件事:
- 尽量不要创建冗余变量
- 在提问之前,请先看看 python tkinter docs。
mainloop()
会连续侦听您定义的任何挂钩,这意味着您不必为此担心。只需定义正确的钩子,如按钮命令。
我介绍了一种更好的处理图像的方法,即把它们放在一个列表中,然后为每个请求的图像减少列表。这使得更新图像更容易。
然后把所有的处理,比如检查单词中是否有被使用的字母等都放在click()
函数中。
from tkinter import *
window = Tk()
# Make a list of all the pictures
pic_list = ['h6.gif','h5.gif','h4.gif','h3.gif','h2.gif','h1.gif']
img = PhotoImage(file=pic_list.pop()) # Get image from list of images
hangman = Label(window, image=img) # Save reference to the Label as
hangman.grid(row=0,column=0,columnspan=4) # you will update it later
# I simplified the word selection a bit
word = 'Wensleydale'
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
guess = 'empty'
# Build the rest of the GUI
Label(window,text="Your word is " + hiddenWord, bg="gray", fg="purple",
font="none 12 bold").grid(row=1, column=0, sticky=W, columnspan=4)
Label(window,text="Enter a letter: ", bg="gray", fg="purple",
font="none 12 bold").grid(row=2, column=0, sticky=W)
textEntry = Entry(window, width=10, bg="white")
textEntry.grid(row=2, column=1, sticky=W, columnspan=3)
def click(): # Callback function
guess = textEntry.get()
# Put all other processing here.
# Updating the image
img = PhotoImage(file=pic_list.pop()) # Get next image from list
hangman.configure(image=img) # Replace image in label
hangman.image = img # Keep reference to the new image
# Create button and associate it with the command callback function
guess_button = Button(window, text="Guess", width=5,
command=click).grid(row=3, column=2, sticky=W)
window.mainloop() # Will loop continously listening for buttonpress