2

我正在实现一个基于 tkinter 文本小部件的控制台应用程序,作为自动完成功能的一部分,我观察到一个问题,即按下返回键会导致删除所选文本。下面的示例显示了类似的问题:

from Tkinter import *

def getCommand(*args):
    global text
    text.insert(END, "\n")
    text.insert(END, "command>")
    x = text.get("1.0",END)
    print "command is %s" %(x)
    return 'break'

def handle_keyrelease(event):
    global text
    if event.keysym == "Return":
        text.tag_remove(SEL,"1.9",END)
        text.mark_set("insert",END)
        getCommand()
        return 'break'

root = Tk()
text = Text(root)
text.pack()
text.insert(END,"command>")
text.focus()
text.bind("<KeyRelease>", handle_keyrelease)
text.insert(END,"sometext")
text.tag_add(SEL,"1.9",END)
text.mark_set("insert","1.9") 
root.mainloop()

在这段代码中,当我按回车键时,我想获得完整的命令sometext,但是只s检索当前代码。当收到返回键事件时,我尝试将光标位置设置为结束并删除选择标签。

编辑

KeyPress事件处理程序的问题:

from Tkinter import *

def getCommand(*args):
    global text
    text.insert(END, "\n")
    text.insert(END, "command>")
    x = text.get("1.0",END)
    print x
    return 'break'

validkeysymchars = []
validkeysymchars = validkeysymchars + map(chr, range(65,91))
validkeysymchars = validkeysymchars + map(chr, range(97,123))

def handle_keyrelease(event):
    global text
    if event.keysym == "Return":
        text.tag_remove(SEL,"1.9",END)
        text.mark_set("insert",END)
        getCommand()
        return 'break'
    if event.keysym in validkeysymchars:
        for x in ['testcommand']:
            strtocmp = text.get("MARK","end")
            strtocmp = strtocmp.encode('ascii','ignore')
            strtocmp = strtocmp.strip()
            print strtocmp
            if x.startswith(strtocmp):
                currpos = text.index(INSERT)
                text.insert(END,x[len(strtocmp):])
                text.tag_add(SEL,currpos,"%s+%dc"%(currpos,len(x)-len(strtocmp)))
                text.mark_set("insert",currpos)   

root = Tk()
text = Text(root)
text.pack()
text.insert(END,"command>")
text.mark_set("MARK",INSERT)
text.mark_gravity("MARK",LEFT)
text.focus()
text.bind("<KeyPress>", handle_keyrelease)
root.mainloop()
4

1 回答 1

1

问题是您处理<KeyRelease>而不是<KeyPress>(或<Return>)。

<KeyRelease>引发事件时,文本小部件已使用换行符进行了更新。并且由于选择了文本,因此所选文本只需用换行符替换(因为它会通过按任何其他键来替换)。

所以最好绑定到<KeyPress>or<Return>而不是<KeyRelease>.


我认为解决您的问题的最简单方法确实是分别<KeyRelease>处理<Return>

(您可以使用 来使其工作<KeyPress>,但这将涉及检查按下了哪个键,手动将此键插入到文本中,检查选择了哪些文本,并替换选定的文本;因此,它会相当笨拙)。

def handle_keyrelease(event):
    global text
    if event.keysym in validkeysymchars:
        for x in ['testcommand']:
            strtocmp = text.get("MARK","end")
            strtocmp = strtocmp.encode('ascii','ignore')
            strtocmp = strtocmp.strip()
            print strtocmp
            if x.startswith(strtocmp):
                currpos = text.index(INSERT)
                text.insert(END,x[len(strtocmp):])
                text.tag_add(SEL,currpos,"%s+%dc"%(currpos,len(x)-len(strtocmp)))
                text.mark_set("insert",currpos)
                return

def handle_return(event):
    text.tag_remove(SEL,"1.9",END)
    text.mark_set("insert",END)
    text.insert(END, "\n")
    text.insert(END, "command>")
    text.mark_set("MARK",INSERT)
    text.mark_gravity("MARK",LEFT)
    return "break"

...
text.bind("<KeyRelease>", handle_keyrelease)
text.bind("<Return>", handle_return)
...
于 2013-09-02T11:55:07.317 回答