Search code examples
pythontkintergridpack

tkinter: how to use pack layout


I am new to Python and am having trouble using the pack layout. I have 40 letters and I want to make 4 rows each containing 10 letters.

Here is my code:

import random
from tkinter import *    

root = Tk()

w = Label(root, text="GAME")
w.pack(side=TOP)

# there are 40 tiles
tiles_letter = ['a', 'b', 'c', 'c', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'f', 'g', 'g', 'h', 'i', 'j', 'k', 'k', 'a', 'b', 'c', 'c', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'f', 'g', 'g', 'h', 'i', 'j', 'k', 'k']

tiles_make_word = []

def add_letter():
    if not tiles_letter:
        return
    rand = random.choice(tiles_letter)
    tiles_make_word.append(rand)
    print(len(tiles_make_word))
    tile_frame_column = Label(root, text=rand, bg="red", fg="white")
    tile_frame_column.pack(side=LEFT, padx=5, pady=10)
    tiles_letter.remove(rand)  # remove that tile from list of tiles
    if len(tiles_make_word) % 10 == 0:
        separator = Frame(height=100)
        separator.pack(fill=X, padx=5, pady=5)
    root.after(500, add_letter)

root.after(500, add_letter)

root.mainloop()

Problem is after every 10 letters it creates a new row but it isn't layed out correctly. It looks more like a zig zag or in a diagonal, instead of being directly underneath the above row. Can someone please tell me what is wrong with the code and how I can fix it? I got confused trying to create new rows with the "after" method. Maybe the mistake has something to do with that. Hopefully it's something simple. I've been stuck on this for hours.

Thanks


Solution

  • Try this.

    the problem is your creating many widget and packing it to root instead we can create a frameContainer which contains frames. so we add the label to new frame.

    import random
    from Tkinter import *
    
    root = Tk()
    
    w = Label(root, text="GAME")
    w.pack(side=TOP)
    frameContainer=[]
    frameContainer.append(Frame(root,height=100))
    frameContainer[-1].pack()
    # there are 40 tiles
    tiles_letter = ['a', 'b', 'c', 'c', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'f', 'g', 'g', 'h', 'i', 'j', 'k', 'k', 'a', 'b', 'c', 'c', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'f', 'g', 'g', 'h', 'i', 'j', 'k', 'k']
    
    tiles_make_word = []
    
    def add_letter():
        global frameContainer
        if not tiles_letter:
            return
        rand = random.choice(tiles_letter)
        tiles_make_word.append(rand)
        print(len(tiles_make_word))
        tile_frame_column = Label(frameContainer[-1], text=rand, bg="red", fg="white")
        tile_frame_column.pack(side=LEFT, padx=5, pady=10)
        tiles_letter.remove(rand)  # remove that tile from list of tiles
        print len(tiles_make_word),'***********'
        if len(tiles_make_word) % 10 == 0:
            frameContainer.append(Frame(root,height=100))
            frameContainer[-1].pack()
        root.after(500, add_letter)
    
    root.after(500, add_letter)
    
    root.mainloop()