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,
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()
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
)
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.
Add this after the insert
TextBox.yview(END)
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,
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()
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
)
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.
Add this after the insert
TextBox.yview(END)