Search code examples
pythontkinterframestkinter-layout

splitting windows using frames in tkinter and python


I am trying to learn tkinter and how to organise a GUI using grids and frames. I have created to simple scrollbar list boxes but would like to place them both in one frame to the right side of the screen so the left hand side can be used for another frame. Could anybody help me with guidance of how to split the display into 2 frames please?

from tkinter import *
from tkinter import ttk

my_window = Tk()
# frame_name = Frame(my_window)

my_list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11',
           '12', '13', '14', '15', '16', '17', '18', '19', '20']
my_list2 = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11',
            '12', '13', '14', '15', '16', '17', '18', '19', '20']


listbox_object = Listbox(my_window)
listbox_object2 = Listbox(my_window)
# listbox.pack()
listbox_object.grid(row=0, column=1)
listbox_object2.grid(row=0, column=3)

scrollbar_object = Scrollbar(my_window)
scrollbar_object2 = Scrollbar(my_window)
# scrollbar.pack(side=RIGHT, fill=Y)
scrollbar_object.grid(row=0, column=2, sticky='ns')
scrollbar_object2.grid(row=0, column=4, sticky='ns')

for item in my_list:
    listbox_object.insert(END, item)

for item in my_list2:
    listbox_object2.insert(END, item)

# attach listbox to scrollbar
listbox_object.config(yscrollcommand=scrollbar_object.set)
listbox_object2.config(yscrollcommand=scrollbar_object2.set)
scrollbar_object.config(command=listbox_object.yview)
scrollbar_object2.config(command=listbox_object2.yview)
mainloop()

Solution

  • It is not very clear what you want to do with the frame. However, I can tell you that the elements in a GUI are hierarchical. So if you want to separate into two frames, you can do:

    main_frame = Frame(my_window)
    main_frame.grid(row=0, column=0, sticky="nswe")
    
    left_frame = Frame(main_frame)
    left_frame.grid(row=0, column=0, sticky="nswe")
    
    # Button added just to see that there is a left frame, otherwise it will shrink
    button_object = Button(left_frame, text="My Button")
    button_object.grid(row=0, column=0)
    
    right_frame = Frame(main_frame)
    right_frame.grid(row=0, column=1, sticky="nswe")
    
    listbox_object = Listbox(right_frame)
    listbox_object2 = Listbox(right_frame)
    listbox_object.grid(row=0, column=0)
    listbox_object2.grid(row=0, column=2)
    
    scrollbar_object = Scrollbar(right_frame)
    scrollbar_object2 = Scrollbar(right_frame)
    scrollbar_object.grid(row=0, column=1, sticky='ns')
    scrollbar_object2.grid(row=0, column=3, sticky='ns')
    

    Note that I added a global main_frame to encapsulate everything, as it is better practice than working directly with the Tk root.

    Finally, if you want to design more closely your interface, you will need to use columnconfigure and rowconfigure to control how your interface split the unused space, e.g.

    main_frame.columnconfigure(0, weight=3)
    main_frame.columnconfigure(1, weight=1)
    

    to tell your interface that 3/4 of the remaining horizontal space is attributed to left_frame (column 0 of main_frame) and 1/4 to right_frame (column 1 of main_frame)

    Many things are not very intuitive in general with GUI design. In your case, I suggest to use the bg parameter while debugging:

    main_frame = Frame(my_window, bg="BLUE")
    left_frame = Frame(main_frame, bg="RED")
    right_frame = Frame(main_frame, bg="GREEN")
    

    so that you see clearly how your program split the space when you resize the window.