Как мне динамически добавлять элементы в scrollview в kivy - PullRequest
1 голос
/ 13 марта 2019

Здравствуйте, я относительно новичок в kivy. Пока что делать базовые вещи было относительно просто, но это поставило меня в тупик. Я делаю приложение, которое должно динамически добавлять прямоугольные элементы холста в сетку в виде прокрутки. Так как я делаю это, мне нужно создать scrollview в python, а не в файле .kv. Как я могу сделать это, чтобы размер прямоугольников был таким же, как размер окна при изменении размера окна?

.py файл:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Line,Rectangle
from kivy.uix.carousel import Carousel
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window

class Scroll(ScrollView):
    def __init__(self,  **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = RelativeLayout(pos=(0,0), height=100, size_hint_y=None, size_hint_x=self.width)
            with SkillStat.canvas:
                Rectangle(pos=self.pos,size=(self.width, 90))
            layout.add_widget(SkillStat)

        self.add_widget(layout)
        pass
    pass
class Sheet(Carousel):
    pass

class SheetApp(App):
    def build(self):    
        return Sheet()

if __name__ == '__main__':
    SheetApp().run()

.kv файл:

# file name: Sheet.kv

<Sheet>:
    RelativeLayout:
        Scroll:
            size_hint:(1,1)

Ответы [ 2 ]

0 голосов
/ 13 марта 2019

Решение

  1. Создать класс с наследованием от RelativeLayout.
  2. Обновите или удалите инструкции, добавленные на холст, с помощью функции bind.

Отрывки

class CustomLayout(RelativeLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)
        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=(self.width, 90))
        self.bind(pos=self.update_rect, size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size

Пример

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Line, Rectangle
from kivy.uix.carousel import Carousel
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivy.lang import Builder


class CustomLayout(RelativeLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)
        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=(self.width, 90))
        self.bind(pos=self.update_rect, size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size


class Scroll(ScrollView):
    def __init__(self, **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = CustomLayout(pos=(0, 0), height=100, size_hint_y=None, size_hint_x=self.width)
            layout.add_widget(SkillStat)

        self.add_widget(layout)


class Sheet(Carousel):
    pass


Builder.load_file('main.kv')


class SheetApp(App):
    def build(self):
        return Sheet()


if __name__ == '__main__':
    SheetApp().run()

main.kv

#:kivy 1.11.0

<Sheet>:
    RelativeLayout:
        Scroll:
            size_hint:(1,1)
            bar_width: 10
            effect_cls: "ScrollEffect"
            scroll_type: ['bars']
            bar_color: [1, 0, 0, 1]     # red color
            bar_inactive_color: [0, 0, 1, 1]    # blue color

выход

Scrollview - App Start Up Scrolling RelativeLaouts Window resized - smaller Window resized - bigger

0 голосов
/ 13 марта 2019

Две основные проблемы в вашем коде:

  1. Все настройки размера и положения вашего SkillStat и холста выполняются методом __init__().В методе __init__() виджета положение виджета всегда равно (0,0), а размер (100, 100).Эти свойства не устанавливаются в реальные значения, пока виджет не будет нарисован.
  2. Вы делаете все это в python, а не в kvkv привязки создаются для многих заданных вами свойств и автоматически обновляются.Если вы выполняете настройку виджета в python, вы должны сами предоставить эти привязки.

Вот модифицированная версия вашего класса Scroll и новый класс MyRelativeLayout, который обрабатывает эти привязки:

class MyRelativeLayout(RelativeLayout):
    def adjust_size(self, *args):
        self.rect.size = self.size  # set the size of the Rectangle


class Scroll(ScrollView):
    def __init__(self,  **kwargs):
        super(Scroll, self).__init__(**kwargs)
        layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
        layout.bind(minimum_height=layout.setter('height'))
        # Make sure the height is such that there is something to scroll.
        for i in range(100):
            SkillStat = MyRelativeLayout(pos=(0,0), height=100, size_hint=(1.0, None))
            with SkillStat.canvas.before:
                SkillStat.rect = Rectangle()
            SkillStat.bind(size=SkillStat.adjust_size)
            layout.add_widget(SkillStat)
        self.add_widget(layout)

Обратите внимание на вызов SkillStat.bind() для создания необходимых привязок, и Rectangle сохраняется как SkillStat.rect в каждом MyRelativeLayout экземпляре.Эти привязки сработают, как только отобразится SkillStat, поэтому начальные pos и size для Rectangle не нужны.

EDIT: Установка pos для Rectangle в привязке, вероятно, вызывало проблемы.Значение по умолчанию pos для Rectangle равно (0,0), что и должно быть всегда.Итак, нам нужно только отрегулировать size из Rectangle.Я удалил привязку для pos.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...