我在_on_keyboard_down
。标签中使用Tree View
事件,使用up
和down
键进行选择。我在Tree View
List.Can中添加了滚动条有人告诉我如何在需要滚动时使用up
和down
进行滚动?
class TreeviewGroup(Popup):
treeview = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
popup = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
rows = [('test1'),('test2'),('test3'),('test4'),('test5'),('test6')]
tree = []
for r in rows:
tree.append({'node_id': r, 'children': []})
for branch in tree:
populate_tree_view(self.tv, None, branch)
#self.remove_widgets()
self.treeview.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
self.bind(on_open=self.on_open)
def on_open(self, *args):
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
if self.tv.selected_node is None:
self.tv.select_node(self.tv.root.nodes[0])
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
node = self.tv.selected_node
_, key = keycode
if key in ('down', 'up'):
parent = node.parent_node
ix = parent.nodes.index(node)
nx = ix+1 if 'down' else ix-1
next_node = parent.nodes[nx % len(parent.nodes)]
self.tv.select_node(next_node)
return True
elif key == 'enter':
App.get_running_app().root.name.text = node.text
keyboard.release()
self.dismiss()
def remove_widgets(self):
for child in [child for child in self.treeview.children]:
self.treeview.remove_widget(child)
def update(self, *args):
self.h = len([child for child in self.tv.children]) * 24
<TreeviewGroup>:
treeview: treeview
title: "Select"
title_size: 17
title_font: "Verdana"
size: 800, 800
auto_dismiss: False
BoxLayout
orientation: "vertical"
ScrollView:
size_hint: 1, .9
BoxLayout:
size_hint_y: None
id: treeview
height: root.h
GridLayout:
cols : 2
row_default_height: '20dp'
size_hint: .5, 0.2
pos_hint: {'x': .25, 'y': 1}
Button:
text: 'Ok'
on_release: root.dismiss()
Button:
text: 'Cancel'
on_release: root.dismiss()
<TreeViewLabel>:
text_size: self.size
height: 30
答案 0 :(得分:3)
您必须使用scroll_to()
方法并传递节点,您还必须将BoxLayout
(self.treeview)的高度设置为内容的大小,在本例中为{ {3}}(self.tv)。
因此,您必须删除.kv中的height: root.h
,并且当您在.py中创建TreeView
时,除了删除不必要的更新方法之外,我们将在那里进行连接并且会中断TreeView
的操作。
我不明白为什么它是值24
:
self.h = len([child for child in self.tv.children]) * 24
30
这是TreeViewLabel
的高度不合适,除了使用Clock
这种类型的任务是不合适的,使用{{1 }}:
bind()
是解决方案。
您还必须更改:
self.tv.bind(minimum_height=self.treeview.setter('height'))
到
nx = ix+1 if 'down' else ix-1
否则你永远无法攀登。
进行所有这些更改的解决方案是:
<强> *。PY 强>
nx = ix+1 if key == 'down' else ix-1
<强> *。KV 强>
class TreeviewGroup(Popup):
treeview = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
popup = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
rows = [('test{}').format(i) for i in range(1, 20)]#[('test1'),('test2'),('test3'),('test4'),('test5'),('test6')]
tree = [{'node_id': r, 'children': []} for r in rows]
self.tv.bind(minimum_height=self.treeview.setter('height'))
for branch in tree:
populate_tree_view(self.tv, None, branch)
#self.remove_widgets()
self.treeview.add_widget(self.tv)
self.bind(on_open=self.on_open)
def on_open(self, *args):
self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
self._keyboard.bind(on_key_down=self._on_keyboard_down)
if self.tv.selected_node is None:
self.tv.select_node(self.tv.root.nodes[0])
def _keyboard_closed(self):
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
node = self.tv.selected_node
_, key = keycode
if key in ('down', 'up'):
parent = node.parent_node
ix = parent.nodes.index(node)
nx = ix+1 if key == 'down' else ix-1
next_node = parent.nodes[nx % len(parent.nodes)]
self.tv.select_node(next_node)
self.scroll.scroll_to(next_node)
return True
elif key == 'enter':
App.get_running_app().root.name.text = node.text
keyboard.release()
self.dismiss()
def remove_widgets(self):
for child in [child for child in self.treeview.children]:
self.treeview.remove_widget(child)
建议,使用适当的名称,例如BoxLayout的名称似乎表示TreeView的名称,这会导致混淆,使其代码的可读性降低。