【问题标题】:How to bind the backspace key in tkinter to delete more than one character?如何在 tkinter 中绑定退格键以删除多个字符?
【发布时间】:2017-05-11 16:21:37
【问题描述】:

我想创建绑定,让我按 Tab 键插入预定义数量的空格,然后按退格键删除那么多空格,基于变量。

当用户按下退格键时,如何删除预定数量的空格?我不知道如何删除多个字符,当我尝试解决这个问题时,绑定删除了错误数量的字符。

【问题讨论】:

  • 注意:这个问题最初是由@HKVariant 提出的,但我们遇到了沟通问题,他很沮丧并在我完成全面回答之前删除了原来的问题。一旦我了解他的真正问题是什么,我认为其他人可能会从我正在研究的答案中受益。

标签: python tkinter


【解决方案1】:

这个问题有两个部分。第一部分是关于如何 一次删除多个字符。第二部分是如何在绑定到退格键的绑定中使用它

删除多个字符

文本小部件的delete 方法采用两个索引,并将删除 这些索引之间的字符。 Tkinter 文本索引可以是相对的 通过将修饰符应用于索引。例如,要引用四个 插入点之前的字符可以使用索引"insert" 加上修饰符"-4 chars"

例子:

self.text.delete("insert -4 chars", "insert")

因为这些索引是普通的字符串,如果你想使用一个变量,你可以使用字符串格式化。

例子:

tabWidth = 4
self.text.delete("insert -%d chars" % tabWidth, "insert")

通过绑定使用函数

要在用户按下退格键时运行函数,可以绑定 <BackSpace> 事件的函数。这个函数将被传递 一个代表事件的参数。

例如:

self.text.bind("<BackSpace>", self.do_backspace)
...
def do_backspace(self, event):
    ...

对标准键进行自定义绑定的一个重要部分是要知道默认情况下您的绑定将不会替换默认行为。例如,如果您的绑定删除了一个字符然后返回,则会删除两个字符,因为您的绑定将删除一个字符,而默认绑定将删除一个。

覆盖此行为的方法是返回字符串"break"。因为您的自定义绑定发生在默认绑定之前,默认绑定将看到您返回“break”并且什么也不做。这使得覆盖默认行为或在保持默认行为的同时进行额外工作变得非常简单。

把它们放在一起,这就是你如何定义一个函数,如果它们是四个连续的空格,则删除前四个字符,如果不是,则执行默认行为:

def do_backspace(self, event):
    # get previous <tabWidth> characters; if they are all spaces, remove them

    previous = self.text.get("insert -%d chars" % self.tabWidth, "insert")
    if previous == " " * self.tabWidth:
        self.text.delete("insert-%d chars" % self.tabWidth, "insert")

        # return "break" so that the default behavior doesn't happen
        return "break"

    # if we get to here, we'll just return. That allows the default
    # behavior to run

把它们放在一起

这是一个完整的工作示例,当您插入四个空格时 按 T​​ab 键,按退格键时删除四个空格:

import tkinter as tk

def do_tab(event):
    text.insert("insert", " " * tabWidth)
    # return "break" so that the default behavior doesn't happen
    return "break"

def do_backspace(event):
    # get previous <tabWidth> characters; if they are all spaces, remove them
    previous = text.get("insert -%d chars" % tabWidth, "insert")
    if previous == " " * tabWidth:
        text.delete("insert-%d chars" % tabWidth, "insert")
        # return "break" so that the default behavior doesn't happen
        return "break"

    # if we get to here, we'll just return. That allows the default
    # behavior to run

root = tk.Tk()
tabWidth = 4

text = tk.Text(root)
text.pack(fill="both", expand=True)

text.bind("<Tab>", do_tab)
text.bind("<BackSpace>", do_backspace)

root.mainloop()

【讨论】:

  • return "break" 对我不起作用,是特定于 Python 3 的吗?
  • @Jachdich:不,自从 tkinter 首次创建以来,它一直是 tkinter 的一部分。
  • 好的,谢谢(愚蠢的字符下限...)
  • 非常感谢@BryanOakley。一周以来我一直在寻找这个答案,谢谢
猜你喜欢
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多