Search code examples
pythontkinterttkwidgets

tkinter notebook widget frame limitation


I was trying to set two different frame in one tab, but as I read somewhere on the internet it is not possible with notebook widget.

I have problem with placing buttons - for example 8 buttons below 10 buttons. the buttons below are smaller and having empty space between each button above on x axis.... I don't want to span them.. I want them in same size and stick them together in the middle. I used grid..

I wanted to use different frame to do that, then each line of buttons are separated from the other... but it's not possible with the notebook widget, Am I right? And I think using .place( x=, y= )it's annoying and take time...

Any suggestions please to simply do that ?

import tkinter
import tkinter.ttk

window = tkinter.Tk()

nb = tkinter.ttk.Notebook(window)  
nb.grid(row=0, column=0, columnspan=10, rowspan=10)

frame = tkinter.Frame(nb)
frame.grid(row=0, column=0)

nb.add(frame, text = "Tab1")

button1 = tkinter.Button(frame, text="button1")
button2 = tkinter.Button(frame, text="button2")
button3 = tkinter.Button(frame, text="button3")

button4 = tkinter.Button(frame, text="button4")
button5 = tkinter.Button(frame, text="button5")
button6 = tkinter.Button(frame, text="button6")
button7 = tkinter.Button(frame, text="button7")
button8 = tkinter.Button(frame, text="button8")

button1.grid(row=0, column=0)
button2.grid(row=0, column=1)
button3.grid(row=0, column=2)
button4.grid(row=1, column=0)
button5.grid(row=1, column=1)
button6.grid(row=1, column=2)
button7.grid(row=1, column=3)
button8.grid(row=1, column=4)

window.mainloop()

In this example the buttons size are the same but in my code the buttons at rows=1 are different size because I'm attaching them to a png photo..


Solution

  • Sure it is possible to place multiple frames in Notebook. You'll have to make them a child object of the initial frame:

    frame = tkinter.Frame(nb)
    nb.add(frame, text = "Tab1")
    
    frame1 = tkinter.Frame(frame)
    frame1.pack(fill="both", expand="True")
    frame2 = tkinter.Frame(frame)
    frame2.pack(fill="both", expand="True")
    

    Then you can place the buttons inside the child frames:

    button1 = tkinter.Button(frame1, text="button1")
    button2 = tkinter.Button(frame1, text="button2")
    button3 = tkinter.Button(frame1, text="button3")
    
    button4 = tkinter.Button(frame2, text="button4")
    button5 = tkinter.Button(frame2, text="button5")
    button6 = tkinter.Button(frame2, text="button6")
    button7 = tkinter.Button(frame2, text="button7")
    button8 = tkinter.Button(frame2, text="button8")
    

    Finally you'll have to fiddle around to place the buttons within their own child frame as you want them to have:

    button1.grid(row=0, column=0)
    button2.grid(row=0, column=1)
    button3.grid(row=0, column=2)
    button4.grid(row=1, column=0)
    button5.grid(row=1, column=1)
    button6.grid(row=1, column=2)
    button7.grid(row=1, column=3)
    button8.grid(row=1, column=4)
    

    This, for example, centers the buttons. Within the child frames, you could also try to use another geometry manager if it seems to fit your needs better.