Tkinter Toplevel"下拉"不重视

时间:2017-06-29 16:12:19

标签: python tkinter

我试图在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()

这是看起来像:

tk window

如果我取出top.overrideredirect(1),那么它会按预期工作,但我会使用我不想要的标题栏:

tk window with overrideredirect off

另一个有趣的事情是,当我在调用self.update_idletasks()之前运行top.overrideredirect(1)然后它再次起作用但是使用冻结的标题栏。我不确定为什么没有self.update_idletasks()就不会发生这种情况(这可能是一个不同的问题):

tk window with update_idletasks

我尝试了以下几种组合,没有想要的结果:

top.attributes('-topmost', True)
top.lift(aboveThis=self)
top.focus_force()
top.grab_set()

总而言之,我只想得到#34;突出显示&#34;工作效果,但图像1的外观没有标题栏。我对所有其他建议或方法持开放态度。

0 个答案:

没有答案