Neos Nokia
Neos Nokia

Reputation: 123

Using Python to update labels Tkinter

I am in the process of making a Hangman type game. So far, I have written the CLI version which works well, i'm just porting it over to create a GUI.

I have become stuck :-(. The program is not complete, and there's still more to do but I have two issues. The first is the label update.

When a letter is chosen, it creates enough dashes for the letter, and places this in a label called 'letter'.

When a user enters a letter, it replaces the dashes, however it then adds a new label next to the old label, instead, I would like to replace this label. I have tried using the .set() but this doesn't seem to work.

My second issue, and this is more of a logic error (I think), is that I wanted to keep track of the letters entered so that I could compare this to newly entered letters and alert the user. This works well, however when a letter has been entered it will warn the user even if its the first time it has been typed.

Here's the code:

import tkinter
from tkinter import *
from tkinter import messagebox
import random

guesses = 8

def play():
    print("play game")

    wordList = ["talking", "dollar","choice", "famous", "define", "features"]

    wordChoice = random.choice(wordList)

    print(wordChoice)
    wordLength = (len(wordChoice))
    print(wordLength)
    guessedLetters = []
    dashes = []

    def enterLetter():
        print("Guess")
        global guesses

        print(guessedLetters)

        while guesses != 0:
            guess = entry.get().lower()

            if len(guess) >1:
                messagebox.showinfo("Error","Sorry, only one letter at a time")
                entry.delete("0","end")
                return
            elif guess.isalpha() == False:
                messagebox.showinfo("Error","Letters only please")
                entry.delete("0","end")
                return
            elif guess in guessedLetters:
                messagebox.showinfo("Error","You have already used the letter")
                entry.delete("0","end")
                return

            guessedLetters.append(guess)
            print(guessedLetters)
            print(guesses)
            count = 0


            for i in range(wordLength):
                if wordChoice[i] == guess:
                    dashes[i] = guess
                    count = count +1
                    letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)

            if count == 0:
                guesses -= 1

            if guesses == 0:
                print("You have ran out of guesses!")
                print("The word was:",wordChoice)

    ######  Play Game GUI


    play = Toplevel()
    play.title("Play Hangman!")

    label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
    label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)

    for i in range(wordLength):
        dashes.append("-")

    letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)


    entry = Entry(play)
    entry.grid(row = 3, column = 1, columnspan = wordLength) 
    enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
    label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
    label = Label(play, text = "").grid(row= 4, columnspan = 6)



def scores():
    print("check scores")

def howToPlay():
    print("how to play")



####### Main Menu

root = Tk()
root.geometry("500x300")                                                                    
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)    
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2) 
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2) 
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1) 
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2) 
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)


root.mainloop()

Upvotes: 0

Views: 115

Answers (2)

Stevo Mitric
Stevo Mitric

Reputation: 1619

The reason you cant update your label is because you haven't stored it in any variable. The grid, pack and place functions of the Label object and of all other widgets returns None, therefore when you call:

letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)

your label cannot be accessed by variable letter. To fix this you should split it like so:

letter = Label(play, text = dashes, font = ("Arial",20))
letter.grid(row = 2, column = i+1,padx = 10, pady =10)

To update text of that label, you can call .configure(text = 'new text') on it.

# letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)    # 

letter.configure(text = dashes)

As for your second issue, i think you confused while loop and if statement in the function enterLetter. It's called once per click and you only need to check one time if player has ran out of guesses.

if guesses != 0:
    ...

elif guesses == 0:
    ....

Upvotes: 1

Grimmauld
Grimmauld

Reputation: 322

  1. You need to configure the Label, not recreate it.
  2. Why do you use a while-loop in enter_letter? Its just run when the Button is clicked, it needs to be an if guesses > 0:
  3. Your program did not terminate when the right word was entered; I added this.

Code:

import tkinter
from tkinter import *
from tkinter import messagebox
import random

guesses = 8

letter = None

def play():
    global letter

    print("play game")

    wordList = ["talking", "dollar","choice", "famous", "define", "features"]

    wordChoice = random.choice(wordList)

    print(wordChoice)
    wordLength = (len(wordChoice))
    print(wordLength)
    guessedLetters = []
    dashes = []


    play = Toplevel()
    play.title("Play Hangman!")

    label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
    label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)

    for i in range(wordLength):
        dashes.append("-")

    letter = Label(play, text = dashes, font = ("Arial",20))
    letter.grid(row = 2, column = i+1,padx = 10, pady =10)
    print(letter)

    def enterLetter():
        print("Guess")
        global guesses, letter

        print(guessedLetters)

        if guesses != 0:
            guess = entry.get().lower()

            if len(guess) >1:
                messagebox.showinfo("Error","Sorry, only one letter at a time")
                return
            elif guess.isalpha() == False:
                messagebox.showinfo("Error","Letters only please")
                return
            elif guess in guessedLetters:
                messagebox.showinfo("Error","You have already used the letter")
                return
            entry.delete("0","end")
            guessedLetters.append(guess)
            #print(guessedLetters)
            #print(guesses)
            print(dashes)
            count = 0


            for i in range(wordLength):
                if wordChoice[i] == guess:
                    dashes[i] = guess
                    count += 1
                    letter.configure(text = dashes)


            if count == 0:
                guesses -= 1

            if "".join(dashes) == wordChoice:
                print("succsess!")
                play.destroy()
                return

            if guesses == 0:
                print("You have ran out of guesses!")
                print("The word was:",wordChoice)

    ######  Play Game GUI


    entry = Entry(play)
    entry.grid(row = 3, column = 1, columnspan = wordLength) 
    enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
    label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
    label = Label(play, text = "").grid(row= 4, columnspan = 6)



def scores():
    print("check scores")

def howToPlay():
    print("how to play")



####### Main Menu

root = Tk()
root.geometry("500x300")                                                                    
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)    
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2) 
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2) 
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1) 
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2) 
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)


root.mainloop()

I hope this helps you.

Upvotes: 1

Related Questions