ユーザーがキーボードまたはマウスボタンを押した回数を登録するPython 2.7でツールを作成しています。クリック数は、画面左上の小さな黒いボックスに表示されます。プログラムは、別のアプリケーションがアクティブな場合でもクリックを登録します。
ボックスの上にマウスを移動する場合を除いて、正常に動作します。その後、マウスが数秒間フリーズした後、プログラムが再び動作します。次にマウスをボックスの上にもう一度移動すると、マウスは再びフリーズしますが、今度はプログラムがクラッシュします。
pumpMessages() をコメントアウトしてみましたが、プログラムは機能します。問題はこの質問pyhook+tkinter=crashによく似ていますが、解決策はありませんでした。
他の回答は、python 2.6 で wx と pyhook を一緒に使用すると、dll ファイルにバグがあることを示しています。それがここに関連しているかどうかはわかりません。
私自身の考えでは、2 つのイベント ループが並行して実行されていることに関係があるのではないかと考えています。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'