Python/Kivy : 使用键盘上下键移动光标到动态添加行

Python/Kivy : Move cursor using keyboard up and down key into dynamic add row

我正在使用 python-2.7 和 kivy。当我点击 +Add More 然后行将添加 dynamic.Someone 帮助我如何使用键盘将光标 one row 跳转到 another row
如果光标进入 2nd row2nd column。如果我按 up 键,那么光标应该跳转到 1st row2nd column。并且 如果我按 down 键,那么光标应该跳转到 3rd row2nd column

test.py

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty

Window.size = (450, 325)


class display(Screen):

    def add_more(self):
        self.ids.rows.add_row()


class Row(BoxLayout):
    button_text = StringProperty("")


class Rows(BoxLayout):
    orientation = "vertical"
    row_count = 0

    def __init__(self, **kwargs):
        super(Rows, self).__init__(**kwargs)
        self.add_row()

    def add_row(self):
        self.row_count += 1
        self.add_widget(Row(button_text=str(self.row_count)))


class test(App):

    def build(self):
        return self.root

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

test.kv

<Row>:
    orientation: "horizontal"

    Button:
        text: root.button_text
        size_hint_x: .2

    TextInput:
        size_hint_x: .8

    TextInput:
        size_hint_x: .8


display:

    BoxLayout:
        orientation: "vertical"

        BoxLayout:
            orientation: "horizontal"

            Button:
                size_hint_x: .2
                text: "+Add More"
                valign: 'bottom'
                on_press: root.add_more()


        BoxLayout:
            orientation: "horizontal"

        Rows:
            id: rows

解决方案如follow.Please参考片段,详细示例

片段

请修改此函数:

class display(Screen):

    def __init__(self, **kwargs):
        super(display, self).__init__(**kwargs)
        Window.bind(on_key_down=self._on_keyboard_down)

    def _on_keyboard_down(self, instance, keyboard, keycode, text, modifiers):
        if int(keycode) == 81 or int(keycode) == 82:
            if int(keycode) == 82:
                key = 'up'
            if int(keycode) == 81:
                key = 'down'

            rows = self.ids.rows
            countRowLen = len(rows.children)
            i = 0
            for row in reversed(rows.children):
                i = i + 1
                j = 0
                for ch in reversed(row.children):
                    if isinstance(ch, TextInput):
                        j = j + 1
                        if ch.focus == True:
                            self.params = {'count': countRowLen, 'row':i, 'column':j, 'key':key, 'gridObj': rows}
                            set_focus_grid_use_keyboard(self)
                            return True
            return True

    def add_more(self):
        self.ids.rows.add_row()

添加新功能

def set_focus_grid_use_keyboard(obj):
    if int(obj.params['count']) == int(obj.params['row']) and obj.params['key'] == 'down':
        focusRow = int(1)
    elif int(obj.params['row']) == 1 and obj.params['key'] == 'up':
        focusRow = int(obj.params['count'])
    elif obj.params['key'] == 'down':
        focusRow =  int(obj.params['row']) + 1
    elif obj.params['key'] == 'up':
        focusRow =  int(obj.params['row']) - 1


    i = 0
    for row in reversed(obj.params['gridObj'].children):
        i += 1
        j = 0
        print(i)
        print(focusRow)
        if i == int(focusRow):
            for ch in reversed(row.children):
                if isinstance(ch, TextInput):
                    j += 1
                    if j == int(obj.params['column']):
                        ch.focus = True
                        return False

示例

test.py

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.textinput import TextInput

Window.size = (450, 325)


def set_focus_grid_use_keyboard(obj):
    if int(obj.params['count']) == int(obj.params['row']) and obj.params['key'] == 'down':
        focusRow = int(1)
    elif int(obj.params['row']) == 1 and obj.params['key'] == 'up':
        focusRow = int(obj.params['count'])
    elif obj.params['key'] == 'down':
        focusRow =  int(obj.params['row']) + 1
    elif obj.params['key'] == 'up':
        focusRow =  int(obj.params['row']) - 1


    i = 0
    for row in reversed(obj.params['gridObj'].children):
        i += 1
        j = 0
        print(i)
        print(focusRow)
        if i == int(focusRow):
            for ch in reversed(row.children):
                if isinstance(ch, TextInput):
                    j += 1
                    if j == int(obj.params['column']):
                        ch.focus = True
                        return False


class display(Screen):

    def __init__(self, **kwargs):
        super(display, self).__init__(**kwargs)
        Window.bind(on_key_down=self._on_keyboard_down)

    def _on_keyboard_down(self, instance, keyboard, keycode, text, modifiers):
        if int(keycode) == 81 or int(keycode) == 82:
            if int(keycode) == 82:
                key = 'up'
            if int(keycode) == 81:
                key = 'down'

            rows = self.ids.rows
            countRowLen = len(rows.children)
            i = 0
            for row in reversed(rows.children):
                i = i + 1
                j = 0
                for ch in reversed(row.children):
                    if isinstance(ch, TextInput):
                        j = j + 1
                        if ch.focus == True:
                            self.params = {'count': countRowLen, 'row':i, 'column':j, 'key':key, 'gridObj': rows}
                            set_focus_grid_use_keyboard(self)
                            return True
            return True

    def add_more(self):
        self.ids.rows.add_row()


class Row(BoxLayout):
    button_text = StringProperty("")


class Rows(BoxLayout):
    orientation = "vertical"
    row_count = 0

    def __init__(self, **kwargs):
        super(Rows, self).__init__(**kwargs)
        self.add_row()

    def add_row(self):
        self.row_count += 1
        self.add_widget(Row(button_text=str(self.row_count)))


class test(App):

    def build(self):
        return self.root

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

test.kv

<Row>:
    orientation: "horizontal"

    Button:
        text: root.button_text
        size_hint_x: .2

    TextInput:
        size_hint_x: .8

    TextInput:
        size_hint_x: .8


display:

    BoxLayout:
        orientation: "vertical"

        BoxLayout:
            orientation: "horizontal"

            Button:
                size_hint_x: .2
                text: "+Add More"
                valign: 'bottom'
                on_press: root.add_more()


        BoxLayout:
            orientation: "horizontal"

        Rows:
            id: rows