Как выделить всю строку в RecycleView с помощью Kivy - PullRequest
0 голосов
/ 01 февраля 2019

Я довольно новичок в python, но я новичок в Kivy.Я нахожу документацию вокруг Киви трудной для интерпретации, по крайней мере, для меня.До сих пор я был в состоянии создать RecycleView, где я могу добавлять, удалять и изменять данные.В идеале я хочу иметь столько столбцов, сколько хочу, но все данные в каждой строке принадлежат друг другу.Следовательно, если я выберу один, я хочу выделить все элементы в этом ряду.Я пытался с тумблером, но безуспешно.Я просто не знаю, как получить доступ к каждой отдельной кнопке переключения в 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 голосов
/ 04 февраля 2019

Вы можете добавить хак к вашему find_row() методу, чтобы установить состояние всех кнопок в строке.Этот метод устанавливает их в соответствии с состоянием выбранного экземпляра Button, поэтому вы также можете отменить выбор.

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

Для этого также необходимо установить идентификатор RecycleGridLayout как:

id: gl

Buttons - это дочерние элементы RecycleGridLayout, поэтому его можно использовать для получения общего числа Buttons.И индекс в списке children противоположен тому, что вы ожидаете.То есть Button, помеченный 0, является индексом 20, а Button, помеченный 20, является индексом 0.Таким образом, вычисление index1 использует эти знания для определения индекса самой левой Button в выбранной строке.Тогда самый правый Button в выбранной строке будет index - 2.range(inde1, index2, -1) шагает по Buttons в выбранной строке.Поскольку find_row() называется on_release, state instance уже переключен, поэтому его state можно использовать для установки state другого Buttons в строке.

...