Kivy Scrollview 自动滚动到新文本。防止向上滚动
Kivy Scrollview Autoscroll to new text. Prevent from scrolling up
我真的很需要一些帮助来解决我实际上非常简单的 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()
非常感谢您的帮助!
如果我没理解错的话,你想要这样的东西。你的代码有很多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()
我真的很需要一些帮助来解决我实际上非常简单的 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()
非常感谢您的帮助!
如果我没理解错的话,你想要这样的东西。你的代码有很多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()