0
votes

First time with TkInter. According to what I've read, you can use Frame widgets to hold other widgets. So, I laid down some preview Frames as such:

import tkinter as tk


root = tk.Tk()

TextFrame = tk.Frame(root, width=200, height=600, bg="red")
TextFrame.pack(side="left")

ListFrame = tk.Frame(root, width=800, height=600, bg="blue")
ListFrame.pack(side="right")

However, when I add a widget and tell it to fill the Frame, it simply replaces the frame instead of expanding to fill the area. Test code used:

ListBox = tk.Listbox(ListFrame, selectmode="single", bg="#545454", fg="#d9d9d9")
for X in range(20):
    ListBox.insert('end', X)
ListBox.pack(fill='both', expand=True)

The same test code expands properly if I set the parent to the main 'root' object. Example:

import tkinter as tk


root = tk.Tk()
root.geometry("1000x600")

ListBox = tk.Listbox(root, selectmode="single", bg="#545454", fg="#d9d9d9")
for X in range(20):
    ListBox.insert('end', X)
ListBox.pack(side="right", fill='both', expand=True)

TextBox = tk.Message(root, text="A bunch of text", width=100)
TextBox.pack(side="left", fill="y")

Am I doing something wrong, here?

2
Is there a reason why you aren't having your frame fill the window? It's shrinking to fit the listbox because you're not requesting that it fill the window it has been put in. - Bryan Oakley

2 Answers

0
votes

Frames are like elastics, they grip their content. You could add:

ListFrame.pack_propagate(False)

to switch off that behavior

0
votes

It's impossible to say what the right answer is since your question doesn't explain exactly the look and behavior that you're wanting to achieve.

By default, widgets shrink or expand to fit their contents. 99.9% of the time this is exactly the right thing, and lets to UIs that are very responsive to the change (different fonts, different resolutions, different window sizes, etc.). In your case, the listbox doesn't replace the frame. Instead, the frame is simply shrinking to fit the listbox.

It is doing this because you didn't tell it to do anything different. When you placed the frame in the root window, you didn't tell tkinter that you wanted the frame to fill the window. You've just sort-of left it to float at the top, which gives it the freedom to grow or shrink to fit its contents.

By giving proper attributes to TextFrame.pack(side="left") you can have that frame fill the window, and therefore prevent it from shrinking to fit its children.

TextFrame.pack(side="left". fill="both", expand=True)

Of course, that assumes you want the frame (and thus, the text widget it contains) to fill the window. If you are putting other windows around it, that may change which options you want to use.