我需要检查在执行某些非 GUI 代码期间是否按下了 Escape 键。(代码在 Python 中,但必要时可以轻松调用 C。)代码从 GUI 接收一个函数,它偶尔调用该函数来检查它是否已被中断。问题是如何实施这项检查。
通过查看文档,gdk_event_peek
这似乎是一个很好的选择:
def _check_esc(self):
event = gtk.gdk.event_peek()
if event is None or event.type not in (gtk.gdk.KEY_PRESS, gtk.gdk.KEY_RELEASE):
return False
return gtk.gdk.keyval_name(event.keyval) == 'Escape'
但是,这不起作用:gtk.gdk.event_peek()
当主循环未运行时,从返回的事件始终为 None 。将其更改为gtk.gdk.display_get_default().peek_event()
也无济于事。我假设这些事件在 X 事件队列中并且尚未移动到 GDK 事件队列中。文档说:
请注意,此函数不会从窗口系统获取更多事件。它只检查已经移动到 GDK 事件队列的事件。
那么,如何将事件转移到 GDK 事件队列中呢?换句话说,什么gtk.gdk.peek_event()
时候返回一个事件?调用gtk.events_pending()
没有任何效果。
这是一个测试它的最小程序:
import gtk, gobject
import time
def code(check):
while 1:
time.sleep(.1)
if check():
print 'interrupted'
return
def _check_esc():
event = gtk.gdk.event_peek()
print 'event:', event
if event is None or event.type not in (gtk.gdk.KEY_PRESS, gtk.gdk.KEY_RELEASE):
return False
return gtk.gdk.keyval_name(event.keyval) == 'Escape'
def runner():
code(_check_esc)
gtk.main_quit()
w = gtk.Window()
w.show()
gobject.idle_add(runner)
gtk.main()
运行代码时,打印的事件始终为 None,即使您按下 Escape 或移动鼠标。
我还考虑过为 Escape 安装一个处理程序,并让检查器使用while gtk.events_pending(): gtk.main_iteration()
成语处理事件。这将导致所有待处理事件(包括键盘和鼠标事件)的出队和分派。效果是在代码运行时 GUI 启用了响应式,这看起来不太好,并且会严重干扰代码的执行。执行期间处理的唯一事件应该是用于中断它的转义键。