Я использую Kivy's recycleview
, чтобы отобразить список данных в виде таблицы.Я использовал пример из документации в качестве основы для моей реализации.
В моей программе RecycleDataView основан на BoxLayout, и его дочерние виджеты генерируются динамически.
Кажется, это работает, но порядок, в котором отображаются элементы, иногда меняется на противоположный и постоянно меняется, если вы измените размер окна.Еще хуже, если вы прокрутите вниз, макет становится совершенно сумасшедшим.Этого не произойдет, если я буду использовать простую метку в качестве класса элемента, поэтому я предполагаю, что проблема в моей динамически создаваемой логике виджета, но я не понимаю, почему.
Вот некоторый минимальный код, который показывает проблему.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
Builder.load_string('''
<RV>:
viewclass: 'RVItem'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
class Attribute:
def __init__(self, name, values):
self.name = name
self.values = values
class RVItem(RecycleDataViewBehavior, BoxLayout):
index = None
attribute = ObjectProperty()
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
self.create_widgets(data.pop('attribute', None))
return super(RVItem, self).refresh_view_attrs(
rv, index, data)
def create_widgets(self, value: Attribute):
"""Dynamically create the needed Widgets"""
if value is None:
return
self.add_widget(Label(text=value.name, height=self.height, size_hint=(1, None)))
if not isinstance(value.values, dict):
self.add_widget(Label(text=value.values, height=self.height, size_hint=(1, None)))
else:
for _, v in value.values.items():
self.add_widget(Label(text=v, height=self.height, size_hint=(1, None)))
image_button = Button(text='+')
#image_button.source = 'wm_ui/glyphs/plus.png'
image_button.size_hint = None, None
image_button.size = "30sp", "30sp"
image_button.bind(on_press=self.add_button_pressed)
self.add_widget(image_button)
def add_button_pressed(self, s):
print("Would add a new item to the recycleview if implemented.")
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'attribute': Attribute(str(x), "test")} for x in range(100)]
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
Для простоты я изменил некоторые виджеты на их базовые классы (например, ImageButton и Label)
Когда вы запустите приложение, вы должны увидеть, что порядок, в котором элементы обращены, и запускс 10 вместо 100 по какой-то причине.
![the started application](https://i.stack.imgur.com/7RPsi.png)
После изменения размера окна с помощью мыши в одном из углов окна вы должны увидеть, как содержимое непрерывно переупорядочивается..
![after resizing the window a bit](https://i.stack.imgur.com/R0RJ2.png)
А если прокрутить вниз, все становится еще более сумасшедшим.
![after scrolling down the list](https://i.stack.imgur.com/zVRFk.png)
К сожалению, я понятия не имею, что вызывает поведение.Я уже разрабатывал некоторые приложения Kivy, но это мое первое по-настоящему глубокое погружение, в котором используются не только ярлыки и несколько входов.