Skip to content
Advertisement

layout buttons within frame nested in tkk.Notebook

I can’t properly layout buttons within frame nested in tkk.Notebook

In Main.py I create ttk.Notebook and attach mainTab instance

root = tk.Tk()
rootFrame = tk.Frame(root, width=600, height=300)
rootFrame.grid(columnspan=1, rowspan=2)
rootFrame.pack(expand=1, fill="both")

tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, columnspan=1, rowspan=1)
mainTab     = ttk.Frame(tabs)
mainTab.grid(columnspan=3, rowspan=6)

tabs.add(mainTab, text="Main")
rootFrame.pack(expand=1, fill="both")
mainPane = MainTab(root,mainTab)
root.mainloop()
  • in mainTab.py I’m trying to insert buttonFrame and layout two buttons within it
class MainTab:
    ...
    def __init__(self, root, mainTab) -> None:
        self.root = root
        buttonFrame = tk.Frame(mainTab, bg="white")
        buttonFrame.grid(column=0, row=4, columnspan=3, rowspan=1)
        self.start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font=BUTTON_FONT, bg="green", fg="white") # , height=1, width=14
        self.start_btn.grid(column=0, row=0, columnspan=2)
        self.reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font=BUTTON_FONT, bg="green", fg="white") # , height=1, width=1
        self.reset_btn.grid(column=2, row=0)
        ...

As a result start button is not properly placed in the grid

enter image description here

It looks like buttonFrame takes full parent frame width and buttons placed in the middle regardless of their grid settings. How I can properly layout buttons within buttonFrame?

Here is the requested “minimal reproducible example” which also look not good

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Time Tracker")
root.iconbitmap('./assets/logoTransp4icon24.ico')
rootFrame = tk.Frame(root, width=600, height=300)
rootFrame.grid(columnspan=1, rowspan=2)
rootFrame.pack(expand=1, fill="both")

tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, columnspan=1, rowspan=1)

mainTab     = ttk.Frame(tabs)
mainTab.grid(columnspan=3, rowspan=6)

buttonFrame = tk.Frame(mainTab, bg="white")
buttonFrame.grid(column=0, row=4, columnspan=3, rowspan=1)
start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font="Arial", bg="green", fg="white") # , height=1, width=14
start_btn.grid(column=0, row=0, columnspan=2)
reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font="Arial", bg="green", fg="white") # , height=1, width=1
reset_btn.grid(column=2, row=0)

timerDisplay = tk.Label(mainTab, text="00:00:00", font="Arial")
timerDisplay.grid(columnspan=2, column=1, row=4)
tabs.add(mainTab, text="Main")
rootFrame.pack(expand=1, fill="both")
root.mainloop()

Advertisement

Answer

buttonFrame occupies column 0 to 2 and timerDisplay occupies column 1 to 2. So timerDisplay overlaps buttonFrame. Removing columnspan=3 in buttonFrame.grid(...) can fix the overlapping issue:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("Time Tracker")
root.iconbitmap('./assets/logoTransp4icon24.ico')
rootFrame = tk.Frame(root, width=600, height=300)
#rootFrame.grid(columnspan=1, rowspan=2) # override by below line
rootFrame.pack(expand=1, fill="both")

tabs = ttk.Notebook(rootFrame)
tabs.grid(column=0, row=1, rowspan=1)

mainTab     = ttk.Frame(tabs)
#mainTab.grid(columnspan=3, rowspan=6) # not necessary

buttonFrame = tk.Frame(mainTab, bg="white")
buttonFrame.grid(column=0, row=4, rowspan=1)  # removed columnspan=3
start_btn = tk.Button(buttonFrame, text="Start", command=lambda:self.start_timer(), font="Arial", bg="green", fg="white") # , height=1, width=14
start_btn.grid(column=0, row=0, columnspan=2)
reset_btn = tk.Button(buttonFrame, text="X", command=lambda:self.reset_timer(), font="Arial", bg="green", fg="white") # , height=1, width=1
reset_btn.grid(column=2, row=0)

timerDisplay = tk.Label(mainTab, text="00:00:00", font="Arial")
timerDisplay.grid(columnspan=2, column=1, row=4)
tabs.add(mainTab, text="Main")
#rootFrame.pack(expand=1, fill="both") # already called above
root.mainloop()
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement