Search code examples
pythontkinterwidgetresizeframe

Is There a Way to Always have a Place Widget Relative to Another Widget(Such as Pack)


So, I'm using the place method to have a widget overlap other widgets, but its position is relative (with winfo) to a widget that uses pack. When the parent frame is resized, the pack position will change, but the place position will not. This is my code:

from tkinter import *
root = Tk()
root.geometry("200x300")

search = Entry(root)
search.pack()

search.update()
x = search.winfo_x()
y = search.winfo_y()
width = search.winfo_width()
height = search.winfo_height()

frame = LabelFrame(root, width=width, height=200)
frame.place(x=x, y=y+height)

root.mainloop()

The LabelFrame stays in its x and y position when the window is resized. The Entry widget will be used as a search bar and I want autocompletion under it. There will be widgets under the entry widget and the autocompletion will only appear when you are typing (That's not what I'm looking for though. Its just more exposition if you need it). So, is there a way to have the place widget always be relative to the pack widget. If you have any answers, thank you:)


Solution

  • If your goal is to put one widget relative to another, place lets you do that. It's great for things like tooltips or other transient widgets that don't otherwise fit into a normal layout.

    The easiest way to do that is to make the widget a child of the controlling widget. For example, for your frame to be placed relative to the search box you can make it a child of the search box. If it's inconvenient to do that, you can use the in_ parameter to tell place which widget is the other widget.

    For example, to place your labelframe immediately below the search box and with the same width as the search box you might do it something like this:

    frame.place(
        in_=search,
        bordermode="outside",
        anchor="nw",
        relx=0,
        rely=1.0,
        y=5,
        relwidth=1.0
    )
    

    This is what the options mean:

    • in_=search: place the frame relative to the search box
    • bordermode="outside": relative measurements are from the outside of the border (default is "inside")
    • anchor="nw": place the widget so that the northwest corner of the frame is at the computed coordinate
    • relx=0: place the anchor point 0% from the left edge of the search box
    • rely=1.0: place the frame at 100% of the height of the search box
    • y=5: add 5 pixels to the computed position so it floats just a little below the window
    • relwidth=1.0: make the width of the frame 100% the width of the search box.

    Obviously you don't have to use y=5, I just added it to illustrate the additive behavior of using rely and y.