Python: Scroll a ScrolledText automatically to the end if the user is not scrolling manually

孤者浪人 提交于 2021-01-28 06:20:45

问题


I made my ScrolledText scroll automatically to the end, based on this answer.

Now I'd like to scroll automatically only if the user is not scrolling manually.

I was looking for something like this: self.text.offsetBottom (see my comment in the code below), but couldn't find it yet.

Any ideas? Thanks!

import time
from Tkinter import *
import ScrolledText

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

        self.text = ScrolledText.ScrolledText(self, height=6, width=40)
        self.text.pack(side="left", fill="both", expand=True)
        self.add_timestamp()

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

        """ -----> HERE <----- """         
        # if self.text.offsetBottom > 0:
        self.text.see("end")
        self.after(1000, self.add_timestamp)

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

回答1:


You can use the yview() method to see if the widget is fully scrolled down. yview() returns a 2-tuple with the top and bottom of the visible part relative to the total size. So if the widget is fully scrolled down, the second number should be 1.0.

We can use this to only scroll if the widget was fully scrolled down before the insert happened:

def add_timestamp(self):
    fully_scrolled_down = self.text.yview()[1] == 1.0
    self.text.insert("end", time.ctime() + "\n")
    if fully_scrolled_down:
        self.text.see("end")
    self.after(1000, self.add_timestamp)

Another option is to check whether the last character is currently visible or not using

visible = self.text.bbox("end-1c")

From effbot, we can read that this method gives a 4-tuple if the character is visible, or None if the character is not visible:

bbox(index)
Calculates the bounding box for the given character.

This method only works if the text widget is updated. To make sure this is the case, you can call the update_idletasks method first.

index
Character index.
Returns:
A 4-tuple (x, y, width, height), or None, if the character is not visible.

We can use this to only scroll if the last character was visible before the insert happened:

def add_timestamp(self):
    last_char_visible= self.text.bbox("end-1c")
    self.text.insert("end", time.ctime() + "\n")
    if last_char_visible:
        self.text.see("end")
    self.after(1000, self.add_timestamp)


来源:https://stackoverflow.com/questions/51781247/python-scroll-a-scrolledtext-automatically-to-the-end-if-the-user-is-not-scroll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!