Tkinter问题创建按钮来收集用户的文本

时间:2018-10-06 22:12:26

标签: python user-interface tkinter nameerror tkinter-entry

我是Tkinter的新手,正在尝试创建一个hangman应用。我已经创建了一个命令行版本,所以我认为这将是一个不错的入门项目。在学习时,我被告知要使用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()

2 个答案:

答案 0 :(得分:0)

首先,在使用tkinter模块时,不建议使用while循环,因为该窗口将在主线程上运行。从逻辑上讲,使用按钮时,可以使用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())

请注意两件事:

答案 1 :(得分:0)

mainloop()连续监听您定义的任何钩子,这意味着您不必担心。只需定义正确的钩子,就像button命令一样。

我介绍了一种更好的方法来处理图像,方法是将它们放在列表中,然后为每个请求的图像缩小列表。这样可以更轻松地更新图像。

然后将所有处理工作,例如检查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