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
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()