我想得到a的插入点的光标位置(行和列)Tkinter.文本,但具体情况如下。在
问题:我的文本编辑器项目需要自定义的撤消/重做Tkinter.文本. 我为下面的测试1和测试2输入了相同的字符串,但是由于Tkinter给出的KeyRelease事件处理程序中的列变量不一致,undo的操作并不一致。问题似乎是我在第二个测试中输入太快,这会产生一个错误的列值。你能帮我找到问题吗?在
复制错误的两个测试过程:
测试一
结果:效果良好。(至少对我来说。浮肿:慢慢打字。)
测试二
结果:获取错误的列,并且无法正确撤消。(重新启动脚本并重复此步骤如果您一开始没有看到错误,它有时可以很好地快速键入。我通常最多尝试3到4次。)
问:这是Tkinter中的一个bug,还是我不理解Tkinter中某些特定的东西会为我的undo/redo记录生成一致的列?在
from Tkinter import *
class TextView(Text):
def __init__(self, root):
Text.__init__(self, root)
self.history = History(self)
self.bind("<KeyRelease>", self.keyRelease)
# used to capture a char at a time in keyRelease. If space char is pressed it creates a Word object and adds it to undo/redo history.
self.word = ""
def keyRelease(self, event):
if event.keysym == "space":
self.word += " "
self.makeWordRecord()
else:
self.word += event.char
def makeWordRecord(self, ):
if len(self.word):
index = self.index(INSERT)
wordEvent = Word(index, self.word)
self.history.addEvent(wordEvent)
self.word = ""
def undo(self, event):
self.makeWordRecord()
self.history.undo()
def redo(self, event):
self.history.redo()
class History(object):
def __init__(self, text):
self.text = text
self.events = []
self.index = -1
# create blank document record, line one, column one, no text
self.addEvent(Word("1.0", ""))
def addEvent(self, event):
if self.index +1 < len(self.events):
self.events = self.events[:self.index +1]
self.events.append(event)
self.index +=1
def undo(self):
if self.index > 0:
self.events[self.index].undo(self.text)
self.index -=1
def redo(self):
if self.index +1 < len(self.events):
self.index +=1
self.events[self.index].redo(self.text)
class Word(object):
def __init__(self, index, word):
self.index = index
self.word = word
def undo(self, text):
line = self.index.split(".")[0]
column = int(self.index.split(".")[-1])
startIndex = line + "." + str(column - len(self.word))
endIndex = line + "." + str(int(column))
text.delete(startIndex, endIndex)
def redo(self, text):
line = self.index.split(".")[0]
column = int(self.index.split(".")[-1])
startIndex = line + "." + str(column - len(self.word))
text.insert(startIndex, self.word)
if __name__ == "__main__":
root = Tk()
root.geometry("400x200+0+0")
textView = TextView(root)
textView.pack()
root.bind("<F1>", textView.undo)
root.bind("<F2>", textView.redo)
root.mainloop()
我终于弄明白了到底是怎么回事,和Tkinter无关,只是所有的工具箱。我现在可以诚实地说,我可以为最佳编程实践添加一些内容,并且:
不要通过绑定到密钥释放方法来处理密钥事件,而是使用按键方法处理密钥
为什么?在
这不是编程问题,而是硬件问题。当一个键被按下时,物理键就会下降。有一个弹簧把钥匙推回原位。如果这个弹簧或者键盘的任何东西导致一个键慢200分之一秒,那么每分钟键入60个单词都可能导致按一个顺序键入的键按另一个顺序返回。这可能是因为弹簧可能稍厚、较硬、过度使用,甚至粘性的摩卡会造成更大的阻力。在
资本化也会受到影响。必须同时按下shift键和另一个键以获取大写字母。但是,如果在释放键时处理键,则shift键可能比大写的字符键快,这将导致小写。这也允许字符颠倒。如果你在输入字符时检查它的位置,你也可能因此得到错误的位置。在
坚持按键。在
相关问题 更多 >
编程相关推荐