在过去的几年里,我一直在使用一个功能齐全的组合框小部件,它是通过将其他 Tkinter 小部件拼接在一起而制作的。 (因为我比 ttk.Combobox 更喜欢它。)对于下拉列表,我总是使用 Toplevel 小部件,因为它与其他小部件重叠,而不是将它们推到一边。我从来没有能够让位置几何管理器作为下拉菜单工作,它不会与其他小部件重叠。我知道有些人说无论如何都不要使用
place()
,但我只需要满足我的好奇心,即使用 place
d 框架而不是使用无边框顶级窗口是否会更容易。
但是我根本无法让
place
d 框架重叠,所以有人可以告诉我这个简单的示例代码有什么问题吗?为什么 dropdown
不与其他小部件重叠?一旦它的 rely
设置为 1,它就会变得不可见,并被其他小部件覆盖。
import tkinter as tk
def unplace():
dropdown.place_forget()
def show(evt=None):
dropdown.lift()
dropdown.place(relx=0, rely=0.3, anchor='nw', relwidth=1.0)#rely=1,
# dropdown.place(relx=0, rely=1, anchor='nw', relwidth=1.0)
dropdown_item.grid(sticky="ew")
root = tk.Tk()
root.geometry("400x400+600+300")
root.config(bg="red")
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frm = tk.Frame(root, bg="blue")
frm.grid(sticky="news")
ent = tk.Entry(frm)
ent.grid()
ent.bind("<Button-1>", show)
dropdown = tk.Frame(ent, bg="tan")
dropdown_item = tk.Button(
dropdown, bg="steelblue", width=12, command=unplace, text="item")
# If these labels are commented, `dropdown` still won't overlap.
c = tk.Label(frm, text="Overlap Me")
c.grid()
d = tk.Label(frm, text="Overlap Me")
d.grid()
e = tk.Label(frm, text="Overlap Me")
e.grid()
f = tk.Label(frm, text="Overlap Me")
f.grid()
show()
root.mainloop()
当我按照@acw1668评论中的建议进行操作时,我发现我误解了x和y。它们是相对于父级的位置,而不是相对于屏幕的位置。将下拉列表的父级更改为组合框的父级是第一步。
import tkinter as tk
def unplace():
dropdown.place_forget()
def show(evt=None):
root.update_idletasks()
ht = ent.winfo_reqheight()
item.grid()
x = ent.winfo_x()
y = ent.winfo_y() + ht
dropdown.place(x=x, y=y, anchor='nw')
dropdown.lift()
root = tk.Tk()
root.geometry("400x400+600+300")
root.config(bg="red")
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frm = tk.Frame(root, bg="blue")
frm.grid(sticky="news")
ent = tk.Entry(frm)
ent.grid()
dropdown = tk.Frame(frm)
item = tk.Button(
dropdown, width=12, command=unplace, text="item", bd=0, bg="dark gray")
ent.bind("<Button-1>", show)
c = tk.Label(frm, text="Overlap Me")
c.grid()
d = tk.Label(frm, text="Overlap Me")
d.grid()
e = tk.Label(frm, text="Overlap Me")
e.grid()
f = tk.Label(frm, text="Overlap Me")
f.grid()
root.mainloop()