Python tkinter使用返回键防止删除所选文本

Python tkinter使用返回键防止删除所选文本,python,tkinter,Python,Tkinter,我正在实现一个基于tkinter文本小部件的控制台应用程序,作为自动完成功能的一部分,我观察到一个问题,按return键会导致删除所选文本。下面的示例显示了类似的问题: from Tkinter import * def getCommand(*args): global text text.insert(END, "\n") text.insert(END, "command>") x = text.get("1.0",END) print "c

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

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

问题是您处理的是
,而不是
(或

在引发
事件时,文本小部件已经用换行符更新。因为选中了文本,所以选中的文本被替换为换行符(按任何其他键都会替换)

所以最好绑定到
而不是


我认为解决您的问题最简单的方法确实是将
分开处理

(您可以使用
使其工作,但这需要检查按下了哪个键,手动将此键插入文本,检查选中的文本,并替换选中的文本;因此,它将相当笨重)

def handle_键释放(事件):
全局文本
如果event.keysym在validkeysymchars中:
对于['testcommand']中的x:
strtocmp=text.get(“标记”、“结束”)
strotcmp=strotcmp.encode('ascii','ignore')
strotcmp=strotcmp.strip()
打印STROTOCMP
如果x.startswith(strtocmp):
currpos=文本索引(插入)
文本.插入(结束,x[len(STROTOCMP):])
text.tag_add(SEL,currpos,“%s+%dc”%(currpos,len(x)-len(strotcmp)))
文本标记集(“插入”,currpos)
返回
def句柄返回(事件):
text.tag_移除(SEL,“1.9”,结束)
文本。标记集(“插入”,结束)
文本。插入(结束,“\n”)
text.insert(结束,“命令>”)
文本。标记集(“标记”,插入)
text.mark_重力(“mark”,左)
返回“中断”
...
text.bind(“,句柄\密钥释放)
text.bind(“,handle\u return)
...

实际上,我首先使用的是
KeyPress
事件处理程序,但我遇到了另一个奇怪的问题。我的自动完成代码没有使用
KeyPress
事件处理程序运行,并强制我使用
keyrease
处理程序。我已经更新了我的代码,你能评论一下为什么它不能与
KeyPress
事件处理程序一起工作吗。只需在文本窗口小部件上键入
t
,您就会注意到,在
keyrease
的情况下,它将在文本窗口小部件中插入
testcommand
,而使用
KeyPress
时什么也不会发生。看起来,在
KeyPress
的情况下,插入新字符后,上一个键将被读取。因此,唯一的解决方案是使用
keyrease
自动完成,使用
KeyPress
返回
键,还是可以更有效地处理它?@sarbjit您确实可以使用单个
处理程序,但这将是相当丑陋和复杂的。最好使用两个单独的处理器。请参阅我的编辑。
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()
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)
...