简体   繁体   English

Tkinter框架无法识别按键

[英]Tkinter Frame Not Recognizing Keypresses

This question is NOT a duplicate of this question: Why doesn't the .bind() method work with a frame widget in Tkinter? 这个问题不是这个问题的重复: 为什么.bind()方法不能与Tkinter中的框架小部件一起使用?

As you can see, I set the focus to the current frame in my game_frame() method. 如您所见,我在game_frame()方法中将焦点设置为当前帧。

I'm writing a Chip-8 emulator in Python and using Tkinter for my GUI. 我正在用Python编写Chip-8模拟器,并将Tkinter用于我的GUI。 The emulator is running, but I can't get Tkinter to recognize keypresses. 模拟器正在运行,但是我无法让Tkinter识别按键。 Here is my code: 这是我的代码:

def game_frame(self):
    self.screen = Frame(self.emulator_frame, width=640, height=320)
    self.screen.focus_set()
    self.canvas = Canvas(self.screen, width=640, height=320, bg="black")
    self._root.bind("<KeyPress-A>", self.hello)
    for key in self.CPU.KEY_MAP.keys():
        print(key)
        self.screen.bind(key, self.hello)
    self.screen.pack()
    self.canvas.pack()

def hello(self, event):
    if event.keysym in self.CPU.KEY_MAP.keys():
        self.CPU.keypad[self.CPU.KEY_MAP[event.keysym]] = 1
        self.CPU.key_pressed = True
        self.CPU.pc += 2
    sys.exit()

def run_game(self, event):
    self.game_frame()
    self.CPU.load_rom("TANK")
    while True:
        self._root.update()
        self.after(0, self.CPU.emulate_cycle)

Could you please help me figure out what's going wrong? 您能帮我找出问题所在吗? I think it might have something to do with my game loop interfering with the key bindings, but I'm not sure. 我认为这可能与我的游戏循环干扰按键绑定有关,但我不确定。 The hello method never gets called when I run the game because the program continues to run in an infinite loop and never exits, regardless of what key is pressed. 在我运行游戏时,永远不会调用hello方法,因为该程序将继续在无限循环中运行,并且无论按下什么键,都不会退出。 Thank you! 谢谢!

The problem could be due to two things. 问题可能是由于两件事。 Without seeing all your code it's impossible to say for sure. 如果没有看到所有代码,就无法确定。

For one, you are binding to a capital "A" rather than a lowercase "a" -- have you testing that the binding works or not when you press a capital A? 例如,您要绑定到大写字母“ A”,而不是小写字母“ a”-您是否在按大写字母A时测试了绑定是否起作用?

Also, you are using after and update incorrectly. 此外,您正在使用after并且错误地update You may be starving the event loop, preventing it from processing key presses. 您可能会饿死事件循环,从而阻止其处理按键操作。 The right way to run a function periodically is to have a function that (re)schedules itself. 定期运行一个函数的正确方法是拥有一个(重新)计划自身的函数。

class CPU_Class():
    ...
    def run_cycle(self):
        self.emulate_cycle()
        self._root.after(1, self.run_cycle)

Two things to note: 有两件事要注意:

  1. don't use after(0, ...) -- you need to give tkinter at least a ms or so to process other events. 不要使用after(0, ...) -您需要给tkinter至少一个ms左右的时间来处理其他事件。
  2. the run_cycle function is responsible for running one cycle, and then scheduling the next cycle to run in the future. run_cycle函数负责运行一个周期,然后安排下一个周期以在将来运行。

Once you do that, you no longer need your while loop. 一旦这样做,就不再需要while循环。 You can simply call run_cycle once, and that will start the CPU running. 您只需调用一次run_cycle即可开始CPU运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM