Search code examples
tkinterpython-3.5tkinter-entrytkinter-layout

setting inner modules in frame using tkinter


Here's my code and what exactly I'm trying to do is setting the URL label in mid of frame and the entry text next to it, and adding 3 buttons below the URL and entry text field.

  import tkinter as tk
  from tkinter import *
  root = tk.Tk()


root.geometry("520x400")

frame1 = tk.LabelFrame(root, text="my_first_window", width=400,  height=200, bd=5)
Label(root, text="URL:").grid(row=0, column=1 ,sticky=W)

e1 = Entry(root)
e1.grid(row=0, column=2)
frame1.grid(row=0, column=0, columnspan=7, padx=8)

Button(root, text='BACK', command=lambda:print('BACK')).grid(row=8, column=1, sticky=W, pady=4)
Button(root, text='NEXT', command=lambda:print('NEXT')).grid(row=8, column=2, sticky=W, pady=4)
Button(root, text='CANCLE', command=lambda:print('CANCLE')).grid(row=8, column=3, sticky=W, pady=4)


mainloop()

Solution

  • If you insist on using the .grid() method then you can add the below to your code:

    for column in range(10):
        Grid.columnconfigure(root, column, weight=1)
    
    for row in range(10):
        Grid.rowconfigure(root, row, weight=1)
    

    This will mean that the column's and row's of the grid will have the space available in the window given to them evenly. Using this in conjunction with the sticky attribute of .grid() will let you achieve the result you are looking for.


    However, subjectively speaking it may be easier for you to switch over to the .pack() method, which (at least in my own opinion) allows for much easier configuration and management of tkinter GUIs.

    You could do something like the below:

    from tkinter import *
    
    root = Tk()
    
    root.geometry("520x400")
    
    frame1 = LabelFrame(root, text="my_first_window", width=400,  height=200, bd=5)
    Label(frame1, text="URL:").pack(side="left", fill="x")
    
    e1 = Entry(frame1)
    e1.pack(side="left", fill="x", expand=True)
    frame1.pack(fill="both", expand=True)
    
    Button(root, text='BACK', command=lambda:print('BACK')).pack(fill="both", expand=True, side="left", padx=5, pady=5)
    Button(root, text='NEXT', command=lambda:print('NEXT')).pack(fill="both", expand=True, side="left", padx=5, pady=5)
    Button(root, text='CANCLE', command=lambda:print('CANCLE')).pack(fill="both", expand=True, side="left", padx=5, pady=5)
    
    root.mainloop()
    

    The above makes use of a lot of different new ideas that have been asked and answered too many times here on Stack Overflow so I'm going to link you to this fantastic answer from Bryan Oakley.