Skip to content Skip to sidebar Skip to footer

Tkinter Text Entry With Pyhook Hangs Gui Window

I have a Tkinter GUI application that I need to enter text in. I cannot assume that the application will have focus, so I implemented pyHook, keylogger-style. When the GUI window d

Solution 1:

I modified the source code given in the question (and the other one) so that the pyHook related callback function sends keyboard event related data to a queue. The way the GUI object is notified about the event may look needlessly complicated. Trying to call root.event_generate in keypressed seemed to hang. Also the set method of threading.Event seemed to cause trouble when called in keypressed.

The context where keypressed is called, is probably behind the trouble.

from Tkinter import *
import threading

import pythoncom, pyHook

from multiprocessing import Pipe
import Queue
import functools

classTestingGUI:
    def__init__(self, root, queue, quitfun):
        self.root = root
        self.root.title('TestingGUI')
        self.queue = queue
        self.quitfun = quitfun

        self.button = Button(root, text="Withdraw", command=self.hide)
        self.button.grid()

        self.search = StringVar()
        self.searchbox = Label(root, textvariable=self.search)
        self.searchbox.grid()

        self.root.bind('<<pyHookKeyDown>>', self.on_pyhook)
        self.root.protocol("WM_DELETE_WINDOW", self.on_quit)

        self.hiding = Falsedefhide(self):
        ifnot self.hiding:
            print'hiding'
            self.root.withdraw()
            # instead of time.sleep + self.root.deiconify()
            self.root.after(2000, self.unhide)
            self.hiding = Truedefunhide(self):
        self.root.deiconify()
        self.hiding = Falsedefon_quit(self):
        self.quitfun()
        self.root.destroy()

    defon_pyhook(self, event):
        ifnot queue.empty():
            scancode, ascii = queue.get()
            print scancode, asciiif scancode == 82:
                self.hide()

            self.search.set(ascii)

root = Tk()
pread, pwrite = Pipe(duplex=False)
queue = Queue.Queue()

defquitfun():
    pwrite.send('quit')

TestingGUI = TestingGUI(root, queue, quitfun)

defhook_loop(root, pipe):
    while1:
        msg = pipe.recv()

        iftype(msg) isstrand msg == 'quit':
            print'exiting hook_loop'break

        root.event_generate('<<pyHookKeyDown>>', when='tail')

# functools.partial puts arguments in this orderdefkeypressed(pipe, queue, event):
    queue.put((event.ScanCode, chr(event.Ascii)))
    pipe.send(1)
    returnTrue

t = threading.Thread(target=hook_loop, args=(root, pread))
t.start()

hm = pyHook.HookManager()
hm.HookKeyboard()
hm.KeyDown = functools.partial(keypressed, pwrite, queue)

try:
    root.mainloop()
except KeyboardInterrupt:
    quit_event.set()

Post a Comment for "Tkinter Text Entry With Pyhook Hangs Gui Window"