为什么我需要 lambda func 绑定到 <Key> 在 Tkinter root window 中调用一个方法
Why do I need lambda func to have bind to <Key> call a method in Tkinter root window
我有这段代码(抱歉,不是很简单):
import tkinter as tk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
# tk.Frame.__init__(self, parent, *args, **kwargs)
super().__init__(parent, *args, **kwargs)
self.reader = parent
# self.reader = tk.Toplevel(self)
self.reader.title("XXX")
self.reader.resizable(False, True)
self.reader.geometry("650x5")
self.reader.minsize(650,150)
self.panel = tk.Text(self.reader, wrap="word", width=12, font=('Courier',14))
self.viewer = tk.Text(self.reader, wrap="word", font=('Courier',14))
self.viewer.insert(tk.INSERT,'h\nm\nbbb\ntt\n\nbbb')
self.panel.insert(tk.INSERT,'hgggg\ngggm\nbbb\n\nbbbbtt\n\nbbb')
self.labelv1 = tk.IntVar()
# self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
self.labelv2 = tk.IntVar()
# self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
self.pippo = tk.StringVar()
# self.pippo.set(("Panel : "+str(self.labelv1)+" Viewer : "+str(self.labelv2)))
self.label = tk.Label(self.reader, textvariable = self.pippo)
self.label.pack(side='top')
# self.update_labels()
self.counter = tk.IntVar()
self.counter.set(0)
# self.reader.bind_class('Text', '<Key>', self.update_labels()) #winfo_toplevel()
# self.winfo_toplevel().bind("<Key>", self.update_labels())
# self.reader.bind("<Key>", self.update_labels())
self.reader.bind("<Key>", lambda event: self.update_labels())
self.scrollbar = tk.Scrollbar(self.reader, command=(self.on_scrollbar))
self.scrollbar.pack(side="right", fill="y")
self.panel.pack(side="left", fill="both", expand=True)
self.viewer.pack(side="right", fill="both", expand=True)
# Changing the settings to make the scrolling work
# self.scrollbar['command'] = self.on_scrollbar
self.panel['yscrollcommand'] = self.on_textscroll
self.viewer['yscrollcommand'] = self.on_textscroll
def update_labels(self, *args):
print('OKK')
self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
self.pippo.set("Panel : "+str(self.labelv1.get())+" Viewer : "+str(self.labelv2.get()))
self.counter.set(self.counter.get() + 1)
print('updating labels : ' , self.counter.get(),' / ', self.pippo.get())
return
def on_scrollbar(self, *args):
"""
Scrolls both text widgets when the scrollbar is moved
"""
self.panel.yview(*args)
self.viewer.yview(*args)
def on_textscroll(self, *args):
'''Moves the scrollbar and scrolls text widgets when the mousewheel
is moved on a text widget'''
self.scrollbar.set(*args)
self.on_scrollbar('moveto', args[0])
if __name__ == "__main__":
master = tk.Tk()
MainApplication(master)
master.mainloop()
我不明白为什么:
self.reader.bind("<Key>", lambda event: self.update_labels())
将文本 windows 内的任何按下的键绑定到一个函数 update_labels()
,该函数报告 window 本身
内的行文本数
有效,而
self.reader.bind("<Key>", self.update_labels())
不会。我阅读了很多文档和示例,这里也是如此,但无法弄清楚为什么后者不能正常工作。
你遇到的问题是因为你给出了函数的输出而不是它的引用。要解决您的问题,您应该这样做:
self.reader.bind("<Key>", self.update_labels)
在某处定义:
def update_labels(self, event):
...
我有这段代码(抱歉,不是很简单):
import tkinter as tk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
# tk.Frame.__init__(self, parent, *args, **kwargs)
super().__init__(parent, *args, **kwargs)
self.reader = parent
# self.reader = tk.Toplevel(self)
self.reader.title("XXX")
self.reader.resizable(False, True)
self.reader.geometry("650x5")
self.reader.minsize(650,150)
self.panel = tk.Text(self.reader, wrap="word", width=12, font=('Courier',14))
self.viewer = tk.Text(self.reader, wrap="word", font=('Courier',14))
self.viewer.insert(tk.INSERT,'h\nm\nbbb\ntt\n\nbbb')
self.panel.insert(tk.INSERT,'hgggg\ngggm\nbbb\n\nbbbbtt\n\nbbb')
self.labelv1 = tk.IntVar()
# self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
self.labelv2 = tk.IntVar()
# self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
self.pippo = tk.StringVar()
# self.pippo.set(("Panel : "+str(self.labelv1)+" Viewer : "+str(self.labelv2)))
self.label = tk.Label(self.reader, textvariable = self.pippo)
self.label.pack(side='top')
# self.update_labels()
self.counter = tk.IntVar()
self.counter.set(0)
# self.reader.bind_class('Text', '<Key>', self.update_labels()) #winfo_toplevel()
# self.winfo_toplevel().bind("<Key>", self.update_labels())
# self.reader.bind("<Key>", self.update_labels())
self.reader.bind("<Key>", lambda event: self.update_labels())
self.scrollbar = tk.Scrollbar(self.reader, command=(self.on_scrollbar))
self.scrollbar.pack(side="right", fill="y")
self.panel.pack(side="left", fill="both", expand=True)
self.viewer.pack(side="right", fill="both", expand=True)
# Changing the settings to make the scrolling work
# self.scrollbar['command'] = self.on_scrollbar
self.panel['yscrollcommand'] = self.on_textscroll
self.viewer['yscrollcommand'] = self.on_textscroll
def update_labels(self, *args):
print('OKK')
self.labelv1.set(int(self.panel.index('end-1c').split('.')[0]))
self.labelv2.set(int(self.viewer.index('end-1c').split('.')[0]))
self.pippo.set("Panel : "+str(self.labelv1.get())+" Viewer : "+str(self.labelv2.get()))
self.counter.set(self.counter.get() + 1)
print('updating labels : ' , self.counter.get(),' / ', self.pippo.get())
return
def on_scrollbar(self, *args):
"""
Scrolls both text widgets when the scrollbar is moved
"""
self.panel.yview(*args)
self.viewer.yview(*args)
def on_textscroll(self, *args):
'''Moves the scrollbar and scrolls text widgets when the mousewheel
is moved on a text widget'''
self.scrollbar.set(*args)
self.on_scrollbar('moveto', args[0])
if __name__ == "__main__":
master = tk.Tk()
MainApplication(master)
master.mainloop()
我不明白为什么:
self.reader.bind("<Key>", lambda event: self.update_labels())
将文本 windows 内的任何按下的键绑定到一个函数 update_labels()
,该函数报告 window 本身
有效,而
self.reader.bind("<Key>", self.update_labels())
不会。我阅读了很多文档和示例,这里也是如此,但无法弄清楚为什么后者不能正常工作。
你遇到的问题是因为你给出了函数的输出而不是它的引用。要解决您的问题,您应该这样做:
self.reader.bind("<Key>", self.update_labels)
在某处定义:
def update_labels(self, event):
...