python - 基维 : How to use on_key_down and on_key_up keyboard event in Tree View?

标签 python python-2.7 kivy kivy-language

我正在使用python-2.7kivy-1.10.0
当我点击 name TextInput 时,就会显示 TreeView 。 我希望使用 updown 键选择标签,当按下 enter 键时,将复制所选文本复制到初始表单,就像您单击该项目时当前完成的那样

测试.py

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.label import Label
from kivy.properties import ObjectProperty
Window.size = (500, 200)


def populate_tree_view(tree_view, parent, node):
    if parent is None:
        tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
                                                     is_open=True))
    else:
        tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
                                                     is_open=True), parent)

    for child_node in node['children']:
        populate_tree_view(tree_view, tree_node, child_node)


tree = []
rows = [(1, 'test1', 11), (2, 'test2', 2), (3, 'test3', 3)]
for r in rows:
    tree.append({'node_id': r[1], 'children': []})



class TreeViewLabel(Label, TreeViewNode):
    pass


class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    #ti = ObjectProperty()

    def __init__(self, **kwargs):
        super(TreeviewGroup, self).__init__(**kwargs)
        self.tv = TreeView(root_options=dict(text=""),
                       hide_root=False,
                       indent_level=4)
        for branch in tree:
            populate_tree_view(self.tv, None, branch)
        self.remove_widgets()
        self.treeview.add_widget(self.tv)

    def remove_widgets(self):
        for child in [child for child in self.treeview.children]:
            self.treeview.remove_widget(child)

    def select_node(self, node):
        '''Select a node in the tree.
                '''
        if node.no_selection:
            return
        if self._selected_node:
            self._selected_node.is_selected = False
        node.is_selected = True
        self._selected_node = node
        print(node)

class GroupScreen(Screen):
    name = ObjectProperty(None)
    popup = ObjectProperty(None)

    def display_groups(self, instance):
        if len(instance.text) > 0:
            if self.popup is None:
                self.popup = TreeviewGroup()
            #self.popup.filter(instance.text)
            self.popup.open()


    def select_node(self, node):
        '''Select a node in the tree.
                '''
        if node.no_selection:
            return
        if self._selected_node:
            self._selected_node.is_selected = False
        node.is_selected = True
        self._selected_node = node
        print(node)


class Group(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        return self.root


if __name__ == '__main__':
    Group().run()

测试.kv

#:kivy 1.10.0

<TreeViewLabel>:
    on_touch_down:
        app.root.name.text = self.text
        app.root.popup.dismiss()

<TreeviewGroup>:
    id: treeview
    treeview: treeview
    title: "Select"
    size_hint: None, None
    size: 400, 200
    auto_dismiss: False

    BoxLayout
        orientation: "vertical"
        #TextInput:
            #id: ti
            #size_hint_y: .1
            #on_text: root.filter(self.text)
        BoxLayout:
            id: treeview
        Button:
            size_hint: 1, 0.1
            text: "Close"
            on_release: root.dismiss()


<CustomLabel@Label>:
    text_size: self.size
    valign: "middle"
    padding_x: 5

<SingleLineTextInput@TextInput>:
    multiline: False

<GreenButton@Button>:
    background_color: 1, 1, 1, 1
    size_hint_y: None
    height: self.parent.height * 0.150

GroupScreen:
    name: name
    test:test

    GridLayout:
        cols: 2
        padding : 30,30
        spacing: 10, 10
        row_default_height: '40dp'

        CustomLabel:
            text: 'Code'

        SingleLineTextInput:
            id: test
            multiline: False
            on_text_validate: name.focus = True


        CustomLabel:
            text: 'Name'

        SingleLineTextInput:
            id: name
            text:' '
            multiline: False
            on_focus: root.display_groups(self)



        GreenButton:
            text: 'Ok'

        GreenButton:
            text: 'Cancel'
            on_press: app.stop()

最佳答案

您的要求可以分为 2 个任务:

  • 我们使用的 key 检测Keyboard .
  • 选择节点,为此我们使用select_node()方法TreeView这允许我们选择一个特定的节点,selected_node返回当前选定的节点。 (您不应覆盖 select_node 方法,应将其从代码中删除。)

....
class TreeviewGroup(Popup):
    treeview = ObjectProperty(None)
    tv = ObjectProperty(None)
    #ti = ObjectProperty()

    def __init__(self, **kwargs):
        super(TreeviewGroup, self).__init__(**kwargs)
        self.tv = TreeView(root_options=dict(text=""),
                       hide_root=False,
                       indent_level=4)
        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 '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()

    ...

class GroupScreen(Screen):
    name = ObjectProperty(None)
    popup = ObjectProperty(None)

    def display_groups(self, instance):
        if len(instance.text) > 0:
            if self.popup is None:
                self.popup = TreeviewGroup()
            #self.popup.filter(instance.text)
            self.popup.open()

...

关于python - 基维 : How to use on_key_down and on_key_up keyboard event in Tree View?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49594923/

相关文章:

python - 无法pickle Python 类实例

python - Py2exe (Python Pygame) - 难道没有更简单的方法吗?

python - 如何在 python 中使用 pylint 获取简短摘要或错误和警告的确切数量

Python,UnicodeDecodeError 尝试打印包含非 ascii 字符的异常

python - 为什么我不能访问 Screen.ids?

python - Kivy kv 文件不工作

python - 将功能分解为被动(算法)和主动(执行)对象

python - 在 Pandas 中,如何用最接近的非纳米值替换零值?

python - 将列表中的大整数值拆分为多个列表中的较小整数

python - 如何在 kivy 应用程序退出时运行方法