aran aran - 23 days ago 7
Python Question

python - How to use tkinter.place()

I want to have an entry and I want to have a listbox of fixed size under it which is fixed. and I want to have another listbox of dynamic height. That will appear and disappear in time and also change in size. I want the second listbox (which is actually a dropdown) to be shown over the other listbox which I want it to be fixed. My code for changing the size etc is correct and works perfectly with pack() but then it will move the other listbox up and down as it's size changes. And when I change pack() to place(...) it's not shown at all anymore.

Here is my code:

from tkinter import *
root = Tk()
entry = Entry(
root,
width=50
)
frame = Frame(
root,
height=10,
width=50,
background="#caeaa9"
)
dropdown = Listbox(
frame,
background="#11FF11",
height=5,
width=50
)
listbox = Listbox(
frame,
background="#FF1111",
height=10,
width=50
)
entry.pack()
listbox.pack()
dropdown.place()
frame.pack()
mainloop()


But the dropdown does not appear when I run it. What am I missing?

By the way, I want the top border of the dropdown to be exactly on the top border of the listbox and both of them right under the entry.

Answer Source

I highly recommend you don't use the place geometry manager. Ever. If you want to create larger or more complex interfaces, having to place widgets is terrible. I suggest using grid instead:

import tkinter as tk
# Avoid wildcard imports!

root = tk.Tk()

entry = tk.Entry(
    root,
    width=50
)

frame = tk.Frame(
    root,
    background="#caeaa9"
)

listbox = tk.Listbox(
    frame,
    background="#FF1111",
    height=10,
    width=50
)

dropdown = tk.Listbox(
    frame,
    background="#11FF11",
    height=5,
    width=50
)

entry.pack()
listbox.grid(column=0, row=0, sticky=N)
dropdown.grid(column=0, row=0, sticky=N)
frame.pack()

root.mainloop()