首页 文章

Python Tkinter调用默认事件处理程序

提问于
浏览
0

我有一个带有输入框和按钮的GUI . 当我按下“q”时,关闭按钮应该被聚焦,除非条目具有焦点 . 按“q”时按下按钮有效,但是当我想在条目中插入“q”时,它会失去焦点,这样我就无法继续在输入框中插入文本 .

import tkinter as tk

class Window(tk.Tk):

        def __init__(self):
                tk.Tk.__init__(self)

                self.e = tk.Entry(self)
                self.e.pack()

                f = tk.Frame(self)
                f.pack()

                self.btn_save = tk.Button(f, text="save", command=lambda: print("save"))
                self.btn_save.pack(side='left')

                self.btn_close = tk.Button(f, text="close", command=self.destroy)
                self.btn_close.pack(side='left')

                self.bind('<w>', lambda e: self.btn_save.focus_set())
                self.bind('<q>', lambda e: self.btn_close.focus_set())

                self.e.focus_set()

w = Window()
w.mainloop()

我知道对于自定义事件处理程序,我可以通过返回 'break' 来避免进一步调用事件处理程序 . 但是如何调用 Entry 的事件处理程序?在以下代码中,当选择条目时,按"q"不再关闭关闭按钮,但我可以不再插入任何文本 .

import tkinter as tk

class Window(tk.Tk):

        def __init__(self):
                tk.Tk.__init__(self)

                self.e = tk.Entry(self)
                self.e.pack()

                f = tk.Frame(self)
                f.pack()

                self.btn_save = tk.Button(f, text="save", command=lambda: print("save"))
                self.btn_save.pack(side='left')

                self.btn_close = tk.Button(f, text="close", command=self.destroy)
                self.btn_close.pack(side='left')

                self.bind('<w>', lambda e: self.btn_save.focus_set())
                self.bind('<q>', lambda e: self.btn_close.focus_set())

                self.e.bind('<Key>', self.on_key_press)
                self.e.focus_set()

        def on_key_press(self, event):
                # How can I call the default event handler here
                # which takes care of inserting and removing characters, moving the cursor and everything?
                return 'break'

w = Window()
w.mainloop()

(顺便通过键盘调用关闭按钮时,窗口按预期关闭,但之后键盘被忽略,直到我点击另一个窗口 . 我使用的是i3版本4.8和Python 3.4.2 . )

1 回答

  • 0

    不过,我找到了一种似乎并不优雅的解决方法 . 特别是如果你有几个入口盒,这似乎不是一个好方法 .

    在聚焦按钮的事件处理程序内部,检查哪个窗口小部件具有焦点,如果它是输入框则不执行任何操作:

    import tkinter as tk
    
    class Window(tk.Tk):
    
            def __init__(self):
                    tk.Tk.__init__(self)
    
                    self.e = tk.Entry(self)
                    self.e.pack()
    
                    self.frame_buttons = tk.Frame(self)
                    self.frame_buttons.pack()
    
                    self.btn_save = tk.Button(self.frame_buttons, text="save", command=lambda:              print("save"))
                    self.btn_save.pack(side='left')
    
                    self.btn_close = tk.Button(self.frame_buttons, text="close", command=self.destroy)
                    self.btn_close.pack(side='left')
    
                    self.bind('<w>', lambda e: None if self.focus_get() == self.e else self.btn_save.       focus_set())
                    self.bind('<q>', lambda e: None if self.focus_get() == self.e else self.btn_close.      focus_set())
    
                    self.e.focus_set()
    
    w = Window()
    w.mainloop()
    

    如果有人能找到更好的解决方案,我将不胜感激 .


    关于在通过键盘调用关闭按钮后忽略键盘的问题,似乎有助于解压缩按钮框架并在销毁之前更新窗口:

    def destroy(self):
                    self.frame_buttons.pack_forget()
                    self.update()
                    tk.Tk.destroy(self)
    

相关问题