Изменение ширины столбца повторного просмотра - PullRequest
0 голосов
/ 09 ноября 2018

RecycleView доставляет мне некоторые проблемы, особенно при изменении столбцов на определенный размер. Я закодировал предполагаемую ширину столбца с GridLayout выше RecycleView. Я также сделал странный способ выделить целую строку, когда одна ячейка выделена с помощью модуля. Я не уверен, что это лучший способ, но мне бы хотелось, чтобы другие высказались об этом методе.

В конечном итоге я захочу удалить всю строку, а затем выбранные данные в файле JSON. Но сейчас я просто хочу ширину подходящего размера.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.storage.jsonstore import JsonStore
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior

kv_string = """

ScreenManager:
    id: manager

    Screen:
        BoxLayout:
            orientation: 'vertical'
            canvas:
                Color:
                    rgba: .2,.2,.5,1
                Rectangle:
                    pos: self.pos
                    size: self.size

            GridLayout:
                size_hint_y: .3
                cols:4
                MyButton:
                    text: 'Num'
                    size_hint_x: 0.5
                MyButton:
                    text: 'Ratings'
                MyButton:
                    text: 'Name'
                    size_hint_x: 2
                MyButton:
                    text: 'Score'
                    on_press:
                        #arrange the boxing in ascending or descending order

            RecycleView:
                data: [{'text': str(x)} for x in app.data]
                viewclass: 'SelectableLabel'

                SelectableRecycleGridLayout:
                    cols: 4
                    #default_size: None, dp(26)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
                    multiselect: True
                    touch_multiselect: True

            ToggleButton:
                id: toggle_button
                size_hint_y: .3
                text: 'Delete Selected'
                state: 'normal'
                on_press:
                    app.data = [0]

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size

<MyButton@Button>:
    background_color: 0,0,0,1
"""
class SelectableLabel(RecycleDataViewBehavior, Label):
    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        return super(SelectableLabel, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        if super(SelectableLabel, self).on_touch_down(touch):
            return True

        # *** This selects the whole row *** # Not sure if this is the best way.
        if self.collide_point(*touch.pos) and self.selectable:
            self.parent.select_with_touch(self.index, touch)
            if self.index % 4 == 0:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index + 3)
                return
            elif self.index % 4 == 1:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index + 2)
                self.parent.select_with_touch(self.index -1)
                return
            elif self.index % 4 == 2:
                self.parent.select_with_touch(self.index + 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index -1)
                return
            elif self.index % 4 == 3:
                self.parent.select_with_touch(self.index - 1)
                self.parent.select_with_touch(self.index - 2)
                self.parent.select_with_touch(self.index - 3)
                return

    def apply_selection(self, rv, index, is_selected):
        self.selected = is_selected

        if App.get_running_app().root.ids.toggle_button.state == 'down':
            print('Deleted', index) #Still need to add delete function
            rv.layout_manager.clear_selection() #Not working
            self.remove_widget(index) #Also not working

class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior, RecycleGridLayout):
    pass

class MyApp(App):

    data = [] #ListProperty?

    store = JsonStore('file.json')
    store.put('Example: 1', value_1 = 'Rating: C', value_2 = 'Score: 10', value_3 = 'Name: Zack')
    store.put('Example: 2', value_1 = 'Rating: A', value_2 = 'Score: 32', value_3 = 'Name: Pete')
    store.put('Example: 3', value_1 = 'Rating: B', value_2 = 'Score: 24', value_3 = 'Name: Toby')
    store.put('Example: 4', value_1 = 'Rating: D', value_2 = 'Score: 03', value_3 = 'Name: Lars')

    x = 0

    for rows in store.keys():
        x += 1
        data.append(x)
        for row in store.get(rows):
            data.append(store.get(rows)[row])

    print(data) #shows successfully appended

    def build(self):
        root_widget = Builder.load_string(kv_string)
        return root_widget

if __name__ == "__main__":
    MyApp().run()

1 Ответ

0 голосов
/ 10 ноября 2018

Вид некрасивого хака, но вы можете добавить refresh_view_layout метод к вашему SelectableLabel классу:

def refresh_view_layout(self, rv, index, layout, viewport):
    mod = index % 4
    if mod == 0:
        layout['size_hint'] = (0.15, None)
    elif mod == 1:
        layout['size_hint'] = (0.225, None)
    elif mod == 2:
        layout['size_hint'] = (0.225, None)
    elif mod == 3:
        layout['size_hint'] = (0.4, None)
    super(SelectableLabel, self).refresh_view_layout( rv, index, layout, viewport)

Итак, вы можете установить size_hint для каждого SelectableLabel на то, что вы хотите. Если вы согласитесь size_hint_x с size_hint_x, который используется для заголовков ваших столбцов Button, я думаю, вы получите то, что хотите.

...