我正在尝试使用网格布局,我可以对项目进行处理,我可以使用箭头键(向上/向下和向左/向右)进行导航。 这个想法是针对瘦身后期应用程序(即android电视或家庭媒体中心),没有触摸或鼠标。
我试图重复使用FocusBehavior和CompoundSelectionBehavior 我有一些东西几乎就在那里,但我无法弄清楚如何将选择移到下一行,左/右保持在我用鼠标点击的第一行,并且没有&# 39; t move。
from kivy.uix.behaviors.compoundselection import CompoundSelectionBehavior
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.app import App
class SelectableBoxLayout(FocusBehavior, CompoundSelectionBehavior, BoxLayout):
def keyboard_on_key_down(self, window, keycode, text, modifiers):
"""Based on FocusBehavior that provides automatic keyboard
access, key presses will be used to select children.
"""
print(keycode, text, modifiers)
print(self.orientation)
if super(SelectableBoxLayout, self).keyboard_on_key_down(
window, keycode, text, modifiers):
return True
if self.orientation == 'horizontal' and keycode[1] in ['up', 'down']:
self.clear_selection()
return self.parent.keyboard_on_key_down(window, keycode, text, modifiers)
if self.select_with_key_down(window, keycode, text, modifiers):
return True
return False
def keyboard_on_key_up(self, window, keycode):
"""Based on FocusBehavior that provides automatic keyboard
access, key release will be used to select children.
"""
if super(SelectableBoxLayout, self).keyboard_on_key_up(window, keycode):
return True
if self.orientation == 'horizontal' and keycode[1] in ['up', 'down']:
self.clear_selection()
return self.parent.keyboard_on_key_up(window, keycode)
if self.select_with_key_up(window, keycode):
return True
return False
def add_widget(self, widget):
""" Override the adding of widgets so we can bind and catch their
*on_touch_down* events. """
widget.bind(on_touch_down=self.button_touch_down,
on_touch_up=self.button_touch_up)
return super(SelectableBoxLayout, self).add_widget(widget)
def button_touch_down(self, button, touch):
""" Use collision detection to select buttons when the touch occurs
within their area. """
if button.collide_point(*touch.pos):
self.select_with_touch(button, touch)
def button_touch_up(self, button, touch):
""" Use collision detection to de-select buttons when the touch
occurs outside their area and *touch_multiselect* is not True. """
if not (button.collide_point(*touch.pos) or
self.touch_multiselect):
self.deselect_node(button)
def select_node(self, node):
node.background_color = (1, 0, 0, 1)
return super(SelectableBoxLayout, self).select_node(node)
def deselect_node(self, node):
node.background_color = (1, 1, 1, 1)
super(SelectableBoxLayout, self).deselect_node(node)
def on_selected_nodes(self, gird, nodes):
print("Selected nodes = {0}".format(nodes))
if self.orientation == 'vertical':
if nodes:
row = nodes[0]
row.clear_selection()
node_src, idx_src = row._resolve_last_node()
text = 'left'
node, idx = row.goto_node(text, node_src, idx_src)
row.select_node(node)
class TestApp(App):
def build(self):
grid = SelectableBoxLayout(orientation='vertical', touch_multiselect=False,
multiselect=False)
for i in range(0, 6):
row = SelectableBoxLayout(orientation='horizontal', touch_multiselect=False,
multiselect=False)
for j in range(0,5):
b = Button(text="Button {0}".format(j))
row.add_widget(b)
grid.add_widget(row)
row.get_focus_next().focus = True
return grid
TestApp().run()
答案 0 :(得分:0)
我花了一段时间调试,但这是一个有效的例子:
from kivy.uix.behaviors.compoundselection import CompoundSelectionBehavior
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.app import App
class SelectableBoxLayout(FocusBehavior, CompoundSelectionBehavior, BoxLayout):
def keyboard_on_key_down(self, window, keycode, text, modifiers):
"""Based on FocusBehavior that provides automatic keyboard
access, key presses will be used to select children.
"""
print(keycode, text, modifiers)
print(self.orientation)
if super(SelectableBoxLayout, self).keyboard_on_key_down(
window, keycode, text, modifiers):
return True
if self.orientation == 'horizontal' and keycode[1] in ['up', 'down']:
self.clear_selection()
return self.parent.keyboard_on_key_down(window, keycode, text, modifiers)
if self.orientation == 'vertical' and keycode[1] in ['up', 'down']:
direction = 'focus_next' if keycode[1] == 'down' else 'focus_previous'
if self.selected_nodes:
next_row = self.selected_nodes[0]._get_focus_next(direction)
else:
next_row = self.children[-1]
self.clear_selection()
self.select_node(next_row)
if next_row:
next_row.focus = True
next = next_row.children[-1]
if next and not isinstance(next, SelectableBoxLayout):
print("moving to {0}".format(next))
next.focus = True
next_row.clear_selection()
next_row.select_node(next)
return True
if self.select_with_key_down(window, keycode, text, modifiers):
return True
return False
def keyboard_on_key_up(self, window, keycode):
"""Based on FocusBehavior that provides automatic keyboard
access, key release will be used to select children.
"""
if super(SelectableBoxLayout, self).keyboard_on_key_up(window, keycode):
return True
if self.orientation == 'horizontal' and keycode[1] in ['up', 'down']:
return self.parent.keyboard_on_key_up(window, keycode)
if self.select_with_key_up(window, keycode):
return True
return False
def add_widget(self, widget, index=0):
""" Override the adding of widgets so we can bind and catch their
*on_touch_down* events. """
widget.bind(on_touch_down=self.button_touch_down,
on_touch_up=self.button_touch_up)
return super(SelectableBoxLayout, self).add_widget(widget, index)
def button_touch_down(self, button, touch):
""" Use collision detection to select buttons when the touch occurs
within their area. """
if button.collide_point(*touch.pos):
self.select_with_touch(button, touch)
def button_touch_up(self, button, touch):
""" Use collision detection to de-select buttons when the touch
occurs outside their area and *touch_multiselect* is not True. """
if not (button.collide_point(*touch.pos) or
self.touch_multiselect):
self.deselect_node(button)
def select_node(self, node):
node.background_color = (1, 0, 0, 1)
print("select: {}".format(getattr(node, 'text', 'none')))
return super(SelectableBoxLayout, self).select_node(node)
def deselect_node(self, node):
node.background_color = (1, 1, 1, 1)
print("deselect: {}".format(getattr(node, 'text', 'none')))
super(SelectableBoxLayout, self).deselect_node(node)
def on_selected_nodes(self, grid, nodes):
pass
class TestingappApp(App):
"""Basic kivy app
Edit testingapp.kv to get started.
"""
def build(self):
grid = SelectableBoxLayout(orientation='vertical', touch_multiselect=False,
multiselect=False)
for i in range(0, 6):
row = SelectableBoxLayout(orientation='horizontal', touch_multiselect=False,
multiselect=False)
for j in range(0,5):
b = Button(text="Event A\n TT {}{}".format(i, j))
row.add_widget(b)
grid.add_widget(row)
row.get_focus_next().focus = True
return grid