如何使用Kivy RecycleView选择整行

时间:2019-02-01 16:53:41

标签: python kivy kivy-language recyclerview-layout

我是python的新手,但是是Kivy的完整入门者。我发现有关Kivy的文档至少对于我来说很难解释。到目前为止,我已经能够创造一个RecycleView我在哪里可以添加,删除和更改数据。理想情况下,我希望能有尽可能多的列我想,但都在每行数据属于一起。因此,如果我选择一个,则要突出显示该行上的所有项目。我已经尝试过切换按钮,但没有成功。我根本不知道怎么我可以通过ID或其他方法在RecycleView访问每个单独的切换按钮。如果我可以分别访问每个切换按钮,则只需将其状态更改为等于“向下”即可。到目前为止,我只能找到用户选择的行(但是并不是那么优雅)。我通过计算每行的按钮的数目和针对所选择的按钮的索引比较该管理这一点。

这里是我试验,一般我喜欢使用.kv文件的示例:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.recycleview.views import RecycleDataViewBehavior


class MyButton(RecycleDataViewBehavior, ToggleButton):
    index = None

    def refresh_view_attrs(self, rv, index, data):
        """ Catch and handle the view changes """
        self.index = index
        return super(MyButton, self).refresh_view_attrs(
            rv, index, data)


class TestRecycleView(RecycleView):
    items_per_row = 3
    selected_data = None
    selected_row = None

    def find_row(self, instance):
        self.selected_row = instance.index // self.items_per_row + 1
        print('Row: ', self.selected_row)
        self.selected_data = self.data[(self.selected_row - 1) * self.items_per_row: self.items_per_row
                                       * self.selected_row]
        print('Data: ', self.selected_data)


KV = '''

<MyButton>:
    on_release:
        app.root.find_row(self)

TestRecycleView:
    data: [{'text': str(x)} for x in range(21)]
    viewclass: 'MyButton'
    id: rv_controller
    target_id: None
    RecycleGridLayout:
        cols: 3
        default_size_hint: 1, None
        orientation: 'vertical'
        key_selection: 'selectable'
        default_size: None, dp(26)
        size_hint_y: None
        height: self.minimum_height
        multiselect: True
        touch_multiselect: True

'''


class Test(App):
    def build(self):
        root = Builder.load_string(KV)
        # root.data = items
        return root


Test().run()

由于我已经能够计算出用户选择了哪一行,所以我也可以计算出RecycleView中正在选择的数据。但是,对于这种行选择,我想要一个简洁的视觉表示。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以在for forecast in data.weatherdata.forecast.tabular: print ("time is " + forecast.time['from'] + "and temperature is " + forecast.time.temperature['value']) 方法中添加hack,以设置一行中所有按钮的状态。此方法将它们设置为与所选print (forecast.time['from'] + forecast.time.temperature['value']) TypeError: list indices must be integers, not str 实例的状态一致,因此您也可以取消选择。

find_row()

这还需要将Button的ID设置为:

def find_row(self, instance):
    rgl = self.ids.gl
    num_buttons = len(rgl.children)
    num_rows = num_buttons // self.items_per_row
    self.selected_row = instance.index // self.items_per_row + 1
    print('Row: ', self.selected_row)
    self.selected_data = self.data[(self.selected_row - 1) * self.items_per_row: self.items_per_row
                                   * self.selected_row]
    print('Data: ', self.selected_data)
    index1 = (num_rows - self.selected_row + 1) * self.items_per_row - 1
    index2 = index1 - self.items_per_row
    state = instance.state
    for index in range(index1, index2, -1):
        rgl.children[index].state = state

RecycleGridLayoutid: gl 的子代,因此可以用来获取Buttons的总数。 RecycleGridLayout列表中的索引与您期望的相反。也就是说,标记为Buttons的{​​{1}}是索引children,标记为Button的{​​{1}}是索引0。因此,20的计算使用该知识来确定所选行中最左边的Button的索引。然后,所选行中最右边的20将是0index1逐步浏览所选行中的Button。由于Button被称为index - 2range(inde1, index2, -1)的{​​{1}}已被切换,因此可以使用其Buttons来设置find_row()该行中的其他on_release