Как запустить pynput.Listener одновременно с tkinter.Tk (). Mainloop () - PullRequest
0 голосов
/ 03 июля 2019

Я учитель.Я преподаю математику, но поскольку образование сталкивается с кризисом кадровых ресурсов, у меня есть некоторые дополнительные обязанности.Я учу детей немного программированию, они хорошо учатся.Теперь я хотел бы сделать с ними игру-змею, но у меня проблема с достижением многопоточности в моем приложении с графическим интерфейсом.

Я нашел похожие случаи, но не нашел решения.Как здесь: Использование клавиатуры для перемещения персонажа в лабиринте и здесь: Tkinter.Tk () и многопоточность

def on_press(key):
    print('{0} pressed'.format(key))

def on_release(key):
    if key == Key.esc:
        return False

with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

root = Tk()
root.mainloop()

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

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Listener является потоком, поэтому, если вы присоединитесь к нему, ваш основной поток будет ждать до конца, чтобы продолжить обработку.

Вы можете просто создать объект Listener без оператора with, и он будет выполняться вдоль основного потока (пока функция обратного вызова не вернет False)

0 голосов
/ 03 июля 2019

Вам не нужно Listener в tkinter.Вы можете использовать root.bind для назначения функции нажатию и отпусканию событий.

from tkinter import *

def on_press(event):
    #print('on_press: event:', event)
    #print('on_press: keysym:', event.keysym)
    print('{0} pressed'.format(event.keysym))

def on_release(event):
    #print('on_release: event:', event)
    #print('on_release: keysym:', event.keysym)
    print('{0} release'.format(event.keysym))

    if event.keysym == 'Escape':
         print("exist program")
         root.destroy()

root = Tk()

root.bind('<KeyPress>', on_press)
root.bind('<KeyRelease>', on_release)

root.mainloop()

Вы также можете назначить функцию для каждой клавиши отдельно

from tkinter import *

def on_escape(event):
    print("exist program")
    root.destroy()

root = Tk()

root.bind('<Escape>', on_escape)
#root.bind('<KeyPress-Escape>', on_press_escape)
#root.bind('<KeyRelease-Escape>', on_release_escape)

root.mainloop()

Ключи в документации Tcl / Tk: https://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm

...