pythontkinterframes

Why isn't my frame showing in a tkinter window?


I am coding a gui in python called eTasks. I need to have three frames to show different task folders on the home screen. However my frames aren't showing. I've tried pack_propagate method and changing the background colour of the frame but that didn't work. Here is my code:

import tkinter as tk 
from tkinter import ttk
from tkinter import*
from time import strftime
from datetime import date
import tkinter as tk
todohome=tk.Tk()
todohome.geometry('500x500+100+100')
todohome.attributes('-fullscreen', True)
todohome.overrideredirect(True)
todohome.configure(bg='white')
ctrlfrme=tk.Frame(todohome, relief='groove', highlightbackground='black', highlightthickness=1)
ctrlfrme.pack(anchor='n', side=tk.TOP, fill=X)
Clsewindowbutton=ttk.Button(ctrlfrme, text='X',     
command=todohome.destroy, width=10)
Clsewindowbutton.pack(side=tk.LEFT, anchor=tk.NE)
    
def minimise():
    todohome.overrideredirect(False)
    todohome.state(newstate='iconic')
        
MinButton=ttk.Button(ctrlfrme, text='-', width=10, command=minimise)
MinButton.pack(side=tk.RIGHT, anchor=tk.SW)

quickbar=tk.Frame(todohome, relief="groove", highlightbackground="black"
                  ,highlightthickness=1)
quickbar.grid_columnconfigure(5, weight=0)
quickbar.pack(anchor='n', side=tk.TOP, pady=5)

Welcome=Label(quickbar, font=('calibri', 20), text="Welcome to eTasks")
Welcome.pack(side=LEFT, anchor="w")

def time():
    ctime=strftime('Time: %H:%M:%S')
    clock.config(text=ctime)
    clock.after(1000, time)

clock=Label(quickbar, font=('calibri', 20),
          foreground='black')
clock.pack(anchor='n', side=tk.RIGHT, padx=0)

def getdate():
    today = date.today()
    cdate = today.strftime("%d/%m/%Y")
    datecal=Label(quickbar, font=('calibri', 20), foreground='black', text=cdate)
    datecal.pack(anchor='n', side=tk.LEFT, padx=100)

taskframe=tk.Frame(todohome, relief="groove", highlightbackground="black"
                  ,highlightthickness=1, bg='red')
taskframe.pack_propagate(False)
taskframe.pack(fill=BOTH)

getdate()
time()
todohome.mainloop()

Solution

  • The problem is that you haven't given taskframe a size, so it defaults to a single pixel wide and tall. You then add it to pack without specifying a side or that it should expand to fill any remaining unused space.

    When you call taskframe.pack(fill=BOTH), the packer will align the widget to the top of the remaining unused space by default. Since the packer allocates an entire side, it the full width of the widget, but only allocates one pixel for the frame height that's the requested size of the frame.

    When you specify fill=BOTH, the packer will expand the frame to fill in both the x and y direction in the allocated space. In the x direction it's allocated the full width by virtue of being packed to the top, but in the y direction it has been allocated only 1 pixel. This results in a frame that is a single pixel tall, but the full width of the window.

    The solution is probably* to add expand=True when calling pack. That will instruct the packer to expand the allocated space to not just fit the frame, but to also include all remaining unused space in the window.

    taskframe.pack(fill=BOTH, expand=True)
    

    * I say probably because I don't know for certain what you're trying to accomplish. Usually when using pack, one widget will be packed with both the expand and fill options if you expect that widget to expand and fill the remaining space. Though, it's also not unusual to have expand set to True for more than one widget.