我正在使用Kivy和Python开发运输应用程序。用户在其中有一个TextInput字段,此字段开始输入出发站的名称。在文本输入中,将显示带有可选出发站名称的RecycleView。用户单击出发站名称后,应将出发站的名称复制到TextInput字段,并且RecycleView应该消失,直到用户再次开始在该字段中键入。
现在,我不知道如何将用户在RecycleView中选择的出发站名称复制到文本输入字段。
search_trip.kv示例:
<MatchedStops>:
orientation: "vertical"
DepartureStopName:
id: departure_stop
hint_text: "Departure stop"
multiline: False
on_text:
root.find_stop(departure_stop.text)
RecycleView:
viewclass: 'SelectableLabel'
data: [{'text': str(x["stop_name"])} for x in root.stops_data]
SelectableRecycleGridLayout:
cols: 1
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
search_trip.py的示例:
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, ListProperty, BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import (
ScreenManager,
Screen,
NoTransition,
)
from search_stops.search import match_stop
Builder.load_file("search_trip.kv")
class TransportSearchApp(App):
def build(self):
screen_manager = ScreenManager(transition=NoTransition())
screen_manager.add_widget(TripSearchScreen(name="search_trip_screen"))
return screen_manager
class TripSearchScreen(Screen):
pass
class MatchedStops(BoxLayout):
stops_data = ListProperty([])
departure_stop_name = ObjectProperty()
def find_stop(self, stop: str) -> None:
matched_stops = match_stop(stop)
self.stops_data = matched_stops
def fill_departure_stop_name(self, dept_stop_name):
self.ids.departure_stop.text = dept_stop_name
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior, RecycleGridLayout):
""" Adds selection and focus behaviour to the view. """
class SelectableLabel(RecycleDataViewBehavior, Label):
"""Add selection support to the Label"""
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
"""Catch and handle the view changes"""
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
"""Add selection on touch down"""
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
"""Respond to the selection of items in the view."""
self.selected = is_selected
if is_selected and rv.data[index]["text"] != "None":
matched_stops = MatchedStops()
matched_stops.departure_stop_name = rv.data[index]["text"]
matched_stops.fill_departure_stop_name(rv.data[index]["text"])
if __name__ == "__main__":
TransportSearchApp().run()
我认为我可能需要直接在DepartureStopName
类上编辑文本输入,即执行以下操作:
class DepartureStopName(TextInput):
text = StringProperty()
def update_stop_name(self, txt):
self.text = txt
但是我也没有设法做到这一点-在这种情况下,文本输入字段始终为空,并且根本不显示RecycleView。