我尝试做一些与Kivy Listview示例非常类似的事情 - 我使用Builder和kv创建一个ListView并用文本文件中的行填充它。我的问题是我无法弄清楚如何绑定回调,因此我可以将所选行的文本移到列表框中。我的代码:
from kivy.uix.listview import ListView, ListItemButton
from kivy.uix.gridlayout import GridLayout
from kivy.uix.modalview import ModalView
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
Builder.load_string("""
#:import label kivy.uix.label
#:import sla kivy.adapters.simplelistadapter
<ListViewModal>:
size_hint: None, None
size: 400, 400
ListView:
id: listview_modal
#on_selection_change: callback # <==== attempt #1
size_hint: .8, .8
adapter:
sla.SimpleListAdapter(
data=[s.strip() for s in open('/Users/zen/Dropbox/todo/todo.txt').readlines()],
cls=label.Label,
selection_mode='single',
allow_empty_selection=True)
#on_selection_change: callback # <===== attempt #2
""")
class ListViewModal(ModalView):
def __init__(self, **kwargs):
super(ListViewModal, self).__init__(**kwargs)
class MainView(GridLayout):
'''Implementation of a simple list view that reads data from a file.
'''
def __init__(self, **kwargs):
kwargs['cols'] = 2
super(MainView, self).__init__(**kwargs)
self.listview_modal = ListViewModal()
self.add_widget(self.listview_modal)
text_input = TextInput()
self.add_widget(text_input)
def callback(self, adapter):
self.text_input.text = adapter.selection.text
if __name__ == '__main__':
from kivy.base import runTouchApp
runTouchApp(MainView(width=800))
我还尝试过添加ID和属性的各种组合,以便能够访问MainView类中的适配器,但都无济于事。
任何建议都将不胜感激!
答案 0 :(得分:0)
第一个问题是你正在使用SimpleListAdapter
- 它很简单&#39;因为它不支持选择。请改用常规ListAdapter
。您还需要使用ListItemButton
来支持选择。 on_selection_change
事件必须绑定Python,而不是kv,否则它不会起作用。最后,您还遇到了text_input
窗口小部件的几个问题,并尝试从text
获取adapter.selection
,这是一个列表而不是窗口小部件。
我已更新您的代码并使用评论注释我的更改。
Builder.load_string("""
#:import ListItemButton kivy.uix.listview.ListItemButton
#:import la kivy.adapters.listadapter
<ListViewModal>:
size_hint: None, None
size: 400, 400
ListView:
id: listview_modal
size_hint: .8, .8
adapter:
la.ListAdapter(
data=[s.strip() for s in open('/Users/zen/Dropbox/todo/todo.txt').readlines()],
cls=ListItemButton, ### use ListItemButton instead of Label
selection_mode='single',
allow_empty_selection=True)
""")
class ListViewModal(ModalView):
def __init__(self, **kwargs):
super(ListViewModal, self).__init__(**kwargs)
### Bind to `on_selection_change` here in `__init__`
self.ids['listview_modal'].adapter.bind(on_selection_change=self.callback)
### in `__init__`, we don't have a parent yet, so we proxy the callback
def callback(self, adapter):
return self.parent.callback(adapter)
class MainView(GridLayout):
'''Implementation of a simple list view that reads data from a file.
'''
def __init__(self, **kwargs):
kwargs['cols'] = 2
super(MainView, self).__init__(**kwargs)
self.listview_modal = ListViewModal()
self.add_widget(self.listview_modal)
self.text_input = TextInput() ### use `self.text_input` instead of `text_input`
self.add_widget(self.text_input)
def callback(self, adapter):
self.text_input.text = adapter.selection[0].text ### get `text` from the first selected item