PYTHON TKINTER 将焦点设置到下一行而不是下一个小部件

PYTHON TKINTER set focus to next row instead of next widget

我在网格中有框架,其中有小部件。这些框架被销毁并创建新的框架。我想用键盘在这些之间移动。 问题:每次有一个新框架时,它都会被 focus next 视为最后一个框架。 问题:如何改为按行聚焦。

    def create_a_line(i):
        p=1 #sometimes there are more widgets in a row, but here just take 1
        bframe = Frame(root)
        bframe.grid(row=i, column=0)
        m = Button(bframe, text=h[i], , takefocus = 1)
        m.bind('<Right>', lambda event, i=i: focus_next(i, p))
        m.bind('<Double-1>', lambda event, i=i: double_click_text(i)) 
        m.grid(row=0, column=p)
        
    def double_click_text(i)
        for widget in root.grid_slaves(row=i):
           widget.destroy()
        #change h[i] i.e. text of the button to something else
        create_a_line(i) #with new text but same row
    
    def focus_next(i, p):  #this is what im struggling with
          event.widget.tk_focusNext().focus() #this is how it is right now
#this is how i would like it to be, but no idea how:
#        if in row=i other widgets with column >p: sometimes there will be more than one widget in a row
#          event.widget.tk_focusNext().focus()
#        else:
#          set_focus(first widget in grid row=i+1)
    
    for i in range(0, 5) #the end number is based on number of lines f.e. 5
        create_a_line(i)

由于缺乏更好的解决方案,这就是我根据评论解决它的方法:

labellsall=[]
h = [] 
def ad_to_labelsall(i,  p , z):
    ag = ["#"+str(i)+"i@", p, z]  #made i more complicated so I dont find random numbers
    labelsall.append(ag)

def del_from_labelsall(i):
    agi = ("#"+str(i)+"i@")
    ngip = [e for e, s in enumerate(labelsall) if agi in s]
    for index in sorted(ngip, reverse=True):
       del labelsall[index]

def create_a_line(i):
    p=1 
    bframe = Frame(root)
    bframe.grid(row=i, column=0)
    m = Button(bframe, text=h[i], , takefocus = 1)
    m.bind('<Right>', lambda event, i=i: focus_next(event, i))
    m.bind('<Double-1>', lambda event, i=i: double_click_text(i)) 
    m.grid(row=0, column=p)
    ad_to_labelsall(i,  p , z=m)

def double_click_text(i)
    del_from_labelsall(i)
    for widget in root.grid_slaves(row=i):
       widget.destroy()
    #some other code change h[i] i.e. text of the button to something else
    create_a_line(i) #with new text but same row

def focus_next(event, i):
    grid_info = event.widget.grid_info()
    p = grid_info["column"]
    agi = ("#"+str(i)+"i@") 
    ngip = [e for e, s in enumerate(labelsall) if agi in s]
    for index in sorted(ngip):
       the_row = labelsall[index]
       if int(the_row[1]) > p:   #check if other widget is in the row before jumping to next row
          the_row[2].focus_set() #if other widget found focus it
          return("break")
       else:
          pass
    i_next = i+1
    try:
      agi_next = ("#"+str(i_next)+"i@")
      ngip_next = [e for e, s in enumerate(labelsall) if agi_next in s]
      labelsall[ngip_next[0]][2].focus_set()
    except:
      agi_next = ("#"+str(i_next+1)+"i@") #sometimes there are rows with no widgets, so just try the next one
      ngip_next = [e for e, s in enumerate(labelsall) if agi_next in s]
      labelsall[ngip_next[0]][2].focus_set()
   return("break")