我正在寫python 2.7中的一個工具,記錄用戶按下鍵盤或鼠標按鈕的次數。點擊量將顯示在屏幕左上方的小黑框中。即使另一個應用程序是活動應用程序,程序也會註冊點擊。使用tkinter + pyhook時凍結。兩個事件循環和多線程
它工作正常,除非我將鼠標移到框上。然後鼠標凍結幾秒鐘後,程序再次運行。如果我再次將鼠標移到框上,鼠標再次凍結,但是這次程序崩潰了。
我已經嘗試註釋掉pumpMessages(),然後程序工作。這個問題看起來很像這個問題pyhook+tkinter=crash,但沒有給出解決方案。
其他答案表明,在python 2.6中使用wx和pyhook時,dll文件存在一個bug。我不知道這是否與此有關。
我自己的想法是,它可能與兩個並行運行的事件循環有關。我已經讀過tkinter不是線程安全的,但是我看不到如何讓這個程序在單線程中運行,因爲我需要同時運行pumpmessages()和mainlooop()。
總結:爲什麼我的程序凍結在鼠標上?
import pythoncom, pyHook, time, ctypes, sys
from Tkinter import *
from threading import Thread
print 'Welcome to APMtool. To exit the program press delete'
## Creating input hooks
#the function called when a MouseAllButtonsUp event is called
def OnMouseUpEvent(event):
global clicks
clicks+=1
updateCounter()
return True
#the function called when a KeyUp event is called
def OnKeyUpEvent(event):
global clicks
clicks+=1
updateCounter()
if (event.KeyID == 46):
killProgram()
return True
hm = pyHook.HookManager()# create a hook manager
# watch for mouseUp and keyUp events
hm.SubscribeMouseAllButtonsUp(OnMouseUpEvent)
hm.SubscribeKeyUp(OnKeyUpEvent)
clicks = 0
hm.HookMouse()# set the hook
hm.HookKeyboard()
## Creating the window
root = Tk()
label = Label(root,text='something',background='black',foreground='grey')
label.pack(pady=0) #no space around the label
root.wm_attributes("-topmost", 1) #alway the top window
root.overrideredirect(1) #removes the 'Windows 7' box around the label
## starting a new thread to run pumMessages() and mainloop() simultaniusly
def startRootThread():
root.mainloop()
def updateCounter():
label.configure(text=clicks)
def killProgram():
ctypes.windll.user32.PostQuitMessage(0) # stops pumpMessages
root.destroy() #stops the root widget
rootThread.join()
print 'rootThread stopped'
rootThread = Thread(target=startRootThread)
rootThread.start()
pythoncom.PumpMessages() #pump messages is a infinite loop waiting for events
print 'PumpMessages stopped'
確定,這可能是它。我已經嘗試將pumpmessages()放入另一個線程,但它不起作用。我發現某處pumpmessages()也只能在主線程中運行。任何建議的替代gui呢?還是另一種解決方法? – Thorbjorn