autoscroll of text and scrollbar in python text box

Question:

I have a tkinter ‘Text’ and ‘Scrollbar’ working fine. In my program in the text window automatically lines will keep on adding. So When a new line of text is inserted and data reached out of limit I would like the text and scrollbar to be scrolled to the bottom automatically, so that the latest line of text is always shown. How to do this?

Also how to link the scroll of text window and scroll bar, because when I do scrolling over the text window scroll wont happen. Only way I observed is to drag the scroll bar.

    scrollbar = Tkinter.Scrollbar(group4.interior())
    scrollbar.pack(side = 'right',fill='y')

    Details1 = Output()        
    outputwindow = Tkinter.Text(group4.interior(), yscrollcommand = scrollbar.set,wrap = "word",width = 200,font = "{Times new Roman} 9")
    outputwindow.pack( side = 'left',fill='y')
    scrollbar.config( command = outputwindow.yview )
    outputwindow.yview('end')
    outputwindow.config(yscrollcommand=scrollbar.set)
    outputwindow.insert('end',Details1)

In the program the function output() will continuously send data, which should scroll

Thanks in advance,

Asked By: Ds Arjun

||

Answers:

You can cause the text widget to scroll to any location with the see which takes an index.

For example, to make the last line of the widget visible you can use the index "end":

outputwindow.see("end")

Here’s a complete working example:

import time
try:
    # python 2.x
    import Tkinter as tk
except ImportError:
    # python 3.x
    import tkinter as tk

class Example(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

        self.text = tk.Text(self, height=6, width=40)
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=self.vsb.set)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)

        self.add_timestamp()

    def add_timestamp(self):
        self.text.insert("end", time.ctime() + "n")
        self.text.see("end")
        self.after(1000, self.add_timestamp)

if __name__ == "__main__":
    root =tk.Tk()
    frame = Example(root)
    frame.pack(fill="both", expand=True)
    root.mainloop()
Answered By: Bryan Oakley

Take a look at Text.see(...) method.

TextWidget.insert(tk.END, str(new_txt))
TextWidget.see(tk.END)

I used this pattern to add (aka insert) text new_txt to my output window and scroll (see) to the bottom (tk.END)

Answered By: Mike from PSG

although very useful, using Text.see(…) in the above manner defeats the purpose of having a scrollbar. Better would be insert text at "0." instead of tk.END. That way, it initially autoscrolls, but you can drag it down to anywhere and it will stay there (while updating its range as more text is added, but the text you see remains constant until you scroll elsewhere). Once you want it to autoscroll again, you simply slide the scrollbar all the way back to the top.

Another solution (which wouldn’t affect the flow direction of incoming text) would be to add some extra logic, such as a checkbox, then everytime you update Text, check that checkbox’s state before you decide whether or not to call Text.see(…).

I don’t know if there is a more elegant solution.

Answered By: moe fear

Add this after the insert

TextBox.yview(END)

Answered By: dvir pashut
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.