Python 3.x TkInter:如何获得实际的文本修改?
我想知道用户在tkinter的文本小部件中更改了什么位置和内容 我发现如何通过使用事件对文本进行修改,但无法获得实际更改:Python 3.x TkInter:如何获得实际的文本修改?,python-3.x,tkinter,Python 3.x,Tkinter,我想知道用户在tkinter的文本小部件中更改了什么位置和内容 我发现如何通过使用事件对文本进行修改,但无法获得实际更改: from tkinter import * def reset_modified(): global resetting_modified resetting_modified = True text.tk.call(text._w, 'edit', 'modified', 0) resetting_modified = False de
from tkinter import *
def reset_modified():
global resetting_modified
resetting_modified = True
text.tk.call(text._w, 'edit', 'modified', 0)
resetting_modified = False
def on_change(ev=None):
if resetting_modified: return
print ("Text now:\n%s" % text.get("1.0", END))
if False: # ????
print ("Deleted [deleted substring] from row %d col %d")
if False: # ????
print ("Inserted [inserted substring] at row %d col %d")
reset_modified()
resetting_modified = False
root = Tk()
text = Text(root)
text.insert(END, "Hello\nworld")
text.pack()
text.bind("<<Modified>>", on_change)
reset_modified()
root.mainloop()
例如,如果我在文本小部件中从hello\nworld中选择“ello”部分,然后按“E”,则我想查看
从第0行第1列删除[ello],然后在第0行第1列插入[E]
如果我想在运行时检测更改,是否有可能获得这些更改或至少它们的坐标,或者我基本上必须在每次击键时区分文本?仔细研究后,我发现idlelib有一个WidgetRedirector,它可以在插入/删除事件时重定向:
from tkinter import *
from idlelib.WidgetRedirector import WidgetRedirector
def on_insert(*args):
print ("INS:", text.index(args[0]))
old_insert(*args)
def on_delete(*args):
print ("DEL:", list(map(text.index, args)))
old_delete(*args)
root = Tk()
text = Text(root)
text.insert(END, "Hello\nworld")
text.pack()
redir = WidgetRedirector(text)
old_insert=redir.register("insert", on_insert)
old_delete=redir.register("delete", on_delete)
root.mainloop()
虽然它看起来很粗糙。还有更自然的方法吗?仔细研究后,我发现idlelib有一个WidgetRedirector,可以在插入/删除事件时重定向:
from tkinter import *
from idlelib.WidgetRedirector import WidgetRedirector
def on_insert(*args):
print ("INS:", text.index(args[0]))
old_insert(*args)
def on_delete(*args):
print ("DEL:", list(map(text.index, args)))
old_delete(*args)
root = Tk()
text = Text(root)
text.insert(END, "Hello\nworld")
text.pack()
redir = WidgetRedirector(text)
old_insert=redir.register("insert", on_insert)
old_delete=redir.register("delete", on_delete)
root.mainloop()
虽然它看起来很粗糙。还有更自然的方法吗?捕获底层tcl/tk代码执行的低级插入和删除是实现您想要的功能的唯一好方法。您可以使用WidgetRedirector之类的工具,如果您想要更多的控制,也可以使用自己的解决方案 编写自己的代理命令以捕获所有内部命令非常简单,只需几行代码。下面是一个自定义文本小部件的示例,该小部件可以在执行每个内部命令时打印出来:
from __future__ import print_function
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)
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):
# this lets' tkinter handle the command as usual
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
# here we just echo the command and result
print(command, args, "=>", result)
# Note: returning the result of the original command
# is critically important!
return result
if __name__ == "__main__":
root = tk.Tk()
CustomText(root).pack(fill="both", expand=True)
root.mainloop()
捕获底层tcl/tk代码执行的低级插入和删除是实现所需操作的唯一好方法。您可以使用WidgetRedirector之类的工具,如果您想要更多的控制,也可以使用自己的解决方案 编写自己的代理命令以捕获所有内部命令非常简单,只需几行代码。下面是一个自定义文本小部件的示例,该小部件可以在执行每个内部命令时打印出来:
from __future__ import print_function
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)
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):
# this lets' tkinter handle the command as usual
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
# here we just echo the command and result
print(command, args, "=>", result)
# Note: returning the result of the original command
# is critically important!
return result
if __name__ == "__main__":
root = tk.Tk()
CustomText(root).pack(fill="both", expand=True)
root.mainloop()