在Tkinter文本小部件中更改Backspace效果

时间:2016-11-28 09:41:06

标签: python replace tkinter backspace strikethrough

我正在寻找一种方法来改变Tkinter文本小部件中的Backspace键效果。我正在监视Tkinter文本窗口中的关键事件,我需要找到一种方法:

  • 禁用退格键的效果,但仍然可以知道它已键入

  • 删除用户打算删除的字符

我不知道从哪里开始。我可以单独输出Backspace事件,但不知道如何阻止它删除字符。我也不知道如何实时影响输入(在用户写作时对字符应用删除线'风格')

这是我现在所拥有的,但这并不多:

from Tkinter import *
import tkFileDialog
root=Tk()
root.title("TextnonEdit")
text=Text(root)
text.grid()

def keepit(key):
    print key.keysym
    if key.keysym == "BackSpace":
        print "do not delete, strikethrough"

# Bind entry to keypress
text.bind("<Key>", keepit)

def saveas():
    global text
    t = text.get("1.0", "end-1c")
    savelocation=tkFileDialog.asksaveasfilename()
    file1=open(savelocation, "w+")
    file1.write(t)
    file1.close()

button=Button(root, text="Save", command=saveas)
button.grid()
root.mainloop()

提前感谢您的回答!

2 个答案:

答案 0 :(得分:1)

通过执行以下操作可以解决问题:

  1. 在文本小部件上创建一个标记,overstrike属性设置为true
  2. 在退格符上创建一个绑定以应用标记
  3. 使绑定函数返回"break"以防止默认行为
  4. 实施例

    import Tkinter as tk
    
    class Example(tk.Frame):
        def __init__(self, parent):
            tk.Frame.__init__(self, parent)
    
            self.text = tk.Text(self)
            self.text.pack(fill="both", expand=True)
    
            # add a tag that lets us apply the overstrike attribute
            self.text.tag_configure("overstrike", overstrike=True)
    
            # add a binding on the backspace key
            self.text.bind("<BackSpace>", self.handleBackspace)
    
        def handleBackspace(self, event):
            # add the overstrike to the character before the
            # insertion cursor
            self.text.tag_add("overstrike", "insert-1c", "insert")
    
            # move the cursor to the previous position
            self.text.mark_set("insert", "insert-1c")
    
            # prevent the default behaviour
            return "break"
    
    if __name__ == "__main__":
        root = tk.Tk()
        Example(root).pack(fill="both", expand=True)
        root.mainloop()
    

答案 1 :(得分:0)

谢谢Brian!这是我经过一些调整后得到的结果,它可以连续使用多个退格并删除选择:

import Tkinter as tk

x = 0

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.text = tk.Text(self)
        self.text.pack(fill="both", expand=True)
        # add a tag that lets us apply the overstrike attribute
        self.text.tag_configure("overstrike", overstrike=True)


        self.text.bind("<Key>", self.eyeout)

        # add a binding on the backspace key
        self.text.bind("<BackSpace>", self.handleBackspace)

    def eyeout(self, key):
        global x
        print key.keysym
        # move the cursor to the previous position
        self.text.mark_set("insert", "insert+" + str(x) + "c")

        print "insert+" + str(x) + "c"

        #reset consecutive backspace count to zero

        x = 0

    def handleBackspace(self, event):

        if self.text.tag_ranges(tk.SEL):
            print ('Selected text !')
            #if text is selected, overstrike all the selection
            self.text.tag_add("overstrike", "sel.first", "sel.last")
            # move cursor to end of selection
            self.text.mark_set("insert", "sel.last")
            # deselect to avoid overwrite
            self.text.tag_remove(tk.SEL, "sel.first", "sel.last")
            # counting doesn't apply to selection, reset backspace count
            global x
            x = 0
        else:
            print('NO Selected Text')
            # add the overstrike to the character before the
            # insertion cursor
            self.text.tag_add("overstrike", "insert-1c", "insert")
            # counting system to know how many backspaces in a row were entered
            print "Backspace!"
            print x
            global x
            x = x+1
            print x
            print "Backspace increase"
            self.text.mark_set("insert", "insert-1c")

        # prevent the default behaviour
        return "break"


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