Python tkinter Text 多行文本框变化事件

问题描述

import tkinter as tk


def on_modify(event):
    chars = event.widget.get('0.0', 'end')
    label.configure(text='%s chars' % len(chars))
    print(chars)


win = tk.Tk()
label = tk.Label(win, anchor=tk.W)
label.pack(side=tk.BOTTOM, fill=tk.X)
text = tk.Text(win, height=4)
text.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
text.focus()
text.bind('<Key>', on_modify)
win.mainloop()

在这里插入图片描述
tk.Text 类直接绑定 <Key> 事件,获取的内容不实时且不准确,特别在发生粘贴和退格的时候




解决方案

修改 get() 方法并实现自定义多行文本框类

import tkinter as tk


class CustomText(tk.Text):
    def __init__(self, *args, **kwargs):
        """自定义多行文本框类,可实时监控变化事件"""
        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):
        if command == 'get' and (args[0] == 'sel.first' and args[1] == 'sel.last') and not self.tag_ranges('sel'):
            return
        if command == 'delete' and (args[0] == 'sel.first' and args[1] == 'sel.last') and not self.tag_ranges('sel'):
            return
        cmd = (self._orig, command) + args
        result = self.tk.call(cmd)
        if command in ('insert', 'delete', 'replace'):
            self.event_generate('<<TextModified>>')
        return result


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


win = tk.Tk()
label = tk.Label(win, anchor=tk.W)
label.pack(side=tk.BOTTOM, fill=tk.X)
text = CustomText(win, height=4)
text.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
text.focus()
text.bind('<<TextModified>>', on_modify)
win.mainloop()

效果



或调用 idlelib.redirector.WidgetRedirector(本人调试失败,有成功的朋友请不吝赐教)

import tkinter as tk
from idlelib.redirector import WidgetRedirector


def on_insert(*args):
    chars = text.get('0.0', 'end')
    label.configure(text='%s chars' % len(chars))
    print(args)
    old_insert(*args)


def on_delete(*args):
    chars = text.get('0.0', 'end')
    label.configure(text='%s chars' % len(chars))
    print(args)
    old_delete(*args)


win = tk.Tk()
label = tk.Label(win, anchor=tk.W)
label.pack(side=tk.BOTTOM, fill=tk.X)
text = tk.Text(win, height=4)
text.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
text.focus()
redirector = WidgetRedirector(text)
old_insert = redirector.register('insert', on_insert)
old_delete = redirector.register('delete', on_delete)
win.mainloop()




参考文献

  1. TkInter: how to get actual text modification?
  2. Text doesn’t contain any characters tagged with “sel” tkinter
  3. GUI Programming with Python: Events and Binds
  4. Where can I find WidgetRedirector in with Python3?
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XerCis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值