У меня тут двойной вопрос, когда я пытался связать с TKinter. Но я готов использовать PYNPUT, если это поможет мне быстрее заставить мои функции работать.
Я изучал этот Pyhon - «Необработанное исключение в обратном вызове слушателя» с помощью pynput , и это помогло некоторым, но я не прошел мимо ошибки.
С помощью PYNPUT я могу захватить ключи и перейти к функции, но затем он переходит в threading.py и __init__py и взрывается следующим образом:
E:\Python\Python36\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition with Anaconda plugin 2019.2.4\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 10281 --file E:/GitHub/NealWalters/game/game.py
pydev debugger: process 32480 is connecting
Connected to pydev debugger (build 192.7142.79)
verify playerCard1=Queen of Clubs verify playerCard2=Six of Hearts
on_press: key='p'
calling self.play()
Unhandled exception in listener callback
Traceback (most recent call last):
File "E:\Python\Python36\lib\site-packages\pynput\_util\__init__.py", line 162, in inner
return f(self, *args, **kwargs)
File "E:\Python\Python36\lib\site-packages\pynput\keyboard\_win32.py", line 280, in _process
self.on_press(key)
File "E:\Python\Python36\lib\site-packages\pynput\_util\__init__.py", line 78, in inner
if f(*args) is False:
File "E:/GitHub/NealWalters/game/game.py", line 117, in on_press
self.play()
File "E:/GitHub/NealWalters/game/game.py", line 177, in play
self.message1.setMsg() # clear
File "E:\GitHub\NealWalters\game\textboxes.py", line 56, in setMsg
self.msgLine.undraw( )
File "E:\GitHub\NealWalters\game\graphics.py", line 68, in undraw
self.canvas.delete(self.id)
File "E:\Python\Python36\lib\tkinter\__init__.py", line 2508, in delete
self.tk.call((self._w, 'delete') + args)
RuntimeError: main thread is not in main loop
Это на самом деле умирает на self.canvas.delete (self.id) ниже. Когда PYNPUT / listener не запущен, все работает нормально, если я нажимаю на кнопки.
def undraw(self):
if not self.canvas: return
self.canvas.delete(self.id)
self.canvas = None
self.id = None
В настоящее время в этой игре нет никаких действий пользователя, кроме нажатия кнопок. Я хочу зафиксировать нажатия клавиш и вызвать тот же метод, который был бы вызван, если бы пользователь нажал кнопку.
С включенным отладчиком я вижу, что получаю свой ключ, затем вызываю функцию "play". Он никогда не попадает на вторую строку функции воспроизведения.
Это игра, которую я получил с GitHub, и она адаптируется к моим предпочтениям. Так что я стараюсь как можно меньше структурно его изменить.
Основная программа выглядит примерно так:
def main():
# first number is width, second is height
screenWidth = 800
screenHeight = 500
mainWindow = GraphWin("Game", screenWidth, screenHeight)
game = game(mainWindow)
listener = keyboard.Listener(on_press=game.on_press)
listener.start()
game.go()
mainWindow.close()
if __name__ == '__main__':
main()
Я добавил тестовую функцию в класс Game, и в настоящее время она не запускается.
def on_press(self, key):
print("on_press: key=" + str(key))
if key == keyboard.KeyCode(char='p'):
print("calling self.play()")
self.play()
def play( self , event=''):
""" User pressed the Play button. """
self.message1.setMsg() #
self.message2.setMsg() # <--- I never reach here!
сообщения 1 и 2 определены в конструкторе игры:
self.message1 = MessageBox(win, Point(xmax*0.55, m1y))
self.message2 = MessageBox(win, Point(xmax*0.55, m2y))
И, наконец, код MessageBox находится в textboxes.py:
class MessageBox:
"Just a Text area to display a message in"
def __init__( self, win, center ):
self.win = win
self.center = center
self.set = False
def setMsg( self, msg=None ):
"""Show a message, call with no parameters to
remove the score from the screen"""
if msg:
self.msgLine = Text( self.center, msg )
self.msgLine.setFill("gold")
#self.msgLine.setSize( 12 )
#self.msgLine.setStyle( "bold" )
self.msgLine.draw( self.win )
self.set = True
elif self.set:
self.msgLine.undraw( )
self.set = False
def setColor( self, color ):
"Change the text color"
self.msgLine.setFill( color )
#self.msgLine.setSize( 13 )