如何使用tkinter每次循环获取文本小部件的内容?

如何使用tkinter每次循环获取文本小部件的内容?

问题描述:

我想重复获取文本小部件的内容,以便我可以分析它并获取有关输入内容的统计信息。这些统计信息需要在用户输入时实时更新,因此我需要使用currentContent变量来更新每个循环。我想要做的就是这样的事情。如何使用tkinter每次循环获取文本小部件的内容?

main = tk.Tk() 
# Y'know, all the typical window setup stuff. 

currentContent = inputBox.get(0.0,END) 
textBlobContent = TextBlob(currentContent) 
# Basically here I'd do a bunch of stuff using TextBlob. 

main.mainloop() 

但是,这是行不通的。一旦窗口加载,它就会获取一次内容,然后停止。主循环肯定会重复运行,并且它应该继续获取Text小部件的内容?

+0

我认为你正在寻找'after'方法:https://开头计算器.com/questions/25753632/tkinter-how-to-use-after-method –

+0

@ j_4321'after'方法?那不是基于时间而是基于每个循环来做? –

+0

根据您的小部件,您可以使用StringVar/IntVar和'.trace'方法。请注意,这将使每次更改都会运行“trace”。类似的想法,但在'Text'小部件上使用'.bind'显示在这里:https://stackoverflow.com/questions/17120429/validation-on-tkinter-text-widget – Lafexlos

一个简单的解决方案,大部分时间工作将是一个绑定<KeyRelease>。这将使用户输入时可以调用一个函数。只要数据用鼠标粘贴或通过其他方式(如工具栏按钮)插入,这不会触发回调。

更强大的解决方案是为小部件设置代理,以便在小部件中插入或删除任何内容时生成事件。该代理可以查看小部件正在做什么(插入,删除,选择已更改等)并生成事件。然后你可以绑定到这个事件来做你想做的任何事情。

下面是生成<<TextModified>>事件只要将数据插入或删除自定义文本类的例子:

import tkinter as tk 

class CustomText(tk.Text): 
    def __init__(self, *args, **kwargs): 
     """A text widget that report on internal widget commands""" 
     tk.Text.__init__(self, *args, **kwargs) 

     # create a proxy for the underlying widget 
     self._orig = self._w + "_orig" 
     self.tk.call("rename", self._w, self._orig) 
     self.tk.createcommand(self._w, self._proxy) 

    def _proxy(self, command, *args): 
     cmd = (self._orig, command) + args 
     result = self.tk.call(cmd) 

     if command in ("insert", "delete", "replace"): 
      self.event_generate("<<TextModified>>") 

     return result 

此代理并四两件事:

  1. 首先,它调用实际的小部件命令,传入所有收到的参数。
  2. 下它会产生一个事件对于每次插入,每删除
  3. 然后再生成一个虚拟的事件
  4. 最后返回实际组件命令的结果

您可以准确地使用这个小工具像任何其他文本小部件一样,还可以绑定到<<TextModified>>

例如,如果你想显示文本组件中的字符数,你可以做这样的事情:

import tkinter as tk 

# ... import of definition of CustomText goes here ... 

root = tk.Tk() 
label = tk.Label(root, anchor="w") 
text = CustomText(root, width=40, height=4) 

label.pack(side="bottom", fill="x") 
text.pack(side="top", fill="both", expand=True) 

def onModification(event): 
    chars = len(event.widget.get("1.0", "end-1c")) 
    label.configure(text="%s chars" % chars) 

text.bind("<<TextModified>>", onModification) 

root.mainloop()