Как привязать клавишу backspace в tkinter для удаления более одного символа?

Я хочу создать привязки, которые позволяют мне нажать tab, чтобы вставить предопределенное количество пробелов, а затем нажмите backspace, чтобы удалить это количество пробелов на основе переменной.

Как удалить заранее определенное количество пробелов, когда пользователь нажимает клавишу backspace? Я не знаю, как удалить несколько символов, и когда я попытался решить эту проблему, привязка удаляет неправильное количество символов.

1 ответов


есть две части этого вопроса. Первая часть связана с как удалить несколько символов одновременно. Вторая часть - как использовать это в привязке, привязанной к клавишам backspace

удаление более одного символа

на delete метод текстового виджета принимает два индекса и удаляет символы между этими индексами. Текстовые индексы Tkinter могут быть относительными применяя модификаторы к индексу. Например, для ссылки на четыре символы перед точкой вставки вы можете использовать индекс "insert" плюс модификатор "-4 chars".

пример:

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

поскольку эти индексы являются нормальными строками, вы можете использовать форматирование строк, если хотите использовать переменную.

пример:

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

использование функции с привязкой

чтобы запустить функцию, когда пользователь нажимает клавишу backspace, вы можете привязать функцию <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

все вместе

вот полный рабочий пример, который вставит четыре пробела, когда вы нажмите tab и удалите четыре пробела при нажатии backspace:

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()