Kivy,带有可选标签和多列的 RecycleView
Kivy, RecycleView with selectable labels and multiple columns
自从过去几周以来,我一直在非常努力地为 raspberry pi3 构建图形用户界面。现在我遇到的这个问题是,我有一个 table 有四列要显示,其行数取决于数据库中的数据。我正在使用 RecycleView
结构。
下面是我正在处理的项目的实际屏幕截图(我目前似乎没有粘贴图像的特权)。引用的 table 很好地显示了从数据库中获取的 3 行。目前还好。
但现在我需要选择这些行table,而我确实为此苦苦挣扎。我用 SelectableRecycleBoxLayout
和 SelectableRecycleGridLayout
实现了它,但我的数据不再显示在列中,这是我得到的输出。
以下是代码的主要部分,通过这些代码我获得了如屏幕截图 1 所示的结果。请指导如何正确实现选择table 视图。谢谢。
main.py
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)]
dash.kv
<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'
BoxLayout:
orientation : 'horizontal'
size_hint: 1.0,0.10
canvas.before:
Color:
rgba: [0.2,0.2,0.2,1.0]
Rectangle :
pos: self.pos
size: self.size
Label:
text: "sl/no"
size_hint: 0.2,1.0
Label:
text: "Type"
size_hint: 0.4,1.0
Label:
text: "Content"
size_hint: 1.0,1.0
Label:
text: "Duration"
size_hint: 0.4,1.0
BoxLayout:
orientation : 'vertical'
size_hint: 1.0,1.0
MainScreen: # the RecylcleView widget
Label:
size_hint: 1.0, 0.10
text: ""
canvas.before:
Color:
rgba: [0.3,0.3,0.3,1.0]
Rectangle :
pos: self.pos
size: self.size
您需要让您的 RecycleViewRow
class 可选择。
在 python 中,您已经有一个名为 SelectableLabel
的 class。将其名称更改为 RecycleViewRow
并让它派生自 BoxLayout
而不是 Label
。并删除你原来的RecycleViewRow
class。
像这样:
class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):
然后在 kv 中的 RecycleViewRow
之上,定义字符串属性,以确保它将键识别为字符串属性。并将 SelectableLabel
内的内容移动到 RecycleViewRow
顶部并删除 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
自从过去几周以来,我一直在非常努力地为 raspberry pi3 构建图形用户界面。现在我遇到的这个问题是,我有一个 table 有四列要显示,其行数取决于数据库中的数据。我正在使用 RecycleView
结构。
下面是我正在处理的项目的实际屏幕截图(我目前似乎没有粘贴图像的特权)。引用的 table 很好地显示了从数据库中获取的 3 行。目前还好。
但现在我需要选择这些行table,而我确实为此苦苦挣扎。我用 SelectableRecycleBoxLayout
和 SelectableRecycleGridLayout
实现了它,但我的数据不再显示在列中,这是我得到的输出。
以下是代码的主要部分,通过这些代码我获得了如屏幕截图 1 所示的结果。请指导如何正确实现选择table 视图。谢谢。
main.py
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)]
dash.kv
<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'
BoxLayout:
orientation : 'horizontal'
size_hint: 1.0,0.10
canvas.before:
Color:
rgba: [0.2,0.2,0.2,1.0]
Rectangle :
pos: self.pos
size: self.size
Label:
text: "sl/no"
size_hint: 0.2,1.0
Label:
text: "Type"
size_hint: 0.4,1.0
Label:
text: "Content"
size_hint: 1.0,1.0
Label:
text: "Duration"
size_hint: 0.4,1.0
BoxLayout:
orientation : 'vertical'
size_hint: 1.0,1.0
MainScreen: # the RecylcleView widget
Label:
size_hint: 1.0, 0.10
text: ""
canvas.before:
Color:
rgba: [0.3,0.3,0.3,1.0]
Rectangle :
pos: self.pos
size: self.size
您需要让您的 RecycleViewRow
class 可选择。
在 python 中,您已经有一个名为 SelectableLabel
的 class。将其名称更改为 RecycleViewRow
并让它派生自 BoxLayout
而不是 Label
。并删除你原来的RecycleViewRow
class。
像这样:
class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):
然后在 kv 中的 RecycleViewRow
之上,定义字符串属性,以确保它将键识别为字符串属性。并将 SelectableLabel
内的内容移动到 RecycleViewRow
顶部并删除 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