Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Text widget from scrolling when content is changed

I have a text widget with a scrollbar which looks something like this:

self.myWidget = Text(root) 
self.myWidget.configure(state=DISABLED)
self.myWidget.pack()

self.myWidgetScrollbar = Scrollbar(root, command=self.myWidget.yview)
self.myWidget.configure(yscrollcommand=self.myWidgetScrollbar.set)
self.myWidgetScrollbar.pack(side=LEFT,fill=Y)

The text widget is updated 4 times per second with:

self.myWidget.configure(state=NORMAL)
self.myWidget.delete(1.0, END) 
self.myWidget.insert(END, "\n".join(self.listWithStuff))  
self.myWidget.configure(state=DISABLED)

The problem is that when I try to scroll, it keeps scrolling me back up to the top (4 times per second, probably). I assume this is because all content is removed.

How can I prevent it from scrolling automatically, or possibly scroll "back" when the content has changed?

like image 676
Rixosupiazolipi Avatar asked Dec 17 '25 16:12

Rixosupiazolipi


2 Answers

You can safe the position and set it back after an update, like this Tcl code does:

proc update_view {w s data} {
  # store position
  set pos [$s get]
  $w configure -state normal -yscrollcommand {}
  $w delete 1.0 end
  $w insert end $data
  $w configure -state disabled -yscrollcommand [list $s set]
  $s get
  $s set {*}$pos
}

The Tkinter code would look similar, something like:

def update_view(self, data):
    pos = self.myWidgetScrollbar.get()
    self.myWidget.configure(yscrollcommand=None, state=NORMAL)
    self.myWidget.delete(1.0, END)
    self.myWidget.insert(END, data)
    self.myWidget.configure(yscrollcommand=self.myWidgetScrollbar.set, state=DISABLED)
    self.myWidgetScrollbar.get()
    self.myWidgetScrollbar.set(pos)

Not sure why the get() in between is needed, maybe to force some lookup, but it works.

like image 76
schlenk Avatar answered Dec 19 '25 06:12

schlenk


You can jump to the bottom of the widget after each update using the yview method of the Text widget. Also, to prevent frustrating users by jumping when they are trying to scroll, you can do a simple check to make sure the scrollbar is already at the bottom (a.k.a the user isn't scrolling).

if self.myWidgetScrollbar.get() == 1.0:
    self.myWidget.yview(END)
like image 40
Hollinski Avatar answered Dec 19 '25 04:12

Hollinski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!