使用箭头键在框架中的按钮之间转移焦点?



我是新来的,我仍然与Python和tkinter保持着学习关系。对于我的第一个项目,我想建立一个复古游戏平台,从我自己的游戏集合开始,其 GUI 灵感来自 Netflix。到目前为止,它主要按预期工作:类别是从所有可用类别的列表中随机选择的,并在此基础上为类别中的每个游戏创建一个按钮。同样,这一切都工作正常。

问题:鉴于应用程序的性质,用户能够使用键盘或蓝牙控制器控制它非常重要。我可以将焦点设置为第一类中的第一个按钮,但是我现在无法使用箭头键将焦点从一个按钮实际移动到另一个按钮(左和右(,或从一个帧移动到另一个帧(向上和向下(。有没有一种简单的方法可以做到这一点?我已经搜索了几天,但得出的很少。

到目前为止我拥有的代码:(编辑以删除永恒的模块数据(

import tkinter as tk
c1i = []
c1b = []
tab_1 = ["a", "b", "c", "d", "e", "f"]
def populate():
for i in tab_1:
new_button = tk.Button(scrl_frame, bd = 0, command = None)
c1b.append(new_button)
new_button.pack(side = "left", padx = 5)

root = tk.Tk()
root.geometry ("800x1200")
main_frame = tk.Frame(root, height = 1200, width = 800)
main_canvas = tk.Canvas(main_frame, height = 1200, width = 800, bg = "black")
frame_1 = tk.Frame(main_canvas, height = 170, width = 800, bg = "black")
canvas_1 = tk.Canvas(frame_1, height = 170, width = 800, bg = "black")
scrl_frame = tk.Frame(canvas_1, bg = "black")
scrl = tk.Scrollbar(frame_1, orient = "horizontal", bg = "black", command = canvas_1.xview)
scrl_frame.bind("<Configure>", lambda k: canvas_1.configure(scrollregion = canvas_1.bbox("all")))
populate()
canvas_1.create_window((0, 0), window = scrl_frame, anchor = "w")
canvas_1.configure(xscrollcommand = scrl.set)

main_frame.pack(fill = "both", expand = True)
main_canvas.pack(fill = "both", expand = True)
frame_1.pack(fill = "x", side = "bottom")
canvas_1.pack(pady = 5, fill = "both", expand = True)
scrl.pack(fill = "x")
root.mainloop()

由于您已经有一个列表c1b来持有按钮,因此您需要声明一个全局变量来保存列表中的哪个按钮处于活动状态,并声明另一个全局变量来指向活动按钮列表:

index = 0
buttons = c1b
buttons[index].focus_set()  # focus on the first button

然后需要将<Left><Right>关键事件绑定到回调以切换焦点:

def switch_button(event):
global index
if event.keysym == 'Left':
if index > 0:
index -= 1
else:
if index < len(buttons)-1:
index += 1
buttons[index].focus_set()
root.bind('<Left>', switch_button)
root.bind('<Right>', switch_button)

还需要将<Up><Down>键事件绑定到回调以切换类别:

def switch_category(event):
global index
if event.keysym == 'Up':
print('select upper category')
# set 'buttons' to upper category
else:
print('select lower category')
# set 'buttons' to lower category
# focus on the first button in the category
index = 0
buttons[index].focus_set()
root.bind('<Up>', switch_category)
root.bind('<Down>', switch_category)

最新更新