我有一个Tkinter GUI应用程序,我需要输入文本 . 我不能假设应用程序将具有焦点,所以我实现了pyHook,keylogger风格 .
当GUI窗口没有焦点时,文本输入工作正常,StringVar正确更新 . 当GUI窗口确实有焦点并且我尝试输入文本时,整个事情就会崩溃 .
即,如果我在启动程序后单击控制台窗口或其他任何内容,则文本输入有效 . 如果我尝试立即输入文本(GUI以焦点开始),或者我在任何时候重新聚焦窗口并输入文本,它就会崩溃 .
这是怎么回事?
下面是一个最小的完整可验证示例,用于演示我的意思:
from Tkinter import *
import threading
import time
try:
import pythoncom, pyHook
except ImportError:
print 'The pythoncom or pyHook modules are not installed.'
# main gui box
class TestingGUI:
def __init__(self, root):
self.root = root
self.root.title('TestingGUI')
self.search = StringVar()
self.searchbox = Label(root, textvariable=self.search)
self.searchbox.grid()
def ButtonPress(self, scancode, ascii):
self.search.set(ascii)
root = Tk()
TestingGUI = TestingGUI(root)
def keypressed(event):
key = chr(event.Ascii)
threading.Thread(target=TestingGUI.ButtonPress, args=(event.ScanCode,key)).start()
return True
def startlogger():
obj = pyHook.HookManager()
obj.KeyDown = keypressed
obj.HookKeyboard()
pythoncom.PumpMessages()
# need this to run at the same time
logger = threading.Thread(target=startlogger)
# quits on main program exit
logger.daemon = True
logger.start()
# main gui loop
root.mainloop()
1 回答
我修改了问题中给出的源代码(和另一个),以便pyHook相关的回调函数将键盘事件相关数据发送到队列 . GUI对象通知事件的方式可能看起来不必要地复杂化 . 试图在
keypressed
中调用root.event_generate
似乎挂了 . 在keypressed
中调用时,threading.Event
的set
方法似乎也会造成麻烦 .调用
keypressed
的上下文可能背后的麻烦 .