My Python app uses the screen manager to control my tabbed screens ('Main', 'First', 'Second'). I would like to add a login screen which shall not contain any tab. When I start the app the login screen appears for a fraction of second and is skipped over. Instead, the 'main' screen shows up. Without the TabbedPanel structure the 'login' screen is not skipped. So the 'login' screen created by the screenmanager whithout a TappedPanel seems to be the cause.
How can I seperate the 'login' screen from the screen manager or prevent it from getting skipped while keeping the TabbedPanel for all the other screens?
main.py:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
class TabbedTest(TabbedPanel):
pass
class LoginScreen(Screen):
pass
class MainScreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
home_tabX = self.ids.home_tab
Clock.schedule_once(lambda *args: tab.switch_to(home_tabX))
#pass
class Firstscreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
first_tabX = self.ids.first_tab
Clock.schedule_once(lambda *args: tab.switch_to(first_tabX))
class Secondscreen(Screen):
def on_enter(self, *args):
tab= self.ids.tabbedpanel
second_tabX = self.ids.second_tab
Clock.schedule_once(lambda *args: tab.switch_to(second_tabX))
class TabTest_with_Screenmanager_V2(App):
def build(self):
sm = ScreenManager(size_hint_y=0.99,
pos_hint={'y': 0},transition=NoTransition())
sm.add_widget(LoginScreen(name='login'))
sm.add_widget(MainScreen(name='main'))
sm.add_widget(Firstscreen(name='first'))
sm.add_widget(Secondscreen(name='second'))
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
TabTest_with_Screenmanager_V2.kv:
<LoginScreen>:
id: login
Label:
text: "Welcome"
<MainScreen>:
id: main
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
BoxLayout:
Label:
text:'Main'
TabbedPanelItem:
id: first_tab
text:"First"
on_release: root.manager.current= 'first'
TabbedPanelItem:
id: second_tab
text:"Second"
on_release:root.manager.current= 'second'
<Firstscreen>:
id: first
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
id: first_tab
text:"First"
BoxLayout:
Label:
text:"first"
TabbedPanelItem:
id: second_tab
text:"Second"
on_state: if self.state == "down":root.manager.current= 'second'
<Secondscreen>:
id: second
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text:"Main"
on_state: if self.state == "down":root.manager.current= 'main'
TabbedPanelItem:
id: first_tab
text:"First"
on_state: if self.state == "down":root.manager.current= 'first'
TabbedPanelItem:
id: second_tab
text:"Second"
BoxLayout:
Label:
text:'second'
The problem is your use of state
in the TabbedPanelItem
. In a TabbedPanel
, one of the TabbedPanelItems
will be the current tab, and that TabbedPanelItem
will get its state
set to down
. Then your on_state
will get triggered and the current Screen
will get changed. The fix is to replace your on_state
lines in the kv
with something like on_release
. For example, change:
on_state: if self.state == "down":root.manager.current= 'main'
to:
on_release: root.manager.current= 'main'