【问题标题】:Kivy : How to use on_key_down and on_key_up keyboard event in Tree View?Kivy:如何在树视图中使用 on_key_down 和 on_key_up 键盘事件?
【发布时间】:2018-04-01 04:53:00
【问题描述】:

我正在使用python-2.7kivy-1.10.0
当我点击 name TextInput 然后树视图显示。 我希望使用updown 键选择标签,当按下enter 键时,文本被复制选定的文本被复制到初始表单,因为它是当前完成时单击项目

test.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()

test.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()

【问题讨论】:

  • @eyllanesc 抱歉给您带来不便。使用键盘向上、向下遍历
  • @eyllanesc 谢谢。是的,正是我想这样做。
  • 您可以使用on_keyboard_downevent监控关键事件。也试试这个stackoverflow question
  • @eyllanesc 非常感谢。我更新了问题。
  • @eyllanesc 我只是在尝试。

标签: python python-2.7 kivy kivy-language


【解决方案1】:

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

  • 为此我们使用Keyboard 检测密钥。
  • 节点的选择,为此我们使用TreeViewselect_node() 方法,它允许我们选择特定节点,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()

...

【讨论】:

  • thanks.updown 键工作正常,但是当按下 enter 键时,不会将文本复制到 TextBox
  • @macsontaylor 你试过了吗?我刚刚尝试过,它可以工作,你的意思是什么文本框,与 Code 或 Name 对齐?你是否从 TreeviewGroup 和 GroupScreen 中删除了 select_node ?
  • 键盘中有 2 个回车键。一个 enter 键工作正常,但另一个不工作。很奇怪
  • @macsontaylor 打印变量 key 当您按下不适合您的输入键时。
  • @macsontaylor 然后将elif key == 'enter': 更改为elif key in ('enter', 'numpadenter'):。它更优雅,因为您不会不必要地重复代码。
猜你喜欢
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 2022-08-10
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
相关资源
最近更新 更多