Tkinter:在 <Key> 之后设置 StringVar事件,包括按下的键 [英] Tkinter: set StringVar after &lt;Key&gt; event, including the key pressed

查看:27
本文介绍了Tkinter:在 <Key> 之后设置 StringVar事件,包括按下的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次在 Text 小部件中输入一个字符时,我都想获取该小部件的内容并从某个数字中减去其长度(基本上是您还剩下 x 个字符"的交易).

Every time a character is entered into a Text widget, I want to get the contents of that widget and subtract its length from a certain number (basically a "you have x characters left" deal).

但是 StringVar() 总是落后于一个事件.这是,从我收集到的,因为在将字符输入到文本小部件之前处理事件.这意味着如果我在字段中有 3 个字符并且我输入了第 4 个字符,则 StringVar 会更新但仍然是 3 个字符长,然后当我输入第 5 个字符时它会更新为 4.

But the StringVar() is always one event behind. This is, from what I gather, because the event is processed before the character is entered into the Text widget. This means that if I have 3 characters in the field and I enter a 4th, the StringVar is updated but is still 3 characters long, then it updates to 4 when I enter a 5th character.

有没有办法让两者保持一致?

Is there a way to keep the two in line?

这是一些代码.我删除了不相关的部分.

Here's some code. I removed irrelevant parts.

def __init__(self, master):
    self.char_count = StringVar()
    self.char_count.set("140 chars left")

    self.post_tweet = Text(self.master)
    self.post_tweet.bind("<Key>", self.count)
    self.post_tweet.grid(...)

    self.char_count = Label(self.master, textvariable=self.foo)
    self.char_count.grid(...)

def count(self):
    self.x = len(self.post_tweet.get(1.0, END))
    self.char_count.set(str(140 - self.x))

推荐答案

一个简单的解决方案是在类绑定之后添加一个新的 bindtag.这样,类绑定将在您的绑定之前触发.请参阅此答案对问题以文本小部件绑定后如何在 Tkinter 文本小部件中绑定自身事件? 举个例子.该答案使用条目小部件而不是文本小部件,但是这两个小部件之间的 bindtags 概念是相同的.只要确保在适当的地方使用 Text 而不是 Entry.

A simple solution is to add a new bindtag after the class binding. That way the class binding will fire before your binding. See this answer to the question How to bind self events in Tkinter Text widget after it will binded by Text widget? for an example. That answer uses an entry widget rather than a text widget, but the concept of bindtags is identical between those two widgets. Just be sure to use Text rather than Entry where appropriate.

另一个解决方案是在 KeyRelease 上绑定,因为默认绑定发生在 KeyPress 上.

Another solution is to bind on KeyRelease, since the default bindings happen on KeyPress.

这里有一个例子,展示了如何使用绑定标签来做到这一点:

Here's an example showing how to do it with bindtags:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.post_tweet = tk.Text(self)
        bindtags = list(self.post_tweet.bindtags())
        bindtags.insert(2, "custom") # index 1 is where most default bindings live
        self.post_tweet.bindtags(tuple(bindtags))

        self.post_tweet.bind_class("custom", "<Key>", self.count)
        self.post_tweet.grid()

        self.char_count = tk.Label(self)
        self.char_count.grid()

    def count(self, event):
        current = len(self.post_tweet.get("1.0", "end-1c"))
        remaining = 140-current
        self.char_count.configure(text="%s characters remaining" % remaining)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

这篇关于Tkinter:在 <Key> 之后设置 StringVar事件,包括按下的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆