2

When I run this code, it adds a blank line to the bottom of my textbox. I want my textbox to just show NEW TEXT after return is pressed, and I cannot figure out how to accomplish it. I searched on this site and could not find an answer, so apologies in advance if this is a duplicate question.

import tkinter as tk

def update(event):
    entry.delete('1.0', tk.END)
    entry.insert('1.0', 'NEW TEXT')
    if entry.get('end-1c', 'end') == '\n':
        entry.delete('end-1c', 'end')

root = tk.Tk()
root.config(bg='snow3')
root.geometry('200x200')
entry = tk.Text(root, height=1.3, width=12)
entry.bind('<Return>', update)
entry.configure(wrap='none')
entry.pack()
root.mainloop()
Lzypenguin
  • 945
  • 1
  • 7
  • 18
  • It shows NEW TEXT when you press the left or up arrow keys. – ahmadjanan Jan 24 '21 at 18:47
  • Yes, I know that. But I do not want my end user to have to press the up or arrow keys. I want them to see NEW TEXT when they press return... – Lzypenguin Jan 24 '21 at 18:48
  • Do you want the user to be able to edit the entry after the text is shown? – ahmadjanan Jan 24 '21 at 18:58
  • When you are pressing enter you are going to second line. "NEW TEXT" is inserted at line 1, but your cursor is still line 2 pos 0. – Epsi95 Jan 24 '21 at 19:15
  • I would've sworn we've seen almost this very exact question in the last few weeks, though I'm having trouble finding it. Also, if you need just a single line, why aren't you using the `Entry` widget? – Bryan Oakley Jan 24 '21 at 19:26
  • It seems `entry.delete` isn't actually deleting the `\n` character put when pressing enter, strange. – Epsi95 Jan 24 '21 at 19:30
  • @Epsi95: that is because the `entry.delete` command is being run before the newline character is inserted into the widget. – Bryan Oakley Jan 24 '21 at 19:36
  • `def update(event): print(len(entry.get('1.0', tk.END))) print(repr('>'+(entry.get('1.0', tk.END))+'>')) entry.delete('1.0', tk.END) print(len(entry.get('1.0', tk.END))) print(repr('>'+(entry.get('1.0', tk.END))+'>'))` if you run this code you can see `1 '>\n>' 1 '>\n>'`. It seems delete just can't touch the newline character @BryanOakley – Epsi95 Jan 24 '21 at 19:39
  • @Epsi95: you are correct that the delete cannot delete the final trailing newline. That is managed by the widget and cannot be deleted. That is by design. However, my comment wasn't about that. You mentioned delete isn't deleting the `\n` put in when pressing enter. It definitely can, assuming you call delete after it's actually inserted. The final trailing newline is not inserted when you press the enter key. – Bryan Oakley Jan 24 '21 at 19:58
  • Oh okay okay, your explanation is great though! – Epsi95 Jan 24 '21 at 19:58

1 Answers1

4

You cannot remove the final newline. That is baked into the text widget.

However, the problem is not the built-in newline. The problem is that the return key is inserting a newline after your function runs. That is because your binding happens before the built-in bindings, which is an important part of the way tkinter handles key bindings (and is a brilliant design!).

In short, this is what happens:

  • user presses the return key
  • your function is called from a widget-specific binding
  • your function deletes everything
  • your function inserts new text
  • your function returns
  • the Text widget class binding inserts a newline

To prevent that last step from happening, you need to return the string "break" from your function. That will prevent the default behavior defined by the Text widget from happening. The end result is that the changes you made to the widget in your function are the only changes made to the widget when the user presses the return key.

def update(event):
    entry.delete('1.0', tk.END)
    entry.insert('1.0', 'NEW TEXT')
    return "break"

For a slightly longer explanation of why this happens, see this answer to the question Basic query regarding bindtags in tkinter.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • OMG this finally worked. Thank you so much. I have been so frustrated trying to figure out how to prevent the newline!!! Really appreciate it. I am interested how/why your returning 'break' and not break. Why do the quotes need to be around them? – Lzypenguin Jan 24 '21 at 23:27
  • 1
    @Lzypenguin: why return the string "break"? That's simply how tkinter is designed to work. It's documented in the built-in documentation for the "bind" command (eg: `print(help(tkinter.Widget.bind))`) – Bryan Oakley Jan 25 '21 at 03:26
  • Gotcha. Thank you again so much for the help. I searched for so long. Appreciate it! – Lzypenguin Jan 25 '21 at 03:57