Kivy,带有可选标签和多列的RecycleView

时间:2019-05-23 11:47:25

标签: python kivy raspberry-pi3

自上几周以来,我一直在非常努力地为树莓派pi3编写GUI。现在,我遇到的问题是,我有一个要显示四列的表,其行数取决于数据库中的数据。我正在使用2019/05/23 10:57:04 [warn] 6#6: *171 upstream sent more data than specified in "Content-Length" header while reading upstream, client: 193.136.38.232, server: , request: "GET /showcase/media/CoNWeT/map-viewer/2.6.2/index.html?entrypoint=true&v=31cb4ca4c8751f6d04c4242d0b52b176a2c7bc9b&theme=wirecloud.defaulttheme HTTP/1.1", upstream: "http://192.168.224.10:8000/showcase/media/CoNWeT/map-viewer/2.6.2/index.html?entrypoint=true&v=31cb4ca4c8751f6d04c4242d0b52b176a2c7bc9b&theme=wirecloud.defaulttheme", host: "193.136.xx.xx:53152", referrer: "http://193.136.xx.xx:53152/arilwan/urbansense-history-info" 2019/05/23 10:57:34 [error] 6#6: *179 upstream prematurely closed connection while reading response header from upstream, client: 193.136.38.232, server: , request: "POST /cdp/http/193.136.xx.xx:53149/v2/subscriptions HTTP/1.1", upstream: "http://192.168.224.10:8000/cdp/http/193.136.xx.xx:53149/v2/subscriptions", host: "193.136.xx.xx:53152", referrer: "http://193.136.xx.xx:53152/arilwan/urbansense-history-info" 结构。

下面是我正在处理的项目的实际屏幕截图(目前我似乎还没有粘贴图像的特权)。引用的表很好地显示了从数据库中提取的3行。到目前为止还好。

Screenshot 1

但是现在我需要使这些行可以选择,而实际上我正在为此而苦苦挣扎。我用RecycleViewSelectableRecycleBoxLayout实现了它,但是我的数据不再显示在列中,这就是我得到的输出。

Screenshot 2

下面是代码的主要部分,我通过这些部分获得了结果,如Screnshot 1所示。请提供方向如何正确实现可选视图。谢谢。

main.py

SelectableRecycleGridLayout

dash.kv

class RecycleViewRow(BoxLayout):

    slno    = StringProperty('')
    typ     = StringProperty('')
    cont    = StringProperty('')
    dur     = StringProperty('')

#-----------------------------------------------------------------------
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):

    ''' 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)

    slno    = StringProperty('')
    typ     = StringProperty('')
    cont    = StringProperty('')
    dur     = StringProperty('')

    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:
            pass #print("selection changed to {0}".format(rv.data[index]))
        else:
            pass #print("selection removed for {0}".format(rv.data[index]))
#-----------------------------------------------------------------------
class MainScreen(RecycleView):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        #fetch data from the database
        app_ref = App.get_running_app()
        ads = app_ref.fetchAds() #function reads everything from db
        rows = len(ads)
        self.data = [{'slno': str(x+1),'typ': str(ads[x][1]),'cont': str(ads[x][2]),'dur': str(ads[x][3])} for x in range(rows)]

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (0, 0.517, 0.705, 1) if self.selected else (0.4,0.4, 0.4, 1)
        Rectangle:
            pos: self.pos
            size: self.size
    #on_press:

    RecycleViewRow:

#----------------------------------------------------------------
<RecycleViewRow>:
    orientation: 'horizontal'
    size_hint: 1.0, 1.0

    Label:
        text: root.slno
        size_hint_x : 0.2

    Label:
        text: root.typ
        size_hint_x : 0.4

    Label:
        text: root.cont
        size_hint_x : 1.0

    Label:
        text:  root.dur
        size_hint_x : 0.4
#----------------------------------------------------------------
<MainScreen>:
    viewclass: 'RecycleViewRow'
    RecycleBoxLayout:
        default_size: None, dp(40)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'

1 个答案:

答案 0 :(得分:0)

您需要选择RecycleViewRow类。
在python中,您已经有一个名为SelectableLabel的类。将其名称更改为RecycleViewRow,并使其源自BoxLayout而不是Label。并删除原始的RecycleViewRow类。 像这样:

class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):

然后在kv中的RecycleViewRow顶部,定义字符串属性,以确保将键识别为字符串属性。然后将SelectableLabelRecycleViewRow内的内容移到SelectableLabel上。
所以现在看起来应该像这样:

RecycleViewRow:

    slno: ""
    typ: ""
    cont: ""
    dur: ""

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