1
votes

Good Day. Learning tkinter, using Python 3.5. To begin I got some success using pack() for frames in root() then used grid() inside the packed frames. Then I decided to use grid to place Frames in root and grid inside these frames. Basically get some info from user - do something with info - some trigger to reset the frames - start over. During the process of destroy() in pack() it appears that Frames are appended to root, and in grid() it appears they are inserted. Is this correct? The difference in the code examples is in pack() example I use:

On another note - I have also run into the problem of the entries being of type('<class 'tkinter.Entry Object'>) instead of tkinter.Entry -- I was not able to reproduce this today. is there a way to read such a value as get() did not work?

Thanks

i = root.slaves()
for child in i[1].winfo_children():

However in the grid() example I needed to use:

i = root.grid_slaves()
for child in i[0].winfo_children():

Min working example using pack():

def new():
    showEntries()
    D_setup()
    all_entries['D'] = D

def D_setup():
    dx = len(D)
    # D Label
    labD = Label(frame_for_D, text='Place to Enter Value')
    labD.grid(row = dx * 2, column = 0)
    # D Entry
    entD = Entry(frame_for_D, width=50)
    entD.grid(row = dx * 2 + 1, column=0)
    entD.delete(0,END)
    entD.insert(END, s[dx])
    # Append the last Entry
    D.append(entD)
    return

def showEntries():

    if len(D) == 0:
        return



    for number, ent in all_entries.items():
        if str(type(ent)) == "<class 'tkinter.Entry'>":
            print(type(ent))
            print (number, ent.get())
        elif str(type(ent)) == "<class 'list'>":
            print (number, [x.get() for x in ent])
    if len(D) > 5:
        i = root.slaves()
        for child in i[1].winfo_children():
            child.destroy()
        D.clear()
        all_entries.clear()
        D.clear()
        print(all_entries)
        print(D)
        raise SystemExit
    return


#------------------------------------

all_entries = {}
D = []
root = Tk()
root.configure(background = 'green')
# -- Define all frames
frame_for_buttons = Frame(root,background='black')
frame_for_D = Frame(root,background='red')
# -- pack all frames
frame_for_buttons.pack()
frame_for_D.pack()
# -- root
newTButton = Button(frame_for_buttons, text='New\n\n' +
                                             'Enter',
                    activebackground='red',
                    activeforeground='black',
                    borderwidth=10, foreground='black',
                    background='yellow',
                    highlightthickness=20,padx=5,pady=5,
                    command=new)
newTButton.grid(row=0, column=0)

root.mainloop()  

example using grid():

def new():

    showEntries()
    D_setup()
    all_entries['D'] = D

def D_setup():
    dx = len(D)
    # D Label
    labD = Label(frame_for_D, text='Place to Enter Value')
    labD.grid(row = dx * 2, column = dx)
    # D Entry
    entD = Entry(frame_for_D, width=50)
    entD.grid(row = dx * 2 + 1, column=dx)
    entD.delete(0,END)
    entD.insert(END, s[dx])
    # Append the Entry
    D.append(entD)
    return

def showEntries():

    if len(D) == 0:
        return

    for number, ent in all_entries.items():
        if str(type(ent)) == "<class 'tkinter.Entry'>":
            print(type(ent))
            print (number, ent.get())
        elif str(type(ent)) == "<class 'list'>":
            print([type(x) for x in ent])
            print (number, [x.get() for x in ent])
    if len(D) > 5:
        #i = frame_for_D.grid_slaves()      .winfo_children()
        i = root.grid_slaves()
        for child in i[0].winfo_children():
            child.destroy()
        D.clear()
        all_entries.clear()
        D.clear()
        print(all_entries)
        print(D)
        raise SystemExit
    return


#------------------------------------

all_entries = {}
D = []
root = Tk()
root.configure(background = 'green')
# -- Define all frames
frame_for_buttons = Frame(root,background='black')
frame_for_D = Frame(root,background='red')
# -- Grid all frames
frame_for_buttons.grid(row = 0, column = 0)
frame_for_D.grid(row = 1, column = 0, pady = 10, padx = 10)
# root
newTButton = Button(frame_for_buttons, text='New\n\n' +
                                             'Enter',
                    activebackground='red',
                    activeforeground='black',
                    borderwidth=10, foreground='black',
                    background='yellow',
                    highlightthickness=20,padx=5,pady=5,
                    command=new)
newTButton.grid(row=0, column=0)

root.mainloop()
1

1 Answers

2
votes

During the process of destroy() in pack() it appears that Frames are appended to root, and in grid() it appears they are inserted.

Not exactly. In both cases they are added to the frame according to their options. In the case of pack, the default placement option (eg: side) is to place the widget at the top of the available space in the parent/master.

In the case of grid the default is to use the first unoccupied row after all other widgets in the same parent/master. If not specified, the column number will be zero.

Best practices dictate that you should always specify at least the side option with pack, and the row and column option with grid so that there is never any confusion about where the widget is intended to be placed.

I have also run into the problem of the entries being of type(') instead of tkinter.Entry

That question doesn't make any sense. The objects created by Entry will always be of type <class 'tkinter.Entry'>, and the method get will always work when used on an object of that type.