Tkinter 框架无法识别按键
Tkinter Frame Not Recognizing Keypresses
这个问题不是这个问题的重复:Why doesn't the .bind() method work with a frame widget in Tkinter?
如您所见,我在 game_frame() 方法中将焦点设置到当前帧。
我正在 Python 中编写一个 Chip-8 模拟器,并将 Tkinter 用于我的 GUI。模拟器是 运行ning,但我无法让 Tkinter 识别按键。这是我的代码:
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)
你能帮我找出问题所在吗?我认为这可能与我的游戏循环干扰键绑定有关,但我不确定。当我 运行 游戏时,hello 方法永远不会被调用,因为程序在无限循环中继续 运行 并且永远不会退出,无论按下什么键。谢谢!
问题可能是由两件事引起的。没有看到你所有的代码,就不可能肯定地说。
首先,您绑定的是大写字母 "A" 而不是小写字母 "a" -- 当您按下大写字母 A 时,您是否测试过绑定是否有效?
此外,您使用的 after
和 update
不正确。您可能使事件循环处于饥饿状态,从而阻止它处理按键操作。定期 运行 函数的正确方法是拥有一个(重新)安排自身的函数。
class CPU_Class():
...
def run_cycle(self):
self.emulate_cycle()
self._root.after(1, self.run_cycle)
需要注意两点:
- 不要使用
after(0, ...)
-- 你需要给 tkinter 至少 1 毫秒左右的时间来处理其他事件。
- run_cycle函数负责运行ning一个周期,然后将下一个周期调度到运行以后。
一旦你这样做了,你就不再需要你的 while
循环了。您只需调用 run_cycle
一次,即可启动 CPU 运行ning.
这个问题不是这个问题的重复:Why doesn't the .bind() method work with a frame widget in Tkinter?
如您所见,我在 game_frame() 方法中将焦点设置到当前帧。
我正在 Python 中编写一个 Chip-8 模拟器,并将 Tkinter 用于我的 GUI。模拟器是 运行ning,但我无法让 Tkinter 识别按键。这是我的代码:
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)
你能帮我找出问题所在吗?我认为这可能与我的游戏循环干扰键绑定有关,但我不确定。当我 运行 游戏时,hello 方法永远不会被调用,因为程序在无限循环中继续 运行 并且永远不会退出,无论按下什么键。谢谢!
问题可能是由两件事引起的。没有看到你所有的代码,就不可能肯定地说。
首先,您绑定的是大写字母 "A" 而不是小写字母 "a" -- 当您按下大写字母 A 时,您是否测试过绑定是否有效?
此外,您使用的 after
和 update
不正确。您可能使事件循环处于饥饿状态,从而阻止它处理按键操作。定期 运行 函数的正确方法是拥有一个(重新)安排自身的函数。
class CPU_Class():
...
def run_cycle(self):
self.emulate_cycle()
self._root.after(1, self.run_cycle)
需要注意两点:
- 不要使用
after(0, ...)
-- 你需要给 tkinter 至少 1 毫秒左右的时间来处理其他事件。 - run_cycle函数负责运行ning一个周期,然后将下一个周期调度到运行以后。
一旦你这样做了,你就不再需要你的 while
循环了。您只需调用 run_cycle
一次,即可启动 CPU 运行ning.