I can't scroll with the keyboard in the text of my Text tag -Tkinter

Question:

I basically got the unwanted characters removed from the Text widget, but when I hit a line break and try to scroll the text with the keyboard or mouse, I just can’t (it always stays in the same place).
this is done in the "validate text" method


class NewNewsFrame(Frame):
    def __init__(self, parent):
        self.Parent = parent
        self.initializecomponents()
        pass

    def validate_text(self, widger):
        value = widger.get("1.0", "end-1c")
        print value.fon
        if not value.isalnum():
            var = str()
            for i in value:
                print(f"({i})")
                var += i if(i.isalpha() or i.isdigit() or i == "(" or i == ")" or i == " " or i == "," or i == "." or i == "n")else ""
            widger.delete("1.0", "end-1c")
            widger.insert("end-1c", var)
        pass

    def initializecomponents(self):
        Frame.__init__(self, self.Parent)

        self.DescriptionLabel = Label(self)
        self.DescriptionBox = Text(self)

        # DescriptionLabel
        self.DescriptionLabel.config(text="Description of the news:",bg=self["bg"], fg="#FFFFFF", font="none 15",anchor="nw")
        self.DescriptionLabel.place(relwidth=1, relheight=0.1, relx=0, rely=0.11, anchor="nw")

        # DescriptionBox
        self.DescriptionBox.bind("<KeyPress>", lambda event: self.validate_text(self.DescriptionBox))
        self.DescriptionBox.bind("<FocusOut>", lambda event: self.validate_text(self.DescriptionBox))

        self.DescriptionBox.place(relheight=0.4, relwidth=1, relx=0, rely=0.16, anchor="nw")
    pass

I tried to find how keyboard scrolling works, but I still don’t know how to do it

Asked By: DG Nutria

||

Answers:

The problem is that you’re deleting and restoring all of the text with every keypress. This causes the cursor position to change in unexpected ways that breaks the default bindings.

If you’re wanting to prevent certain characters from being entered, there’s a better way. If your validation function returns the string "break", that prevents the character from being inserted. You don’t have to re-scan the entire contents or delete and restore the text, because the bad characters never get entered in the first place.

Your validation function might look something like this:

def validate_text(self, event):
    if event.char.isalpha() or event.char.isdigit() or event.char in "() ,.n":
        pass
    else:
        return "break"

Next, simplify the binding to look like the following. Tkinter will automatically pass the event parameter to the function.

self.DescriptionBox.bind("<KeyPress>", self.validate_text)

This will break your <FocusOut> binding, but I’m not sure it’s needed.

For more information about how events are processed and why returning "break" does what it does, see this answer to the question Basic query regarding bindtags in tkinter. That question is about an Entry widget but the concept is the same for all widgets.

Answered By: Bryan Oakley
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.