2017-02-07 6 views
1

Я пытаюсь создать программу, которая прослушивает определенные комбинации клавиш, а затем отображает информацию пользователю в окне Tkinter. Для этого я использую кейлоггер, как так (упрощенный для данного примера):Сочетание основного окна Tkinter с другим прослушивателем событий

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() 

Как и ожидалось, окно выскакивает и показывает пользователю, какой ключ они нажатой. Тем не менее, я хотел бы объединить функциональные возможности для отображения других сообщений, взаимодействуя с окном Tkinter, например, нажав кнопку. Тем не менее, мне кажется, что для этого мне нужен mainloop Tkinter, и я не могу понять, как работать рядом с PumpMessages(), так как он также останавливает код, похожий на mainloop().

Я попытался запустить root.mainloop() в root.after(), и я попытался воссоздать root.mainloop так:

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

, а затем запустить его прямо перед PumpMessages, но ни одно из этих решений работал. Также не похоже, что вы можете запускать PumpMessages или root.mainloop в потоке, хотя я мог бы просто не делать этого правильно. Если это невозможно с Tkinter, есть ли альтернативный графический интерфейс Python, который я мог бы использовать, чтобы это стало возможным?

ответ

0

Вам не нужно создавать функцию для использования mainloop(), поэтому просто разместите mainloop() в нижней части кода. Если вы хотите задержку на нем, используйте root.after(milliseconds, function)

Кроме того, не забудьте положить mainloop() перед тем PumpMessages()

например

def mainloopfunction(): 
    mainloop() 

root.after(5000, mainloopfunction) 

Надеюсь, что смогу помочь!

+0

К сожалению, это не работает. Если я поставлю mainloop() в конце, это никогда не будет достигнуто, потому что код никогда не прогрессирует мимо PumpMessages(). Если я буду использовать, как показано здесь, интерфейс перестанет отвечать на запросы, как только он запустит mainloop. EDIT - на самом деле, кажется, что он никогда не достигает mainloop, поэтому PumpMessages() должен препятствовать выполнению его функции. –

+0

Вы пытались запустить mainloop перед PumpMessages() – Jake

+0

Huh. Это похоже на работу, хотя код никогда не достигает PumpMessages(), поэтому это не должно быть необходимой частью кейлоггера. Это точно не отвечает на вопрос, но я думаю, это работает. –