Я попытался получить доступ к TabbedPanel.content.children [0] и удалить дочерний элемент и переписать новый дочерний элемент, но он не работает. Следует отметить, что TabbedPanel.content является TabbedPanelContent, а не ListView (в моем случае).Изменить содержимое вкладки с помощью кнопки в Kivy
Что я хочу сделать, это отредактировать содержимое моего спискаView. Приложение создает кнопку для создания данных и две вкладки, где первая вкладка создает списокView данных. Если кнопка снова нажата, она удалит предыдущий ListView и введет новый.
Как обновить содержимое вкладки? Код:
#test tabs
import kivy
kivy.require('1.0.6') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader
from kivy.properties import ListProperty
from kivy.properties import DictProperty
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.dictadapter import DictAdapter
from kivy.adapters.models import SelectableDataItem
from kivy.uix.selectableview import SelectableView
from kivy.uix.listview import ListView, ListItemButton
from kivy.factory import Factory
from kivy.lang import Builder
import random
#templates kv for SelectableView+BoxLayout called CustomListItem
Builder.load_string('''
[[email protected]+BoxLayout]:
size_hint_y: ctx.size_hint_y
height: ctx.height
ListItemButton:
text: ctx.text
is_selected: ctx.is_selected
''')
class testTabs(BoxLayout):
data = ListProperty([1,2,3,4,5])
def __init__(self, *args, **kwargs):
super(testTabs, self).__init__(**kwargs)
self.listViewDict = {}
#layout = GridLayout(rows = 2)
self.layout = BoxLayout(orientation = "vertical")
#buttonLayout = GridLayout(cols = 4)
dataButton = Button(text = "press to load random data to tab 1")
dataButton.bind(on_release = self.randData)
self.layout.add_widget(dataButton)
#create list
list_item_args_converter = \
lambda row_index, rec: {'text': rec['text'],
'is_selected': rec['is_selected'],
'size_hint_y': None,
'height': 35}
entry_dict = \
{str(i): {'text': str(self.data[i]), 'is_selected': False} \
for i in xrange(len(self.data)) }
self.listViewDict = entry_dict
sortedDateEntriesList = sorted(self.listViewDict)
dict_adapter = DictAdapter(sorted_keys = sortedDateEntriesList,
data = self.listViewDict,
args_converter=list_item_args_converter,
template = 'CustomListItem')
self.list_view = ListView(adapter=dict_adapter)
### Create tabs ###
self.tabbedPanel = TabbedPanel()
self.tabbedPanel.default_tab_text = "data tab"
self.tabbedPanel.tab_pos = "top_left"
self.tabbedPanel.default_tab_content = self.list_view
tabbedPanelHeader = TabbedPanelHeader(text = "tab 2")
tabbedPanelHeader.content = Label(text = "Hello world")
self.tabbedPanel.add_widget(tabbedPanelHeader)
self.layout.add_widget(self.tabbedPanel)
self.add_widget(self.layout)
#self.tabbedPanel.content.bind(children = self.foo)
def foo(self, *args):
print "############################in foo args:"
print args
tabbedPanelHeader = args[0]
print tabbedPanelHeader.children
def printContent(self, object):
print "object:" +str(object) +"'s content: " +str(object.content)
def printChildren(self, object):
for child in object.children:
print "object:" +str(object) +"'s child: " +str(child)
#create list view
def randData(self, *args):
print args
self.tabbedPanel.content.children[0].remove_widget(self.list_view)
print "content tabbedPanel children:"
print self.tabbedPanel.content.children
tempData = []
numValues = random.randint(10,20)-1
for i in xrange(numValues):
tempData.append(random.randint(1,30))
self.data = tempData
list_item_args_converter = \
lambda row_index, rec: {'text': rec['text'],
'is_selected': rec['is_selected'],
'size_hint_y': None,
'height': 35}
entry_dict = \
{str(i): {'text': str(self.data[i]), 'is_selected': False} \
for i in xrange(len(self.data)) }
self.listViewDict = entry_dict
sortedDateEntriesList = sorted(self.listViewDict)
dict_adapter = DictAdapter(sorted_keys = sortedDateEntriesList,
data = self.listViewDict,
args_converter=list_item_args_converter,
template = 'CustomListItem')
self.list_view = ListView(adapter=dict_adapter)
self.tabbedPanel.content.children[0].add_widget(self.list_view)
def on_data(self, *args):
print "on_data func. Data created:"
print args
class MyApp(App):
def build(self):
return testTabs()
if __name__ == '__main__':
MyApp().run()
Это похоже на работу с обновлением содержимого ListView (решает эту проблему, но вводит еще один), но в инициализации FUNC я начинаю с 5 пунктов и созданного самостоятельно. list_view настроен на такой размер, я думаю. Поэтому, если есть много элементов, он не сможет прокрутить до конца списка. Я думал о редактировании свойства ListView.row_height, но не знаю формулы. Кто-нибудь знает, как я могу это сделать? Другим решением было бы создать новый ListView каждый раз и изменить содержимое tabbedPanel, так что мы снова вернемся к той же проблеме – lirre
Ах, поэтому вы имеете в виду, что при обновлении списка с большим количеством элементов вы не можете прокручивать до конца, потому что это замки на первоначальной высоте? Я думаю, что это активная ошибка со списком (она уже давно), которая уже может быть исправлена в kivy master, или скоро будет, если нет. Какую версию ты используешь? – inclement
Да, это почти правильно. Я думаю, что ListView имеет некоторый параметр высоты, например scrollHeight или что-то (возможно, ListView.row_height), которое он устанавливает на основе количества элементов, которые у меня есть в ListView (в этом случае 5). Поэтому, когда я генерирую более 15 предметов, он останавливается на 15 элементах. Можно прокручивать больше и просматривать еще несколько предметов, но затем он возвращается к просмотру 15 предметов при остановке анимации прокрутки. Я использую версию Kivy 1.7.2 для окон. – lirre