【问题标题】:Kivy - Editable RecycleViewKivy - 可编辑的回收视图
【发布时间】:2017-12-04 09:29:30
【问题描述】:

我正在尝试使用 TextInput 小部件作为 Kivy 中的单个元素创建一个带有 RecycleView 小部件的可编辑表格。通过查看示例和网络上的一些帖子,我能够编写一个接受用户输入的表格。

现在我正在尝试获取用户编辑的行。我可以找到文本输入的 on_text 事件,但这并没有提供有关行号的信息。我还尝试查看可用于 RecycleView 的事件,但无法从中获得太多帮助。

你们中的任何人都可以引导我走上正确的道路吗?我对kivy还很陌生。我附上了一个我正在研究的简单示例。

from kivy.app import App
from kivy.uix.recycleview import RecycleView
from kivy.lang import Builder


Builder.load_string('''
<Row@BoxLayout>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    itemText: ''
    TextInput:
        id:CellText
        text:root.itemText


<RV>:
    id: rv
    viewclass: 'Row'
    scroll_type: ['bars', 'content']
    scroll_wheel_distance: dp(114)
    bar_width: dp(10)
    RecycleGridLayout:
        cols:3
        default_size: None, dp(30) 
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        spacing: dp(1)
''')


class RV(RecycleView):

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'itemText':'1'}, {'itemText':'John'}, {'itemText':'K'}, {'itemText':'2'}, {'itemText':'David'}, {'itemText':'P'}]


class rvTestApp(App):

    def build(self):
        return RV()

if __name__ == '__main__':
    rvTestApp().run()

【问题讨论】:

    标签: python kivy textinput


    【解决方案1】:

    我不知道以下是否可推荐,但是,当我在回收视图数据中添加一个框时,我将它传递给回收视图实例,并在创建该框时将其添加到回收列表中视图,以便您可以从每个盒子控制 rv,并且您可以从 rv 控制每个盒子:

    from kivy.app import App
    from kivy.uix.recycleview import RecycleView
    from kivy.uix.boxlayout import BoxLayout
    from kivy.lang import Builder
    from kivy.properties import ObjectProperty, ListProperty
    from kivy.clock import Clock
    
    Builder.load_string('''
    <Row>:
        canvas.before:
            Color:
                rgba: 0.5, 0.5, 0.5, 1
            Rectangle:
                size: self.size
                pos: self.pos
        itemText: ''
        TextInput:
            id:CellText
            text:root.itemText
    
    
    <RV>:
        id: rv
        viewclass: 'Row'
        scroll_type: ['bars', 'content']
        scroll_wheel_distance: dp(114)
        bar_width: dp(10)
        RecycleGridLayout:
            cols:3
            default_size: None, dp(30) 
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(1)
    ''')
    
    
    class RV(RecycleView):
        list_items = ListProperty([])
    
        def __init__(self, **kwargs):
            super(RV, self).__init__(**kwargs)
            self.data = [{'itemText': '1', 'paren': self, 'index':0}, {'itemText': 'John', 'paren': self, 'index':1},
                     {'itemText': 'K', 'paren': self, 'index':2}, {'itemText': '2', 'paren': self, 'index':3},
                     {'itemText': 'David', 'paren': self, 'index':4}, {'itemText': 'P', 'paren': self, 'index':5}]
    
        def which_edit(self, *args):
            '''This will print the index of the box which is currently edited'''
            print args[0].parent.index 
    
    
    class Row(BoxLayout):
        paren = ObjectProperty() #the instance of the rv
    
        def __init__(self, **kwargs):
            super(Row, self).__init__(**kwargs)
            Clock.schedule_once(self.update)
    
        def update(self, *args):
            self.paren.list_items.append(self)
            self.ids.CellText.bind(text=self.paren.which_edit)
    
    
    class TestApp(App):
    
        def build(self):
            return RV()
    
    if __name__ == '__main__':
        TestApp().run()
    

    【讨论】:

    • 感谢您的建议。我认为这会很好,即使它看起来更像是一种解决方法。
    【解决方案2】:

    SP SP 的答案可以解决这个问题,但我找到了另一种方法(希望这是一个更好的方法)来获取行索引。

    将以下覆盖函数添加到行类中有助于我在用户单击文本输入时获取行索引。

    class Row(BoxLayout, RecycleDataViewBehavior):
    index = None
    
    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(Row, self).refresh_view_attrs(
            rv, index, data)
    
    def on_touch_down(self, touch):
        if super(Row, self).on_touch_down(touch):
            return True
        if self.collide_point(*touch.pos):
            global rowIndex
            rowIndex = self.index
    

    再次感谢您帮助我提出建议。发布我的解决方案以防其他人面临同样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多