kivy/examples/widgets/focus_behavior.py

67 lines
2.5 KiB
Python
Raw Normal View History

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.behaviors import FocusBehavior
class FocusButton(FocusBehavior, Button):
'''A button, which when focused, turns red and sets the keyboard
input to the text of the button.
'''
def on_focused(self, instance, value, *largs):
self.background_color = [1, 0, 0, 1] if value else [1, 1, 1, 1]
def keyboard_on_key_down(self, window, keycode, text, modifiers):
'''We call super before doing anything else to enable tab cycling
by FocusBehavior. If we wanted to use tab for ourselves, we could just
not call it, or call it if we didn't need tab.
'''
if super(FocusButton, self).keyboard_on_key_down(window, keycode,
text, modifiers):
return True
self.text = keycode[1]
return True
class FocusApp(App):
def build(self):
root = BoxLayout()
self.grid1 = grid1 = GridLayout(cols=4)
self.grid2 = grid2 = GridLayout(cols=4)
2014-02-23 23:22:51 +00:00
root.add_widget(FocusButton(text='Left', size_hint_x=0.4))
root.add_widget(grid1)
root.add_widget(grid2)
2014-02-23 23:22:51 +00:00
root.add_widget(FocusButton(text='Right', size_hint_x=0.4))
for i in range(40):
grid1.add_widget(FocusButton(text='l' + str(i)))
for i in range(40):
grid2.add_widget(FocusButton(text='r' + str(i)))
# make elements 29, 9 un-focusable. The widgets are displayed in
# reverse order, so 9 = 39 - 10
2014-02-23 23:22:51 +00:00
grid2.children[30].text = grid1.children[14].text =\
grid2.children[10].text = grid1.children[34].text = 'Skip me'
grid2.children[10].is_focusable = False
grid2.children[30].is_focusable = False
# similarly, make 39 - 14 = 25, and 5 un-focusable
grid1.children[14].is_focusable = False
grid1.children[34].is_focusable = False
2014-02-23 23:22:51 +00:00
# don't move focus passed this element
grid2.children[35].focus_next = FocusBehavior.EndIteration
grid2.children[35].text = 'Stop forward'
# exchange the links between the sides so that it'll skip to the other
# side in the middle. Remember that children are displayed reversed
# in layouts.
grid1.children[10].link_focus(next=grid2.children[9])
grid2.children[10].link_focus(next=grid1.children[9])
return root
if __name__ == '__main__':
FocusApp().run()