Ввод с клавиатуры без повторной задержки

#python #tkinter

#питон #tkinter

Вопрос:

Эй, я пытаюсь решить проблему, в которой персонаж перемещается по 2D-плоскости с помощью клавиш WASD. Однако, когда я удерживаю кнопку, код записывается один раз, затем делает задержку, а затем пишет без остановки.

Как устранить эту задержку? Я видел некоторые решения, использующие after() с canvas (), но не уверен, как применить это к метке() с помощью «text=».

Спасибо за любые идеи!

 from tkinter import * import tkinter as tk  coordinates = {  "x1y1": "", "x2y1": "", "x3y1": "", "x4y1": "", "x5y1": "", "x6y1": "", "x7y1": "", "x8y1": "", "x9y1": "",  "x1y2": "", "x2y2": "", "x3y2": "", "x4y2": "", "x5y2": "", "x6y2": "", "x7y2": "", "x8y2": "", "x9y2": "",  "x1y3": "", "x2y3": "", "x3y3": "", "x4y3": "", "x5y3": "", "x6y3": "", "x7y3": "", "x8y3": "", "x9y3": "",  "x1y4": "", "x2y4": "", "x3y4": "", "x4y4": "", "x5y4": "", "x6y4": "", "x7y4": "", "x8y4": "", "x9y4": "",  "x1y5": "", "x2y5": "", "x3y5": "", "x4y5": "", "x5y5": "", "x6y5": "", "x7y5": "", "x8y5": "", "x9y5": "",  "x1y6": "", "x2y6": "", "x3y6": "", "x4y6": "", "x5y6": "", "x6y6": "", "x7y6": "", "x8y6": "", "x9y6": "",  "x1y7": "", "x2y7": "", "x3y7": "", "x4y7": "", "x5y7": "", "x6y7": "", "x7y7": "", "x8y7": "", "x9y7": "",  "x1y8": "", "x2y8": "", "x3y8": "", "x4y8": "", "x5y8": "", "x6y8": "", "x7y8": "", "x8y8": "", "x9y8": "",  "x1y9": "", "x2y9": "", "x3y9": "", "x4y9": "", "x5y9": "", "x6y9": "", "x7y9": "", "x8y9": "", "x9y9": "",   }   #Player starting position player_x = 5 player_y = 5   #Onpress update player X/Y positions and make sure they don't exceed coordinate system def keypress_w(event):  global player_y  player_y -= 1  if player_y lt; 1:  player_y  = 1  update_world()  def keypress_a(event):  global player_x  player_x -= 1  if player_x lt; 1:  player_x  = 1  update_world()  def keypress_d(event):  global player_x  player_x  = 1  if player_x gt; 9:  player_x -= 1  update_world()  def keypress_s(event):  global player_y  player_y  = 1  if player_y gt; 9:  player_y -= 1  update_world()   def keypress_esc(event):  sys.exit()  def update_world():  #Create string with player coordinates and input into dictionary  player_xy = "x", player_x, "y", player_y  player_coord = ''.join(map(str, player_xy))   #Update previous player tile to map tile  coord_keys = coordinates.keys()  for coords in coord_keys:  if coords == player_coord:  coordinates[player_coord] = '€'  else:  coordinates[coords] = ' '   #Print map  width = 9  coord_values = coordinates.values()  i=0  world=""   for item in coord_values:  world = world   item   " "  i  = 1  if i % width == 0:  world = world[:-1]   'n'   world = world[:-1]   #refresh the label that displays the world  world_label.place(x=220,y=100)  world_label.configure(font=("Courier", 24), text=world, bg="white")    root = Tk() #Create window  world_label = Label() #Create World Label widget world_label.pack() update_world() #Function update_world   #Sends pressed key values to functions keypress_"x" root.bind("lt;wgt;", keypress_w) root.bind("lt;agt;", keypress_a) root.bind("lt;sgt;", keypress_s) root.bind("lt;dgt;", keypress_d) root.bind("lt;Escapegt;", keypress_esc)     root.geometry("800x600") #Size of window  root.title('Game 0.1') #Title of window  root.mainloop() #  

Комментарии:

1. Это конфигурация системы на клавиатурном устройстве.

Ответ №1:

Вы можете использовать метод таймера root.after(delay, func) для запуска функции для имитации повтора клавиатуры.

Новый демо-код для вас. Он работает при одновременном нажатии обеих клавиш.

 from time import sleep import tkinter as tk  class Root(tk.Tk):   def __init__(self, title, width, height):  super().__init__()  self.title(title)  self.width = width  self.height = height  self.canvas = tk.Canvas(self, width=width, height=height, bg='green')  self.canvas.pack()  self.geometry(f'{width}x{height}')  self.radius = 20  self.delay = 20  self.step = 5  self.x = width // 2  self.y = height // 2  self.press_left = False  self.press_right = False  self.press_up = False  self.press_down = False  self.ball = None  self.draw_ball()  self.binding()   def draw_ball(self):  if self.ball:  self.canvas.delete(self.ball)  self.ball = self.canvas.create_oval(self.x - self.radius, self.y - self.radius,  self.x   self.radius, self.y   self.radius, fill='white')  self.canvas.update()   def binding(self):  self.bind("lt;KeyPress-agt;", self.left_down)  self.bind("lt;KeyPress-dgt;", self.right_down)  self.bind("lt;KeyPress-wgt;", self.up_down)  self.bind("lt;KeyPress-sgt;", self.down_down)  self.bind("lt;KeyRelease-agt;", self.left_up)  self.bind("lt;KeyRelease-dgt;", self.right_up)  self.bind("lt;KeyRelease-wgt;", self.up_up)  self.bind("lt;KeyRelease-sgt;", self.down_up)  self.bind("lt;Escapegt;", self.escape)   def left_down(self, event):  def left():  if self.press_left:  if self.x gt;= self.radius   self.step:  self.x -= self.step  self.draw_ball()  self.after(self.delay, left)  else:  self.bind("lt;KeyPress-agt;", self.left_down)  self.unbind("lt;KeyPress-agt;")  self.press_left = True  left()   def left_up(self, event):  self.press_left = False   def right_down(self, event):  def right():  if self.press_right:  if self.x lt;= self.width - self.radius - self.step:  self.x  = self.step  self.draw_ball()  self.after(self.delay, right)  else:  self.bind("lt;KeyPress-dgt;", self.right_down)  self.unbind("lt;KeyPress-dgt;")  self.press_right = True  right()   def right_up(self, event):  self.press_right = False   def up_down(self, event):  def up():  if self.press_up:  if self.y gt;= self.radius   self.step:  self.y -= self.step  self.draw_ball()  self.after(self.delay, up)  else:  self.bind("lt;KeyPress-wgt;", self.up_down)  self.unbind("lt;KeyPress-wgt;")  self.press_up = True  up()   def up_up(self, event):  self.press_up = False   def down_down(self, event):  def down():  if self.press_down:  if self.y lt;= self.height - self.radius - self.step:  self.y  = self.step  self.draw_ball()  self.after(self.delay, down)  else:  self.bind("lt;KeyPress-sgt;", self.down_down)  self.unbind("lt;KeyPress-sgt;")  self.press_down = True  down()   def down_up(self, event):  self.press_down = False   def escape(self, event):  root.destroy()  root = Root("Game 0.1", 800, 600) root.mainloop()  

Комментарии:

1. Большое спасибо! Я поиграю с этим и попытаюсь внедрить в свой код!