python Tkinter grid method not working as should be for some reason

Question:

i am trying to get my listbox to move to the bottom of the gui but no matter how high of a row value i give it it wont budge. you can see my listbox in the Creat_Gui method in my code. im not sure why this is happpening it cant be the button because the button is in row 1 so im not sure whats causing this.

i tried using sticky=’s’ that didnt work i tried changing the rows multiple times didnt work. i tried using the root.rowconfigure(100,weight=1) this worked kind of but messes with thte grid which is annoying

import tkinter as tk

class Manager:
    def __init__(self):
        self.root=tk.Tk()

        self.root.title('password_manager')
        self.root.geometry('500x600')

        self.create_GUI()
        self.storage = {}
        self.root.mainloop()


    def create(self):
        pass

    def open_page(self):
        print('openpage')
    def add_new_button(self):
        pass
    def add_new(self):
        self.app_title=tk.Label(text='test')
        self.app_title.grid(row=2,column=50)
        self.application_name=tk.Entry(self.root,width=20,font=('arial',18))
        self.username=tk.Entry(self.root,width=20,font=('arial',18))
        self.password=tk.Entry(self.root,width=20,font=('arial',18))
        self.application_name.grid(row=2, column=1)
        self.username.grid(row=3, column=2)
        self.password.grid(row=4, column=3)

        self.app_name_label = tk.Label(self.root, text='Application Name:')
        self.username_label = tk.Label(self.root, text='Username:')
        self.password_label = tk.Label(self.root, text='Password:')

        self.app_name_label.grid(row=2, column=0)
        self.username_label.grid(row=3, column=1)
        self.password_label.grid(row=4, column=2)

        self.password.bind('<Return>',self.hide)
    def hide(self,thing):
        #store user info to pass onto dictionary and hide textboxes
        username=self.username.get()
        password=self.password.get()
        app_name=self.application_name.get()
        self.application_name.grid_forget()
        self.username.grid_forget()
        self.password.grid_forget()
        self.add_to_memory(username,password,app_name)

    def add_to_memory(self,username,password,app_name):
        #store username password and application name in dictionary
        if app_name in self.storage.keys():
            return
        else:
            self.storage[app_name]=(username,password)
        print(self.storage)
    def create_GUI(self):
        #create initial interface
        #self.root.columnconfigure(100, weight=1)
        #self.root.rowconfigure(100, weight=1)
        self.listbox=tk.Listbox(self.root,width=100)

        self.listbox.grid(row=200,column=0)
        self.button=tk.Button(self.root,text='add new',font=('arial',18),command=self.add_new)
        self.button.grid(row=1,column=0)


Manager()
Asked By: cade232

||

Answers:

If you want to use grid, and you want a widget to be at the bottom of it’s parent, you need to designate some row above that widget to take all of the extra space, forcing the widget to the bottom. Here’s one example:

def create_GUI(self):
    self.listbox=tk.Listbox(self.root,width=100)
    self.expando_frame = tk.Frame(self.root)
    self.button=tk.Button(self.root,text='add new',font=('arial',18),command=self.add_new)

    self.root.grid_rowconfigure(2, weight=1)
    self.button.grid(row=1,column=0)
    self.expando_frame.grid(row=2, sticky="nsew")
    self.listbox.grid(row=3,column=0)

With that, the listbox will be at the bottom, with extra space above it. If you want to add more widgets, you can add them to self.expando_frame rather than self.root and they will appear above the listbox.

Using frames in this way is a valuable technique. You could, for example, use three frames in root: one for the top row of buttons, one for the listbox on the bottom, and one for everything in the middle. You could then use pack on these frames and save a line of code (by virtue of not having to configure the rows). You can then use grid for widgets inside the middle frame.

Answered By: Bryan Oakley