Почему я должен дважды щелкнуть, чтобы прокрутить? Прокручиваемый ярлык в киве, python - PullRequest
0 голосов
/ 06 января 2020

У меня следующая проблема: мне нужно написать приложение, в котором я покажу правильные ответы на каждый вопрос. Я написал с Kivy некоторый код, и я борюсь с одной вещью. Я создал страницу. Есть кнопка для отображения ответов, но после одного нажатия я вижу только часть своих ответов и не могу прокрутить. Но когда я нажимаю кнопку второй раз, все хорошо. Не могли бы вы сказать мне, почему это? Как это починить? Я хотел бы видеть все ответы после одного нажатия кнопки и иметь возможность прокрутки.

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 голос
/ 07 января 2020

Я думаю, что высота вашего виджета не обновляется правильно, и для исправления необходимо выполнить некоторые привязки. Поскольку язык 'kv' автоматически выполняет привязки, я предоставил ответ, который использует '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()

Я считаю, что два экземпляра size_hint_y: None и соответствующие правила height являются ключом.

Обратите внимание, что я также изменил:

ScrollableLabel.update(self.scroll, lines)

на:

self.scroll.update(lines)
...