Reputation: 1001
I have a Kivy application based on a TabbedPanel. Now I want to autofocus one of the TextInputs when I change to a tab.
When initializing the applications, this works:
class FocusedTextInput(TextInput):
def on_parent(self, widget, parent):
self.focus = True
But when changing to another tab and back to the first one, the FocusedTextInput is already on its parent so the callback isn't thrown. Whenever I want to handle other events (e.g. the click event of the TabbedPanelItem or the on_parent of it), the instance of the FocusedTextInput is None, even when I schedule a callback (e.g. 10s after) and the Input is visible and usable through other functions (e.g. focus_out handler of the input).
Is there any way to automatically focus one TextInput once the user changed tabs?
I look forward to your answers and hope for you kivy experts out there. ;-)
These parts of my application might be interesing for you: This class initializes the tabs (one tab for this example) and loads the content from the kv file.
class Applikation(App):
bezahlungProp = ObjectProperty(None)
#[...]
def build(self):
rootNode = TabbedPanel(do_default_tab=False)
rootNode.bind(current_tab=self.tabChanged)
bezahlungitem = TabbedPanelItem(text="Bezahlung")
self.bezahlungitem = bezahlungitem
self.bezahlung = Bezahlung()
rootNode.add_widget(bezahlungitem)
bezahlungitem.add_widget(self.bezahlung)
self.bezahlungProp = ObjectProperty(self.bezahlung)
self.bezahlung.add_widget(Builder.load_file("bezahlung.kv"))
# [...]
return rootNode
def tabChanged(self, instance, value):
Builder.sync()
value.content.init()
This represents one tab:
class Bezahlung(BoxLayout):
ticketIDInp = ObjectProperty(None)
def on_parent(self, a, b):
Clock.schedule_once(self.on_parent_callback,10)
def on_parent_callback(self,b):
#this throws an error -> self.ticketIDInp is None
self.ticketIDInp.focus = True
def init(self):
#Application also fails here:
self.ticketIDInp.focus = True
def ticketIDInp_focus_out(self):
#I can use self.ticketIDInp.text here without problems
response = self.server.request("hookStatFromTicket",{"ticketID":self.ticketIDInp.text})
[...]
Relevant part of the bezahlung.kv:
Bezahlung:
ticketIDInp: ticketIDInp
BoxLayout:
BoxLayout:
FocusedTextInput:
id: ticketIDInp
on_text_validate: root.ticketIDInp_focus_out()
Upvotes: 0
Views: 587
Reputation: 8066
One way to do what you want is to bind the current_tab property. Here is a working example (the 2nd Tab is the one with the wanted behavior)
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder
Builder.load_string("""
<Test>:
size_hint: .5, .5
pos_hint: {'center_x': .5, 'center_y': .5}
do_default_tab: False
TabbedPanelItem:
text: 'first tab'
Label:
text: 'First tab content area'
TabbedPanelItem:
id: tab2
text: 'tab2'
BoxLayout:
Label:
text: 'Second tab content area'
TextInput:
text: 'Button that does nothing'
focus: root.current_tab == tab2 # <--- this is it! also can be changed to "== self.parent.parent"
""")
class Test(TabbedPanel):
pass
class TabbedPanelApp(App):
def build(self):
t = Test()
return t
if __name__ == '__main__':
TabbedPanelApp().run()
Upvotes: 1