正如标题所示,我试图制作一个固定标题和单元格大小为w400 x h60的数据表。如果标签内的文本超过400的宽度,则标签应水平滚动。下面发布的代码是我最接近的代码。
检查树时,ScrollCell(BoxLayout)的尺寸为100x100,并且不会满足给定尺寸或填充RecycleGridLayout的deafult col /行宽度/高度。
以下是它的外观:
感谢您解决此问题的任何帮助。
rtable.py:
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.recycleview import RecycleView
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty, StringProperty
import kivy
kivy.require('1.10.0')
class HeaderCell(Label):
pass
class TableHeader(ScrollView):
"""Fixed table header that scrolls x with the data table"""
header = ObjectProperty(None)
def __init__(self, list_dicts=None, *args, **kwargs):
super(TableHeader, self).__init__(*args, **kwargs)
titles = list_dicts[0].keys()
for title in titles:
self.header.add_widget(HeaderCell(text=title))
class ScrollCell(BoxLayout):
text = StringProperty(None)
is_even = BooleanProperty(None)
class TableData(RecycleView):
nrows = NumericProperty(None)
ncols = NumericProperty(None)
rgrid = ObjectProperty(None)
def __init__(self, list_dicts=[], *args, **kwargs):
self.nrows = len(list_dicts)
self.ncols = len(list_dicts[0])
super(TableData, self).__init__(*args, **kwargs)
self.data = []
for i, ord_dict in enumerate(list_dicts):
is_even = i % 2 == 0
row_vals = ord_dict.values()
for text in row_vals:
self.data.append({'text': text, 'is_even': is_even})
class Table(BoxLayout):
def __init__(self, list_dicts=[], *args, **kwargs):
super(Table, self).__init__(*args, **kwargs)
self.orientation = "vertical"
self.header = TableHeader(list_dicts=list_dicts)
self.table_data = TableData(list_dicts=list_dicts)
self.table_data.fbind('scroll_x', self.scroll_with_header)
self.add_widget(self.header)
self.add_widget(self.table_data)
def scroll_with_header(self, obj, value):
self.header.scroll_x = value
if __name__ == '__main__':
from kivy.app import App
from collections import OrderedDict
class RtableApp(App):
def build(self):
data = []
keys = ["Title Col: {}".format(i + 1) for i in range(15)]
for nrow in range(30):
row = OrderedDict.fromkeys(keys)
for i, key in enumerate(keys):
row[key] = "Data col: {}, row: {}".format(i + 1, nrow + 1)
if i % 3 == 0:
row[key] = row[key] + ". Extra long label. " * 3
data.append(row)
return Table(list_dicts=data)
RtableApp().run()
rtable.kv:
<HeaderCell>
size_hint: (None, None)
height: 60
width: 400
text_size: self.size
halign: "left"
valign: "middle"
background_disabled_normal: ''
disabled_color: (1, 1, 1, 1)
canvas.before:
Color:
rgba: 0.165, 0.165, 0.165, 1
Rectangle:
pos: self.pos
size: self.size
<TableHeader>:
header: header
bar_width: 0
do_scroll: False
size_hint: (1, None)
effect_cls: "ScrollEffect"
height: 60
GridLayout:
id: header
rows: 1
size_hint: (None, None)
width: self.minimum_width
height: self.minimum_height
<ScrollCell>:
orientation: 'horizontal'
label: label
size_hint: (None, None)
size: (400, 60)
text: ''
canvas.before:
Color:
rgba: [0.23, 0.23, 0.23, 1] if self.is_even else [0.2, 0.2, 0.2, 1]
Rectangle:
pos: self.pos
size: self.size
ScrollView:
scroll_type: ['bars', 'content']
do_scroll_x: True
do_scroll_y: False
effect_cls: "ScrollEffect"
Label:
id: label
text_size: None, self.height
size_hint: (None, 1)
width: self.texture_size[0]
text: root.text
padding_x: 10
<TableData>:
rgrid: rgrid
bar_width: 25
scroll_type: ['bars']
bar_color: [0.2, 0.7, 0.9, 1]
bar_inactive_color: [0.2, 0.7, 0.9, .5]
do_scroll_x: True
do_scroll_y: True
effect_cls: "ScrollEffect"
viewclass: "ScrollCell"
RecycleGridLayout:
id: rgrid
rows: root.nrows
cols: root.ncols
size_hint: (None, None)
width: self.minimum_width
height: self.minimum_height
col_default_width: 400
row_default_height: 60