Как получить доступ к свойствам Kivy изнутри «я» в __init__()Python

Программы на Python
Anonymous
Как получить доступ к свойствам Kivy изнутри «я» в __init__()

Сообщение Anonymous »

Как я могу получить доступ к свойству Kivy в собственной функции __init__() виджета?
Я написал собственный виджет в Kivy. Мне нужно отобразить несколько тысяч экземпляров этого объекта виджета в сетке на экране киви. Это приводит к сбою системы, поэтому я заключаю GridLayout в RecycleView. Благодаря этому он будет рендериться немедленно и без каких-либо задержек. Отлично!
Раньше в функцию __init__() моего пользовательского виджета передавались позиционные аргументы, которые я использовал для настройки нескольких полей экземпляра, которые будут использоваться для определения того, что будет появляются (и как) в виджете. К сожалению, RecycleView заставил меня заменить позиционные аргументы свойствами Kivy. И я не могу получить доступ к значениям этих свойств в функции __init__() объекта.
Для простоты давайте рассмотрим этот минимальный пример проблемы, взятый из этот вопрос в списке рассылки Kivy.

Код: Выделить всё

#!/usr/bin/env python3
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty, ListProperty

kv = '''
:
# This class is used as the viewclass in the RecycleView
# The means this widget will be instanced to view one element of data from the data list.
# The RecycleView data list is a list of dictionaries.   The keys in the dictionary specify the
# attributes of the widget.
Button:
text: root.left_text
on_release: print(f'Button {self.text} pressed')
Button:
text: root.right_text
on_release: print(f'Button {self.text} pressed')

BoxLayout:
orientation: 'vertical'
Button:
size_hint_y: None
height: 48
text: 'Add widget to RV list'
on_release: rv.add()

RV:                          # A Reycleview
id: rv
viewclass: 'TwoButtons'  # The view class is TwoButtons, defined above.
scroll_type: ['bars', 'content']
bar_width: 10
RecycleBoxLayout:
# This layout is used to hold the Recycle widgets
default_size: None, dp(48)   # This sets the height of the BoxLayout that holds a TwoButtons instance.

default_size_hint: 1, None
size_hint_y: None

height: self.minimum_height   # To scroll you need to set the layout height.
orientation: 'vertical'
'''

class TwoButtons(BoxLayout):  # The viewclass definitions, and property definitions.
left_text = StringProperty()
right_text = StringProperty()

print( "TwoButtons top" )

def __init__(self, **kwargs):
print( "self.left_text:|" +str(self.left_text)+ "|" )
super().__init__(**kwargs)
print( "self.left_text:|" +str(self.left_text)+ "|"  )

class RV(RecycleView):

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.data = [{'left_text': f'Left {i}', 'right_text': f'Right {i}'} for i in range(2)]

def add(self):
l = len(self.data)
self.data.extend(
[{'left_text': f'Added Left {i}', 'right_text': f'Added Right {i}'} for i in range(l, l + 1)]
)

class RVTwoApp(App):

def build(self):
return Builder.load_string(kv)

RVTwoApp().run()
В приведенном выше сегменте кода пользовательский виджет, который мы используем RecycleView для создания множества экземпляров, называется TwoButtons.




Изображение





Кнопки в графическом интерфейсе отображаются с текстом Left 0 и Left 1 по желанию, но попытка получить доступ к их значениям из __init__() приводит к пустая строка (

Код: Выделить всё

self.left_text:||
)



Две кнопки Класс имеет два свойства Kivy:
  • StringProperty left_text и
    StringProperty right_text
Если вы запустите приложение, вы ясно увидите, что RecycleView может передавать данные в свойства экземпляров TwoButtons, поскольку текст появляется на кнопках, как и ожидалось.
Проблема в том, что значением свойства left_text является пустая строка внутри __init__()
Рассмотрим следующее выполнение приведенной выше программы:

Код: Выделить всё

user@buskill:~/tmp/rv$ python3 rv.py
[INFO   ] [Logger      ] Record log in /home/user/.kivy/logs/kivy_24-03-17_23.txt
[INFO   ] [Kivy        ] v2.1.0
[INFO   ] [Kivy        ] Installed at "/home/user/.local/lib/python3.9/site-packages/kivy/__init__.py"
[INFO   ] [Python      ] v3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110]
...
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [Base        ] Start application main loop
[INFO   ] [GL          ] NPOT texture support is available
self.left_text:||
self.left_text:||
self.left_text:||
self.left_text:||
Как видите, операторы print() внутри функции __init__() TwoButtons возвращают пустую строку для left_text (хотя фактический left_text на кнопках в графическом интерфейсе отображается как Left 0 и Left 1, по желанию).
Более того, если вы нажмете кнопку «Добавить виджет в список RV», чтобы добавить третий ряд кнопок с текстом «Добавлено слева 2» и «Добавлено справа 2», то следующие новые строки будут print()

Подробнее здесь: https://stackoverflow.com/questions/781 ... lf-on-init

Вернуться в «Python»