привязка клавиш не работает ткинтер - PullRequest
0 голосов
/ 20 мая 2018

Этот код должен заставить танк двигаться влево, когда вы нажимаете стрелку влево, но он не работает:

from tkinter import *
from tkinter.constants import LEFT
root = Tk()
c = Canvas(root, width=400, height=400)
tank = c.create_rectangle(200,200,250, 250, outline = 'dark green', 
fill='dark green')
c.pack()

class tank:
    def move_left(self):
        c.move(tank, -200, 0)
c.bind('<Left>', tank.move_left(tank))
c.focus_set()            
root.mainloop()            

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Вот версия, основанная на недавно удаленном ответе Маски Реблохона.Если он отправит свою собственную исправленную версию, я удалю эту.

import tkinter as tk

class Battlefield(tk.Canvas):
    def __init__(self, master):
        self.master = master
        super().__init__(root, width=400, height=400)
        self.pack()

        tank = Tank(self)

        self.bind('<Left>', tank.move)
        self.bind('<Right>', tank.move)
        self.bind('<Up>', tank.move)
        self.bind('<Down>', tank.move)

class Tank:
    OFFSETS = {'Left': (-1, 0), 'Right': (1, 0), 'Up': (0, -1), 'Down': (0, 1)}

    def __init__(self, canvas):
        self.canvas = canvas
        self.id = self.canvas.create_rectangle(200, 200, 250, 250, outline='dark green', fill='dark green')

    def move(self, event):
        self.canvas.move(self.id, *Tank.OFFSETS[event.keysym])

if __name__ == '__main__':
    root = tk.Tk()
    battlefield = Battlefield(root)
    battlefield.focus_set()
    root.mainloop()

Конечно, вам не нужен класс для чего-то такого простого.

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400)
canvas.pack()
tank = canvas.create_rectangle(200, 200, 250, 250, outline='dark green', fill='dark green')

OFFSETS = {'Left': (-1, 0), 'Right': (1, 0), 'Up': (0, -1), 'Down': (0, 1)}

def move(event):
    canvas.move(tank, *OFFSETS[event.keysym])

canvas.bind('<Left>', move)
canvas.bind('<Right>', move)
canvas.bind('<Up>', move)
canvas.bind('<Down>', move)
canvas.focus_set()

root.mainloop()
0 голосов
/ 20 мая 2018

Здесь две проблемы:

  • В c.bind('<Left>', tank.move_left(tank)) вы фактически передаете возвращаемое значение tank.move_left второму аргументу c.bind;и это возвращаемое значение равно None.

  • Вы определяете переменную с именем tank, а затем перезаписываете эту переменную классом с именем tank.

Устранение обеих проблем:

from tkinter import *
from tkinter.constants import LEFT
root = Tk()
c = Canvas(root, width=400, height=400)
tank = c.create_rectangle(200,200,250, 250, outline = 'dark green', fill='dark green')
c.pack()

class Tank: # Pascal case is the recommended naming convention for classes
    def move_left(self):
        c.move(tank, -200, 0)

c.bind('<Left>', Tank.move_left) # Passing the function and not its return value as 2nd argument
c.focus_set()            
root.mainloop()     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...