Kivy Scrollview 自动滚动到新文本。防止向上滚动

Posted

技术标签:

【中文标题】Kivy Scrollview 自动滚动到新文本。防止向上滚动【英文标题】:Kivy Scrollview Autoscroll to new text. Prevent from scrolling up 【发布时间】:2021-09-03 23:33:48 【问题描述】:

对于我非常简单的 Python Kivy 问题,我真的需要一些帮助! 我有一个 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")
     

    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_y=None)
        self.add_widget(self.layout)

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

        self.layout.add_widget(self.text_history)

    @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()

非常感谢您的任何帮助!

【问题讨论】:

【参考方案1】:

如果我理解正确的话,你想要这样的东西。你的代码有很多bug,很繁琐,所以我完全重写了。我也不建议在辅助线程中更改 UI(添加小部件、播放动画),这是一种不好的做法,在 kivy == 2.1.0dev0 中可能会导致错误。

from kivy.app import App
from kivy.lang import Builder

kv = """
Screen:
    BoxLayout:
        spacing: 10
        orientation: "vertical"
        
        ScrollView:
            id: scroll_view
            always_overscroll: False
            BoxLayout:
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                Label:
                    id: label
                    size_hint: None, None
                    size: self.texture_size 

        Button:
            text: "Add Text"
            size_hint_y: 0.2
            on_release: app.add_text()
        
"""


class TextAdding(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.text_counter = 0

    def build(self):
        return Builder.load_string(kv)

    def add_text(self):
        self.root.ids.label.text += f"Some text self.text_counter\n"
        self.text_counter += 1
        self.root.ids.scroll_view.scroll_y = 0


if __name__ == "__main__":
    TextAdding().run()

【讨论】:

我想我可以在此基础上制定一个解决方案!我的实际程序有点复杂,但你的回答在这一点上帮助了我很多..至少我是这么认为的。我是一个新手,目前我正在边做边学。非常感谢您的时间和详细的帮助!像这样的答案很有价值,因为它们是面向问题的,而不仅仅是笼统的。我会尝试一下,然后再回到这篇文章。 为什么这不能在第二个屏幕上工作?我尝试在第二个屏幕上的滚动视图中添加一些文本,但它仅适用于您的代码示例。我的问题在哪里?***.com/questions/68056772/… 如果我上面的解决方案对你有帮助,标记为答案,至于你的第二个问题,我现在看看)

以上是关于Kivy Scrollview 自动滚动到新文本。防止向上滚动的主要内容,如果未能解决你的问题,请参考以下文章

标签的 Kivy ScrollView 不会滚动

TextInput中的kivy ScrollView实现

Kivy ScrollView 用于文本段落

在kivy中将文本与ScrollView中的标签边缘对齐

Kivy ScrollView - 不滚动

为啥孩子的 Kivy ScrollView 孩子不可滚动?