Kivy Scrollview 自动滚动到新文本并且行消失

Kivy Scrollview autoscroll to new text and lines disappear

我有一个 Kivy 滚动视图,想通过单击按钮添加一些文本。每次单击后,滚动视图应自动滚动到最新的文本行。但由于某种原因,它只能每隔一秒使用一次,并且只能使用一行。当有多行时(参见示例),一些行会在滚动视图的边缘后面消失。文本在跳到顶部和跳到底部边缘之间切换。当文本位于底部并且您手动滚动(或只需单击滚动视图字段)时,文本就会跳到顶部。我希望能够手动滚动,但文本不应该在不单击“添加文本”的情况下跳转。但是,当单击“添加文本”时,它应该会按照描述滚动到新的底部文本行。

import kivy
from kivy.config import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
from kivy.clock import mainthread
import threading

kivy.require("2.0.0")
Config.set('kivy', 'keyboard_mode', 'systemandmulti')

class MainMenu(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 1
        self.rows = 3
        
        self.infowindow = ScrollableInfo(height=Window.size[1]*0.8, size_hint_y=None)
        self.add_widget(self.infowindow)

        self.addtextbutton = Button(text="Add Text")
        self.addtextbutton.bind(on_press=self.add_text_thread)
        self.add_widget(self.addtextbutton)

    def addtext(self, *_):
        self.infowindow.update_scrollview(f"This is some new Text \n and even more \n and more")
     

    def add_text_thread(self, *args):
        threading.Thread(target=self.addtext, daemon=True).start()



class ScrollableInfo(ScrollView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.layout = GridLayout(cols=1, size_hint=(1, None))
        self.add_widget(self.layout)

        self.text_history = Label(size_hint_y=None, markup=True)
        self.scrolllabel = Label()

        self.layout.add_widget(self.text_history)
        self.layout.add_widget(self.scrolllabel)

    @mainthread
    def update_scrollview(self, newinfo):
        self.text_history.text += '\n' + newinfo
        
        self.layout.height = self.text_history.texture_size[1]+15
        self.text_history.height = self.text_history.texture_size[1]
        self.text_history.text_size = (self.text_history.width*0.98, None)

        self.scroll_y = 0

class Textadding(App):
    def build(self):
        self.screen_manager = ScreenManager()

        self.mainmenu_page = MainMenu()
        screen = Screen(name="MainMenu")
        screen.add_widget(self.mainmenu_page)
        self.screen_manager.add_widget(screen)

        return self.screen_manager

if __name__ == "__main__":
    counting_app = Textadding()
    counting_app.run()

提前致谢!

您可以通过使用更多绑定来做到这一点。首先,将 GridLayout 的高度绑定到它自己计算的 minimum_size。然后将其 size 绑定到调整 scroll_y 属性:

的方法
    self.layout = GridLayout(cols=1, size_hint=(1, None))
    self.layout.bind(minimum_height=self.layout.setter('height'))
    self.layout.bind(size=self.on_size)

ScrollableInfoon_size()方法:

def on_size(self, *args):
    self.scroll_y = 0

现在,您不必在 update_scrollview() 方法中进行大小计算,因此它变成了:

@mainthread
def update_scrollview(self, newinfo):
    self.text_history.text += '\n' + newinfo