gjjhhh_
gjjhhh_

Reputation: 169

Python tkinter entry prompt

I want to prompt a string of letters one for each time to ask user to click and the game will continue only when user press the correct key.

I am having trouble with the key pressing part. I want to get the text on the button and test if it matches with the prompted letter, if it matches the entry widget will prompt the next letter otherwise it just stays still.

I imported random to shuffle the letters so that every time it will generates different letters. I did not add the random.shuffle(alist), because it does not work.

here is my code:

from tkinter import *
from tkinter.ttk import *
import random
import tkinter

class KeyboardGame:
    def __init__(self):
        window = Tk()
        window.title('haha')
        self.value = StringVar()
        self.value.set('click on any key to start...')
        btm_frame = Frame(window, relief=RAISED)
        entry = Entry(window, text=self.value)
        entry.grid(row=0, column=0, padx=40, pady=5, sticky='EW')
        for i in ['ixnsywfhze', 'uobpqgtav', 'lmjkcdr']:
            frame1 = Frame(btm_frame)
            for j in i:
                button = Button(frame1, text=j, command=self.game)
                button.pack(side=LEFT)
                frame1.pack(padx=2, pady=2)

        btm_frame.grid(row=1, column=0, padx=5, pady=5)
        window.mainloop()



    def game(self):
        n = 0
        alist = ['h', 'c', 'p', 'e', 'm', 'n', 'd']

        self.value.set(alist[n])
        while button['text'] != alist[n]:
            self.value.set(alist[n])
        n += 1



KeyboardGame()

Upvotes: 1

Views: 1650

Answers (1)

Billal BEGUERADJ
Billal BEGUERADJ

Reputation: 22754

You can resolve your problem by binding the same event to each button you created.

Hence, in your callback you will need to identify the button which is clicked (which thing your actual code does not do) in order to compare its text using cget() method to the content of the entry widget.

Notice that in order to increment n inside game() you will need to render it as an instance variable. You must be careful not to increment it when it reaches the same value as the alist's length.

Full program

Here are the ideas mentioned above implemented. Note that I focus on fixing your issues only. This means I am not going to comment the best practices you should follow:

from tkinter import *
from tkinter.ttk import *
import tkinter

class KeyboardGame:

   def __init__(self):
       window = Tk()
       window.title('haha')
       self.value = StringVar()
       self.value.set('h')
       self.btm_frame = Frame(window, relief=RAISED)
       self.entry = Entry(window, text=self.value)
       self.entry.grid(row=0, column=0, padx=40, pady=5, sticky='EW')
       self.n = 0

       for i in ['ixnsywfhze', 'uobpqgtav', 'lmjkcdr']:
           self.frame1 = Frame(self.btm_frame)
           for j in i:
               button = Button(self.frame1, text=j)
               button.pack(side=LEFT)
               button.bind("<Button-1>", self.game)
               self.frame1.pack(padx=2, pady=2)

       self.btm_frame.grid(row=1, column=0, padx=5, pady=5)
       window.mainloop()



   def game(self, event):
       alist = ['h', 'c', 'p', 'e', 'm', 'n', 'd']  
       w = event.widget # Identify the button
       if w.cget("text") == self.value.get() and self.n < 6:
           self.n = self.n + 1
           self.value.set(alist[self.n])   

# Start program
if __name__ =="__main__":
   KeyboardGame()

Demo

Here is a screenshot of the running above program:

enter image description here

Upvotes: 3

Related Questions