Ich habe eine Tkinter GUI-Anwendung, die ich auf einer Schaltfläche drücken muss ausblenden. Ich kann nicht davon ausgehen, dass die Anwendung den Fokus haben wird, also habe ich pyHook, Keylogger-Stil implementiert. Wenn ich jedoch remove() von einer Funktion, die von pyHook gestartet wurde, aufrufen, hängt das Fenster und ich muss es zwangsweise schließen.Tkinter zurückziehen Oddness mit pyHook
Um zu testen, fügte ich eine Schaltfläche in der GUI selbst, um genau die gleiche Funktion aufzurufen, und es funktioniert gut. Was ist los? 'Verstecken' druckt beide Male, so dass ich weiß, dass es wirklich an dem Aufruf von remove() hängt.
Unten finden Sie ein minimales vollständiges nachprüfbares Beispiel zu zeigen, was ich meine:
from Tkinter import *
import threading
import time
try:
import pythoncom, pyHook
except ImportError:
print 'The pythoncom or pyHook modules are not installed.'
# main gui box
class TestingGUI:
def __init__(self, root):
self.root = root
self.root.title('TestingGUI')
self.button = Button(root, text="Withdraw", command=self.Hide) # works fine
self.button.grid()
def ButtonPress(self, scancode, ascii):
if scancode == 82: # kp_0
self.Hide() # hangs
def Hide(self):
print 'hiding'
self.root.withdraw()
time.sleep(2)
self.root.deiconify()
root = Tk()
TestingGUI = TestingGUI(root)
def keypressed(event):
key = chr(event.Ascii)
# have to start thread in order to return True as required by pyHook
threading.Thread(target=TestingGUI.ButtonPress, args=(event.ScanCode,key)).start()
return True
def startlogger():
obj = pyHook.HookManager()
obj.KeyDown = keypressed
obj.HookKeyboard()
pythoncom.PumpMessages()
# need this to run at the same time
logger = threading.Thread(target=startlogger)
# quits on main program exit
logger.daemon = True
logger.start()
# main gui loop
root.mainloop()
Threads und tkinter nicht gut mischen, siehe zum Beispiel http://StackOverflow.com/a/10556698/5781248 –
Ich weiß, dass es Probleme gibt, aber Sie werden feststellen, dass 'mainloop()' * ist * läuft im Hauptthread. Außerdem funktioniert dieses ganze Projekt gut in Linux, wenn ich Xs Datensatzkontext verwende. Dies ist definitiv ein pyHook-Problem. – heidi
'threading.Thread (target = TestingGUI.ButtonPress, args = (event.ScanCode, key)). Start()' in der Funktion 'keypressed' sieht aus wie es ein tk-Widget verursacht, das außerhalb des Hauptthreads ie' self.root aufgerufen wird. remove() 'und' self.root.deiconify() 'Aufrufe. –