1

I am trying to build a program that listens for certain key combinations and then shows information to the user in a Tkinter window. To do this, I'm using a keylogger like so (simplified for this example):

from pyHook import HookManager
from pythoncom import PumpMessages
import Tkinter as tk

def on_keyboard_event(event):
    label.config(text=event.Key)
    root.update()
    return True

hm = HookManager()
hm.KeyDown = on_keyboard_event
hm.HookKeyboard()
root = tk.Tk()
label = tk.Label(root, text='Hello world')
label.pack()
PumpMessages()

As expected, the window pops up and shows the user what key they pressed. However, I would like to integrate functionality to show other messages by interacting with the Tkinter window, such as by pressing a button. However, it seems I need Tkinter's mainloop to do this, which I can't figure out how to run alongside PumpMessages(), since it also halts the code similar to mainloop().

I tried running root.mainloop() in a root.after(), and I tried recreating root.mainloop like so:

def mainloop():
    root.update()
    root.after(50, mainloop)

and then running it right before PumpMessages, but neither of these solutions worked. It also doesn't seem like you can run PumpMessages or root.mainloop in a thread, though I could just not be doing it right. If this is not possible with Tkinter, is there an alternate Python GUI I could use that would make it possible?

1 Answer 1

0

You don't need to create a function to use mainloop() so just simply place the mainloop() at the bottom of your code. If you want a delay on it, use root.after(milliseconds, function)

Also, remember to put mainloop() before PumpMessages()

e.g.

def mainloopfunction():
    mainloop()

root.after(5000, mainloopfunction)

Hope I could help!

Sign up to request clarification or add additional context in comments.

6 Comments

Unfortunately, this doesn't work. If I put mainloop() at the end, it is never reached because the code never progresses past PumpMessages(). If I use after as displayed here, the interface becomes unresponsive as soon as it starts the mainloop. EDIT - actually, it doesn't appear that it ever reaches the mainloop, so PumpMessages() must be preventing after from executing it's function.
Have you tried running mainloop before PumpMessages()
Huh. That does seem to work, though the code never reaches PumpMessages(), so that must not be a necessary part of the keylogger. This doesn't exactly answer the question, but I guess it works.
After some testing, it appears that PumpMessages (which lacks almost any documentation online) is necessary only if you are not using mainloop. Basically, you need some sort of event listener running to pick up keystrokes, but it doesn't need to be PumpMessages.
So is that your problem solved or is there still something wrong?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.