title: Freeze when using tkinter + pyhook. Two event loops and multithreading
body: <p>I am writing a tool in python 2.7 registering the amount of times the user pressed a keyboard or mouse button. The amount of clicks will be displayed in a small black box in the top left of the screen. The program registers clicks even when another application is the active one.</p>
  
  <p>It works fine except when I move the mouse over the box. The mouse then freezes for a few seconds after which the program works again. If I then move the mouse over the box a second time, the mouse freezes again, but this time the program crashes.</p>
  
  <p>I have tried commenting out pumpMessages() and then the program works. The problem looks a lot like this question <a href="https://stackoverflow.com/questions/6765362/pyhook-tkinter-crash">pyhook+tkinter=crash</a>, but no solution was given there.</p>
  
  <p>Other answers has shown that there is a bug with the dll files when using wx and pyhook together in python 2.6. I don't know if that is relevant here.</p>
  
  <p>My own thoughts is that it might have something to do with the two event loops running parallel. I have read that tkinter isn't thread safe, but I can't see how I can make this program run in a single thread since I need to have both pumpmessages() and mainlooop() running.</p>
  
  <p>To sum it up: Why does my program freeze on mouse over?</p>
  
  <pre><code>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'
  </code></pre>