我知道Tk的按键和释放事件应该只在按键被实际按下或释放时触发?
然而,在下面的简单代码中,如果我按住"a“键,我会得到一个连续的交替按键/释放键事件序列。
是我做错了什么,还是TkInter出了问题?这是Linux mint上的Python2.7。
from Tkinter import *
def keyup(e):
print 'up', e.char
def keydown(e):
print 'down', e.char
root = Tk()
frame = Frame(root, width=100, height=100)
frame.bind("<KeyPress>", keydown)
frame.bind("<KeyRelease>", keyup)
frame.pack()
frame.focus_set()
root.mainloop()按住“a”时的输出:
down a
up a
down a
up a
down a
up a
down a
up a
etc...发布于 2014-12-01 00:32:10
好的,更多的研究发现了this helpful post,这表明这是由于X的自动重复行为造成的。您可以使用以下命令禁用此功能
os.system('xset r off')然后使用脚本末尾的"on“重置它。问题是这是全球行为-不仅仅是我的脚本-这不是很好,所以我希望有人能想出更好的方法。
发布于 2014-12-01 14:05:01
自动重复行为取决于系统。在Win7中,
down a
down a
down a
...
down a
up a这是不到一秒的时间。
发布于 2019-02-07 16:09:27
好吧,现在有点晚了,但我有一个有效的解决方案。这不是很好,但它不需要os.system覆盖系统设置,这很好。
基本上,我创建了一个记录按键时间的类。我说当一个键在最后一小段时间内被按下时,它就是按下的(这里是.1ms)。要获得按下,很简单:如果键未注册为已按下,则触发事件。对于释放,逻辑比较困难:如果有可疑的释放事件,设置一个短时间的计时器(这里是.1s),然后检查以确保键没有按下。
验证完新闻或发布后,在代码中调用on_key_press或on_key_release方法。至于那些,只要按照你最初想要的方式来实现就行了。
我知道这并不完美,但我希望它能有所帮助!
代码如下:
初始化按键事件的位置:
key_tracker = KeyTracker()
window.bind_all('<KeyPress>', key_tracker.report_key_press)
window.bind_all('<KeyRelease>', key_tracker.report_key_release)
key_tracker.track('space')下面是我的自定义KeyTracker类:
class KeyTracker():
key = ''
last_press_time = 0
last_release_time = 0
def track(self, key):
self.key = key
def is_pressed(self):
return time.time() - self.last_press_time < .1
def report_key_press(self, event):
if event.keysym == self.key:
if not self.is_pressed():
on_key_press(event)
self.last_press_time = time.time()
def report_key_release(self, event):
if event.keysym == self.key:
timer = threading.Timer(.1, self.report_key_release_callback, args=[event])
timer.start()
def report_key_release_callback(self, event):
if not self.is_pressed():
on_key_release(event)
self.last_release_time = time.time()https://stackoverflow.com/questions/27215326
复制相似问题