3

How I can select all text like block using click+drug left mouse in Entry widget tkinter python.

 e1 = tk.Entry(bop, width = 50, font = "Helvetica 13")
 e1.grid(row=1,column=1, padx=15, pady=15)
 e1.bind_class("Entry","<Control-a>", select_all(e1))

here is the function of select_all():

def select_all(e):
   a = e.select_range(0,tk.END)
Cœur
  • 37,241
  • 25
  • 195
  • 267
halim hamadi
  • 99
  • 3
  • 12
  • `bind` expects function name (callback) - it means without `()` and arguments. You can create function without arguments which uses your function with argements, or use lambda: `bind( ..., lambda:select_all(e1))` – furas Jan 05 '17 at 06:10
  • BTW: `Entry` has method `get()` to get all text. – furas Jan 05 '17 at 06:32

2 Answers2

9

There was so many similar examples on SO

import tkinter as tk

def callback(event):
    print('e.get():', e.get())
    # or more universal
    print('event.widget.get():', event.widget.get())
    # select text after 50ms
    root.after(50, select_all, event.widget)

def select_all(widget):
    # select text
    widget.select_range(0, 'end')
    # move cursor to the end
    widget.icursor('end')

root = tk.Tk()

e = tk.Entry(root)
e.pack()
e.bind('<Control-a>', callback)

root.mainloop()

bind expects filename without () and arguments (callback). But also bind executes this function always with one argument event which gives access to entry which executed this function event.widget so you can use it with many different entries. And finally Entry has .get() to get all text.


EDIT:

Because after releasing keys <Control-a> selection is removed so I use after() to execute selection after 50ms. It selects all text (but it moves cursor to the beginning) and moves cursor to the end. (see code above)


EDIT:

Before I couldn't find correct combination with Release but it has to be <Control-KeyRelease-a> and now it doesn't need after()

import tkinter as tk

def callback(event):
    print('e.get():', e.get())
    # or more universal
    print('event.widget.get():', event.widget.get())

    # select text
    event.widget.select_range(0, 'end')
    # move cursor to the end
    event.widget.icursor('end')

root = tk.Tk()

e = tk.Entry(root)
e.pack()
e.bind('<Control-KeyRelease-a>', callback)

root.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • While your example is useful, it doesn't fully answer the question. Can you modify your `callback` method to actually do the "select all" functionality? – Bryan Oakley Jan 05 '17 at 12:44
  • I found `` and now it doesn't need `after()` – furas Jan 05 '17 at 19:30
  • Strange, at least in Tkinter with Python 2.7 I had to do `event.widget.icursor(0)`, that is the beginning, in order to make the selection to work. – rbaleksandar Aug 08 '17 at 21:21
6

furas' answer is great but still does not work as a perfect analogue of windows Ctrl+A behavior. The event only fires after releasing the 'a' key, but the event should fire on the 'a' key press.

Taking from Python tkinter: stopping event propagation in text widgets tags , stopping the event propagation is what we need. Returning 'break' stops whatever following event is breaking the ctrl+a behavior, and also allows us to shorten our bind to '<Control-A>'

def callback(event):

    # select text
    event.widget.select_range(0, 'end')
    # move cursor to the end
    event.widget.icursor('end')
    #stop propagation
    return 'break'

root = tk.Tk()

e = tk.Entry(root)
e.pack()
e.bind('<Control-a>', callback)

root.mainloop()
Tyler Smith
  • 221
  • 2
  • 3
  • Is it possible to one line-it using lambda? – Jack Jan 19 '22 at 12:54
  • I manage to do it and seems to be working. I hope it doesn't introduce some nasty bugs. `e.bind('', lambda x: e.selection_range(0, 'end') or "break")` – Jack Jan 19 '22 at 13:02
  • @Jack I think you should the function itself, because as you can see the callback function is using its parameter arguments to do the job, hence no external dependency, which means you can use it in every other entry widget there is. – Aman Ahmed Siddiqui Jul 30 '22 at 05:21