我试图在Tkinter中创建一个自定义的下拉列表,我决定选择Toplevel
。一切都按预期工作,除了焦点没有发生。创建窗口后,它会保持在我的其他窗口之上,但<Enter>/<Leave>
绑定在我点击窗口之前不起作用。这是一个确切问题的重建示例。
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.mainframe = ttk.Frame(self)
self.init_ui()
self.mainloop()
def init_ui(self):
self.mainframe.grid(row=0, column=0, sticky='nsew')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=1)
self.mainframe.columnconfigure(0, weight=1)
l = ttk.Label(self.mainframe, text='Test ▾')
l.config(cursor='hand', font=('Helvetica', 12, 'underline'))
l.bind('<Button-1>', self.dropdown)
l.grid(row=0, column=0, padx=50, pady=(5, 300), sticky='new')
def dropdown(self, *args):
top = tk.Toplevel(self)
top.overrideredirect(1)
top.transient(self)
def create_label(n):
nonlocal top
l = tk.Label(top, text='Test{}'.format(n))
l.config(cursor='hand', relief='ridge')
l.bind('<Enter>', enter_leave)
l.bind('<Leave>', enter_leave)
l.bind('<Button-1>', lambda _: top.destroy())
l.grid(row=n, column=0)
def enter_leave(e):
# 7 = enter
# 8 = leave
if e.type == '7':
e.widget.config(bg='grey')
else:
e.widget.config(bg='white')
# populate some labels
for x in range(9):
create_label(x)
self.update_idletasks()
top_width = top.winfo_width()
top_height = top.winfo_height()
root_x = self.winfo_x()
root_y = self.winfo_y()
top.geometry('{}x{}+{}+{}'.format(
top_width, top_height,
int(root_x + (self.winfo_width() / 2)),
root_y + 50
))
if __name__ == '__main__':
App()
这是看起来像:
如果我取出top.overrideredirect(1)
,那么它会按预期工作,但我会使用我不想要的标题栏:
另一个有趣的事情是,当我在调用self.update_idletasks()
之前运行top.overrideredirect(1)
然后它再次起作用但是使用冻结的标题栏。我不确定为什么没有self.update_idletasks()
就不会发生这种情况(这可能是一个不同的问题):
我尝试了以下几种组合,没有想要的结果:
top.attributes('-topmost', True)
top.lift(aboveThis=self)
top.focus_force()
top.grab_set()
总而言之,我只想得到#34;突出显示&#34;工作效果,但图像1的外观没有标题栏。我对所有其他建议或方法持开放态度。