I have this text box on the bottom of my app, and I need it to stay there no matter what (much like a sticky positioning in css). But as I resize the window, the textbox kinda gets hidden by the Frame on top(that consists of another textbox and a scrollbar)

top=Frame(self.root)
top.pack(side=TOP, fill=BOTH, expand=True)
text1=Text(top)
text1.pack(side=LEFT, fill=BOTH, expand=True)
scroll=Scrollbar(top)
scroll.pack(side=RIGHT, fill=Y)
scroll.config(command=text1.yview)
text1.config(yscrollcommand=scroll.set)
text1.config(state="disabled")
text2=Text(self.root, height=1)
text2.pack(side=BOTTOM, fill=BOTH, expand=False)
self.root.mainloop()

1 Answers

2
Bryan Oakley On Best Solutions

When you resize a window to make it smaller than the preferred size, tkinter has no choice but to start reducing the size of the interior widgets. Since you're using pack, pack will will start by reducing the size of the widget that was packed last. Once it disappears it will pick the next-to-last widget, and so on.

In your case, the bottom text widget is packed last, so it is the first one to be reduced. In your case you want the top text widget to be the one that grows and shrinks, so it should be the one you pack last.

Personally, I find the code much easier to read if you group widgets together that have the same parent or master, and separate layout commands from widget creation commands. It makes it much easier to visualize the relationships between widgets. In your case I would rewrite the code to look like the following.

Notice that I create all of the widgets that are directly in root first, and then all the widgets that are inside top second, and that I grouped the creation of the widgets together, and then grouped the layout of the widgets together. Also pay attention to the order that top and text2 are packed.

    top=Frame(self.root)
    text2=Text(self.root, height=1, background="pink")

    text2.pack(side=BOTTOM, fill=BOTH, expand=False)
    top.pack(side=TOP, fill=BOTH, expand=True)

    text1=Text(top)
    scroll=Scrollbar(top)
    text1.config(yscrollcommand=scroll.set)
    text1.config(state="disabled")
    scroll.config(command=text1.yview)

    text1.pack(side=LEFT, fill=BOTH, expand=True)
    scroll.pack(side=RIGHT, fill=Y)

Note:

The order in which the widgets are managed is called the packing list. The normal way to change the packing list is to pack items in a different order, as in the above example. You can, however, explicitly request that items be placed in a different order. For example, you could continue to pack the top widget first, but when you pack the text2 you can use before=top to tell pack that you want the bottom text widget to be before the top widget in the packing list.

    top.pack(side=TOP, fill=BOTH, expand=True)
    text2.pack(side=BOTTOM, fill=BOTH, expand=False, before=top)