如何让 Tkinter 事件侦听器工作?



我正在使用Tkinter作为我用Python编写的小工具的GUI。基本上,我只想在条目小部件的内容更改后立即执行回调方法。这可以使用 Tkinter 自己的变量类(StringVar、BooleanVar 等(来完成 - 有关详细信息,请参阅文档:http://effbot.org/tkinterbook/variable.htm(。

所以我无法让机制工作,我在网上找到了一个片段,它工作得很好。现在我试图弄清楚为什么我的版本不起作用。 正如您在两个代码示例中所看到的,唯一的区别是,我在类中使用事件侦听功能,而我在网上找到的代码片段仅以直接从上到下的方式演示它。 这是我已经尝试过的:

  • 我直接在我的 GUI 类的构造函数中实例化了 Tk 实例 - 相同的行为。
  • 我直接从 Tk 类(而不是 Frame(继承了 - 相同的行为。
  • 我将回调放在类之外 - 相同的行为。
我唯一的想法是问题可能与范围有关,我试图验证这一点。

工作代码片段:

from tkinter import *
import tkinter as tk
def text_changed(*args):
print("Text changed.")
top = tk.Tk()
string_listener = StringVar()
string_listener.set("Init Text")
string_listener.trace("w", text_changed)
entry_widget = tk.Entry(top, textvariable = string_listener)
entry_widget.pack()
top.mainloop()

代码片段不起作用

from tkinter import *
import tkinter as tk
root = tk.Tk()
class GUI(tk.Frame):
def __init__(self, master=root):
super(GUI, self).__init__(master)
string_listener = StringVar()
string_listener.set("Init Text")
string_listener.trace("w", self.text_changed_callback)
entry_widget = tk.Entry(master, textvariable=string_listener)
entry_widget.pack()
def text_changed_callback(self, *args):
print("Text changed.")
gui = GUI()
gui.mainloop()

就像在工作示例中一样,我的代码应该打印Text changed.,每次从外部小部件中的字符串中删除或附加到字符串时。

问题是string_listener是一个局部变量,python 在__init__完成运行时正在销毁该变量。这不会发生在原始代码中,因为变量是在全局范围内创建的。

一个简单的解决方案是将引用另存为类的属性:

import tkinter as tk
root = tk.Tk()
class GUI(tk.Frame):
def __init__(self, master=root):
super(GUI, self).__init__(master)
self.string_listener = tk.StringVar()
self.string_listener.set("Init Text")
self.string_listener.trace("w", self.text_changed_callback)
entry_widget = tk.Entry(master, textvariable=self.string_listener)
entry_widget.pack()
def text_changed_callback(self, *args):
print("Text changed.")
gui = GUI()
gui.mainloop()

注意:我还StringVar更改为tk.StringVar,以便我可以删除tkinter的冗余通配符导入。

最新更新