如何通过应用绑定和焦点使用箭头键移动条目?

How to move in entries using the arrow keys by applying the bind and focus?

我在 tkinter 中有一些条目。目前,我需要将光标移动到每个条目并单击它以 select 它。我希望使用 arrow keys 来执行此操作。我看到我们可以使用 bind_class 到 select 所有条目小部件;但是,我不知道如何解决 focus() 以在条目中移动 Up/Down/Left/Right。这是我的代码:

import tkinter as tk


class Data:
    def __init__(self):
        self.x = tk.IntVar()


class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.minsize(700, 700)
        container = tk.Frame(self)
        container.pack()

        self.data = Data()

        self.frames = {}
        for F in (PageOne, ):
            frame = F(container, self.data)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

    def show_frame(self, c):
        frame = self.frames[c]
        frame.tkraise()


class PageOne(tk.Frame):
    def __init__(self, parent, data):
        super().__init__(parent)
        self.data = data

        self.row_list = []
        for i in range(4):
            self.entry_list = []
            for j in range(4):
                self.A = tk.Entry(self)
                self.A.grid(row=i, column=j)
                self.entry_list.append(self.A)
            self.row_list.append(self.entry_list)

        self.bind_class("Entry", "<Down>", self.next_widget)
        self.bind_class("Entry", "<Up>", self.next_widget)
        self.bind_class("Entry", "<Right>", self.next_widget)
        self.bind_class("Entry", "<Left>", self.next_widget)

    def next_widget(self, event):
        event.widget.focus()
        return ("break")

app = SampleApp()
app.mainloop()

您可以使用 tk_focusPrev()tk_focusNext() 获取密钥 LeftRight 所需的 Entry

对于键UpDown,您可以使用grid_size()获取网格的列数和行数,并在Entry上使用grid_info()获取网格信息,即 rowcolumn,其中 Entry 是。然后确定哪个Entry应该成为焦点:

def next_widget(self, event):
    entry = event.widget
    if event.keysym in ('Up', 'Down'):
        cols, rows = entry.master.grid_size()
        info = entry.grid_info()
        if event.keysym == 'Up':
            row = (info['row'] if info['row'] > 0 else rows) - 1
        else:
            row = (info['row'] + 1) % rows
        self.row_list[row][info['column']].focus()
    elif event.keysym == 'Left':
        entry.tk_focusPrev().focus()
    elif event.keysym == 'Right':
        entry.tk_focusNext().focus()
    return "break"