Search code examples
pythonpython-3.xtkinterlabeltkinter-layout

How to position a text in a label randomly in Tkinter


I'm a beginner in coding also more than a beginner in Python. The teacher gave us a game project in which we have to develop a memory game that first we choose the difficulty(how many numbers there are to keep in mind) and then these numbers are gonna appear one by one with 1 sec interval and then the user is gonna submit the answer .if user gets all the numbers right,go to the next level(increment the difficulty by one),else quit .but these numbers have to appear on the label in random positions.but in mine they appear on a specific position is there a way to make the numbers appear on random positions ?

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


def check():
    global difficulty
    global entered_correctly
    global a

    content = int(e.get())
    if content == sequence[a]:
        label_result['text'] = "correct"
        entered_correctly = entered_correctly + 1
        if entered_correctly == difficulty:
            messagebox.showinfo("Congratulations", "YOU WIN")
            entered_correctly = 0
            difficulty = difficulty + 1
            create_sequence()
            show_sequence()

    else:
        messagebox.showinfo("You entered the wrong number", " YOU LOSE!")
        root.quit()
    a = a + 1

def get_me():
    global difficulty
    difficulty = simpledialog.askinteger("Choose the difficulty", "Enter a positive integer")
    if difficulty != 0:
        button.forget()
        pack_widgets()
        create_sequence()
def start():
    button.pack()
def pack_widgets():
    e.pack()
    btn_check.pack(fill=X, pady=10)
    label_result.pack()
    label_result.after(1000, show_sequence)
def create_sequence():
    for k in range(0, difficulty):
        sequence.append(randint(0, 20))
def show_sequence():
    label.pack()
    k = 1
    seconds = 1
    global counter
    while 1:
        if counter == difficulty:
            break
        label.after(1000*k, change_text)
        counter = counter + 1
        k = k+1
    counter = 0
def change_text():
    global i
    label["text"] = sequence[i]
    i = i+1

entered_correctly = 0
a = 0
i = 0
difficulty = 0
counter = 0
root = Tk()
root.title("Memory Game")
root.geometry("600x480")
button = Button(root, text="Start", command=get_me)
sequence = []
e = Entry(root)
btn_check = Button(root, fg="green", bg="white", command=check,  text="Check", bd=5)
label = Label(root, width=80, height=40, text='')
label_result = Label(root, width=20, height=5, text='', bg="brown", fg="blue")
start()
root.mainloop()

Solution

  • Instead of using a Label and trying to place text at random places inside it, I suggest you use a Text widget because it supports inserting text at random line and column positions.

    Here's a version of your code with the necessary modifications. I replaced the Label you named simply label with a Text widget named num_display. The primary changes were to the change_text() function.

    from tkinter import *
    from random import*
    from tkinter import simpledialog
    from tkinter import messagebox
    
    DSP_WIDTH, DSP_HEIGHT = 40, 15  # Dimensions of number display.
    
    
    def check():
        global difficulty
        global entered_correctly
        global a
    
        content = int(e.get())
        if content == sequence[a]:
            label_result['text'] = "correct"
            entered_correctly = entered_correctly + 1
            if entered_correctly == difficulty:
                messagebox.showinfo("Congratulations", "YOU WIN")
                entered_correctly = 0
                difficulty = difficulty + 1
                create_sequence()
                show_sequence()
    
        else:
            messagebox.showinfo("You entered the wrong number", " YOU LOSE!")
            root.quit()
        a = a + 1
    
    def get_me():
        global difficulty
        difficulty = simpledialog.askinteger("Choose the difficulty", "Enter a positive integer")
        if difficulty != 0:
            button.forget()
            pack_widgets()
            create_sequence()
    
    def start():
        button.pack()
    
    def pack_widgets():
        e.pack()
        btn_check.pack(fill=X, pady=10)
        label_result.pack()
        label_result.after(1000, show_sequence)
    
    def create_sequence():
        for k in range(0, difficulty):
            sequence.append(randint(0, 20))
    
    def show_sequence():
        num_display.pack()
        k = 1
        seconds = 1
        global counter
        while 1:
            if counter == difficulty:
                break
            num_display.after(1000*k, change_text)
            counter = counter + 1
            k = k+1
        counter = 0
        num_display.after(1000*k, clear)  # Erase last number displayed.
    
    def clear():
        """ Clear by deleting current contents and filling with blank lines. """
        num_display.delete('1.0', END)
        for k in range(DSP_HEIGHT):
            num_display.insert(f'{k}.0', ' '*(DSP_WIDTH-2) + '\n')
    
    def change_text():
        global i
    
        # Display next number at random position on number display.
        line = randint(0, DSP_HEIGHT-2) + 1
        column = randint(0, DSP_WIDTH-2)
        posn = f'{line}.{column}'
        clear()
        num_display.insert(posn, sequence[i])
        i = i+1
    
    entered_correctly = 0
    a = 0
    i = 0
    difficulty = 0
    counter = 0
    root = Tk()
    root.title("Memory Game")
    root.geometry("600x480")
    button = Button(root, text="Start", command=get_me)
    sequence = []
    e = Entry(root)
    btn_check = Button(root, fg="green", bg="white", command=check,  text="Check", bd=5)
    #label = Label(root, width=80, height=40, text='')
    num_display = Text(root, width=DSP_WIDTH, height=DSP_HEIGHT)
    label_result = Label(root, width=20, height=5, text='', bg="brown", fg="blue")
    start()
    root.mainloop()
    

    Here's a screenshot of it running and displaying one of the numbers in a random position:

    screenshot