kivy:如何使用滚动工作_on_keyboard_down事件

时间:2018-04-02 04:48:07

标签: python-2.7 kivy kivy-language

我在_on_keyboard_down。标签中使用Tree View事件,使用updown键进行选择。我在Tree View List.Can中添加了滚动条有人告诉我如何在需要滚动时使用updown进行滚动?

的.py

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

.kv

<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

1 个答案:

答案 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的名称,这会导致混淆,使其代码的可读性降低。