英文:
Why I have to click twice to scroll? Scrollable Label in kivy, python
问题
以下是您要翻译的代码部分:
import kivy
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 Screen, ScreenManager
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.config import Config
Config.set('graphics', 'resizable', True)
import os
import sys
class MyApp(App):
def build(self):
self.screen_manager = ScreenManager()
self.answers = Answers()
screen = Screen(name="Answers")
screen.add_widget(self.answers)
self.screen_manager.add_widget(screen)
return self.screen_manager
class Answers(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rows = 3
self.label = Label(text="Answers: ", font_size=40)
self.add_widget(self.label)
self.button = Button(text="Show answers")
self.button.bind(on_press=self.showanswers)
self.add_widget(self.button)
self.scroll = ScrollableLabel(height=Window.size[1]*0.75, size_hint_y=None)
self.add_widget(self.scroll)
def showanswers(self, instance):
f = open("text.txt", "r")
lines = f.readlines()
ScrollableLabel.update(self.scroll, lines)
myapp.screen_manager.current = "Answers";
class ScrollableLabel(ScrollView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout = GridLayout(cols=1, size_hint_y=None)
self.add_widget(self.layout)
self.lines = Label(size_hint_x=1, size_hint_y=None, text_size=(self.width, None))
self.scroll_to_point = Label()
self.scroll_to_point.bind(texture_size=self.scroll_to_point.setter('size'))
self.layout.add_widget(self.lines)
self.layout.add_widget(self.scroll_to_point)
def update(self, lines):
self.lines.text = '\n'
for i in range(len(lines)):
self.lines.text += '\n ' + str(i+1) + ". " + lines[i]
self.layout.height = self.lines.texture_size[1]
self.lines.height = self.lines.texture_size[1]
self.lines.text_size = (self.lines.width*0.75, None)
self.scroll_to(self.scroll_to_point)
f = open("text.txt", 'a+')
for i in range(30):
f.write("Important text \n")
f.close()
myapp = MyApp()
myapp.run()
英文:
I have a following problem: I need to write an app, where I will show proper answers for every question. I wrote with kivy some code and I'm struggling with one thing. I created a page. There is a button for showing answers, but after one press I only see a part of my answers and I can't scroll. But, when I press a button second time, everything is good. Could you tell me why is that? How to repair it? I would like to see all answers after pressing a button once and be able to scroll.
import kivy
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 Screen, ScreenManager
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.config import Config
Config.set('graphics', 'resizable', True)
import os
import sys
class MyApp(App):
def build(self):
self.screen_manager = ScreenManager()
self.answers = Answers()
screen = Screen(name = "Answers")
screen.add_widget(self.answers)
self.screen_manager.add_widget(screen)
return self.screen_manager
class Answers(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rows = 3
self.label = Label(text = "Answers: ", font_size = 40)
self.add_widget(self.label)
self.button = Button(text="Show answers")
self.button.bind(on_press=self.showanswers)
self.add_widget(self.button)
self.scroll = ScrollableLabel(height = Window.size[1]*0.75, size_hint_y = None)
self.add_widget(self.scroll)
def showanswers(self, instance):
f = open("text.txt", "r")
lines = f.readlines()
ScrollableLabel.update(self.scroll, lines)
myapp.screen_manager.current = "Answers"
class ScrollableLabel(ScrollView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout = GridLayout(cols = 1, size_hint_y = None)
self.add_widget(self.layout)
self.lines = Label(size_hint_x = 1, size_hint_y = None, text_size = (self.width, None))
self.scroll_to_point = Label()
self.scroll_to_point.bind(texture_size=self.scroll_to_point.setter('size'))
self.layout.add_widget(self.lines)
self.layout.add_widget(self.scroll_to_point)
def update(self, lines):
self.lines.text = '\n'
for i in range(len(lines)):
self.lines.text += '\n ' +str(i+1) + ". " + lines[i]
self.layout.height = self.lines.texture_size[1]
self.lines.height = self.lines.texture_size[1]
self.lines.text_size = (self.lines.width*0.75, None)
self.scroll_to(self.scroll_to_point)
f = open("text.txt", 'a+')
for i in range(30):
f.write("Important text \n")
f.close()
myapp = MyApp()
myapp.run()
答案1
得分: 1
I think your widget heights are not updating correctly, and to correct that requires doing some binding. Since the 'kv' language automatically does bindings, I have provided an answer that uses 'kv':
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.config import Config
Config.set('graphics', 'resizable', True)
class MyApp(App):
def build(self):
self.screen_manager = ScreenManager()
self.answers = Answers()
screen = Screen(name="Answers")
screen.add_widget(self.answers)
self.screen_manager.add_widget(screen)
return self.screen_manager
class Answers(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rows = 3
self.label = Label(text="Answers: ", font_size=40)
self.add_widget(self.label)
self.button = Button(text="Show answers")
self.button.bind(on_press=self.showanswers)
self.add_widget(self.button)
self.scroll = ScrollableLabel(height=Window.size[1]*0.75, size_hint_y=None)
self.add_widget(self.scroll)
def showanswers(self, instance):
f = open("text.txt", "r")
lines = f.readlines()
self.scroll.update(lines)
myapp.screen_manager.current = "Answers"
class ScrollableLabel(ScrollView):
def update(self, lines):
self.ids.lines.text = '\n'
for i in range(len(lines)):
self.ids.lines.text += '\n ' +str(i+1) + ". " + lines[i]
Builder.load_string('''
<ScrollableLabel>:
size_hint_y: None
GridLayout:
cols: 1
size_hint_y: None
height: self.minimum_height # adjust height to handle the Label
Label:
id: lines
size_hint_y: None
height: self.texture_size[1] # set height based on text
''')
f = open("text.txt", 'a+')
for i in range(30):
f.write("Important text \n")
f.close()
myapp = MyApp()
myapp.run()
I believe the two instances of size_hint_y: None
and the corresponding height
rules are the key.
Note that I also changed:
ScrollableLabel.update(self.scroll, lines)
to:
self.scroll.update(lines)
英文:
I think your widget heights are not updating correctly, and to correct that requires doing some binding. Since the 'kv' language automatically does bindings, I have provided an answer that uses 'kv':
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.config import Config
Config.set('graphics', 'resizable', True)
class MyApp(App):
def build(self):
self.screen_manager = ScreenManager()
self.answers = Answers()
screen = Screen(name = "Answers")
screen.add_widget(self.answers)
self.screen_manager.add_widget(screen)
return self.screen_manager
class Answers(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rows = 3
self.label = Label(text = "Answers: ", font_size = 40)
self.add_widget(self.label)
self.button = Button(text="Show answers")
self.button.bind(on_press=self.showanswers)
self.add_widget(self.button)
self.scroll = ScrollableLabel(height = Window.size[1]*0.75, size_hint_y = None)
self.add_widget(self.scroll)
def showanswers(self, instance):
f = open("text.txt", "r")
lines = f.readlines()
self.scroll.update(lines)
myapp.screen_manager.current = "Answers"
class ScrollableLabel(ScrollView):
def update(self, lines):
self.ids.lines.text = '\n'
for i in range(len(lines)):
self.ids.lines.text += '\n ' +str(i+1) + ". " + lines[i]
Builder.load_string('''
<ScrollableLabel>:
size_hint_y: None
GridLayout:
cols: 1
size_hint_y: None
height: self.minimum_height # adjust height to handle the Label
Label:
id: lines
size_hint_y: None
height: self.texture_size[1] # set height based on text
''')
f = open("text.txt", 'a+')
for i in range(30):
f.write("Important text \n")
f.close()
myapp = MyApp()
myapp.run()
I believe the two instances of size_hint_y: None
and the corresponding height
rules are the key.
Note that I also changed:
ScrollableLabel.update(self.scroll, lines)
to:
self.scroll.update(lines)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论