Python Forum
How to move in entries using the arrow keys by applying the bind and focus?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to move in entries using the arrow keys by applying the bind and focus?
#1
I have some entries in tkinter. currently, I need to move the cursor to each entry and click it to select it. I am looking to do this using the arrow keys. I saw we can use bind_class to select all the Entry widgets, however, I don't know how to work around focus() to move Up/Down/Left/Right in entries.

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()
Reply
#2
You want left and right arrow keys to move the cursor in the entry box. You can bind up and down arrows to move you up and down a list of widgets, but tab and shift tab already do this without having to write additional code.

If you still want to do the arrow thing:
import tkinter as tk
    
class SampleApp(tk.Tk):
    def __init__(self):
        super().__init__()
 
        self.entry_list = []
        for index in range(16):
            entry = tk.Entry(self)
            entry.grid(row=index // 4, column=index % 4)
            for key in ("<Up>", "<Down>", "<Left>", "<Right>"):
                entry.bind(key, lambda event, i=index: self.next_widget(event, i))
            self.entry_list.append(entry)
 
    def next_widget(self, index, x, y):
        r = (index // 4 + y) % 4
        c = (index % 4 + x) % 4
        self.entry_list[r * 4 + c].focus_set()
 
SampleApp().mainloop()
Reply
#3
Thanks for your reply. Actually, tab or shift only selects the next entry. What will happen once we want to go backward or in any direction? Sorry, your current code raises an error.
Error:
entry.bind(key, lambda event, i=index: self.next_widget(event, i)) TypeError: next_widget() missing 1 required positional argument: 'y'
Yoriz write Apr-05-2022, 11:54 AM:
Please post errors (in their entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#4
Tab goes to the next entry, shift+tab the previous.

Not sure what happened to the post. At first I wrote the code one way, then thought of a better way. That code in the post was a mashup of both versions. Sorry about that.

This is the code I meant to post, but with an edit. The Shift+Tab comment made me realize you can use Shift+Arrow to navigate and still use left/right arrow keys inside the entry. Serendipity!
import tkinter as tk
    
class SampleApp(tk.Tk):
    def __init__(self):
        super().__init__()
 
        self.entry_list = []
        for index in range(16):
            entry = tk.Entry(self)
            entry.grid(row=index // 4, column=index % 4)
            for key in ("<Shift-Up>", "<Shift-Down>", "<Shift-Left>", "<Shift-Right>"):
                entry.bind(key, lambda event, i=index: self.next_widget(event, i))
            self.entry_list.append(entry)
 
    def next_widget(self, event, index):
        print(event)
        r = index // 4
        c = index % 4
        if event.keysym == "Left":
            c = (c-1) % 4
        elif event.keysym == "Right":
            c = (c+1) % 4
        elif event.keysym == "Up":
            r = (r-1) % 4
        elif event.keysym == "Down":
            r = (r+1) % 4
        entry = self.entry_list[r * 4 + c]
        entry.focus_set()  # These three lines may be what you were looking for.  Take focus
        entry.select_range(0, 'end')  # Select contents
        entry.icursor('end')  # Place cursor

SampleApp().mainloop()
pymn likes this post
Reply
#5
Thanks a lot. That is a clever way.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Python Turtle. Pointers of the "arrow" direction of the vector. roomONmoon 1 689 Dec-09-2023, 11:49 PM
Last Post: deanhystad
  [Tkinter] Open tkinter colorchooser at toplevel (so I can select/focus on either window) tabreturn 4 1,922 Jul-06-2022, 01:03 PM
Last Post: deanhystad
  [Tkinter] bind menator01 1 1,265 Apr-15-2022, 08:47 PM
Last Post: menator01
  [Tkinter] bind lambda keypress counter knoxvilles_joker 15 7,815 Apr-19-2021, 01:56 AM
Last Post: knoxvilles_joker
  [Tkinter] arrow key selection for menu knoxvilles_joker 6 5,882 Apr-19-2021, 12:04 AM
Last Post: knoxvilles_joker
  [Tkinter] Mouse click without use bind ATARI_LIVE 8 7,476 Oct-23-2020, 10:41 PM
Last Post: ATARI_LIVE
  How to disable focus on Frame in Tkinter? szafranji 1 3,032 May-13-2020, 10:45 PM
Last Post: DT2000
  QComboBox doesn't display selection as long as it has not lost the focus Meaulnes 3 3,254 May-07-2020, 03:42 PM
Last Post: Meaulnes
  [Kivy] AttributeError: 'NoneType' object has no attribute 'bind' faszination_92 2 6,282 Apr-12-2020, 07:01 PM
Last Post: Larz60+
  [WxPython] Bind error PeterLinux 1 2,258 Apr-06-2020, 03:07 AM
Last Post: joe_momma

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020