英文:
Separate login screen from Screenmanager due to TabbedPanel
问题
我的Python应用程序使用屏幕管理器来控制我的标签屏幕('Main','First','Second')。我想要添加一个登录屏幕,它不应该包含任何选项卡。当我启动应用程序时,登录屏幕会出现一小段时间,然后被跳过,而是显示出"主"屏幕。如果没有选项卡面板结构,登录屏幕就不会被跳过。因此,由屏幕管理器创建的没有选项卡面板的"登录"屏幕似乎是问题的原因。
如何将"登录"屏幕与屏幕管理器分离或防止其被跳过,同时保留其他所有屏幕的选项卡面板?
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))
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 = FloatLayout()
root.add_widget(sm)
return root
if __name__ == '__main__':
TabTest_with_Screenmanager_V2().run()
TabTest_with_Screenmanager_V2.kv:
<LoginScreen>:
id: login
Label:
text: "欢迎"
<MainScreen>:
id: main
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
BoxLayout:
Label:
text: '主页'
TabbedPanelItem:
id: first_tab
text: "第一页"
on_release: root.manager.current = 'first'
TabbedPanelItem:
id: second_tab
text: "第二页"
on_release: root.manager.current = 'second'
<Firstscreen>:
id: first
TabbedPanel:
id: tabbedpanel
do_default_tab: False
TabbedPanelItem:
id: home_tab
text: "主页"
on_state: if self.state == "down": root.manager.current = 'main'
TabbedPanelItem:
id: first_tab
text: "第一页"
BoxLayout:
Label:
text: "第一页"
TabbedPanelItem:
id: second_tab
text: "第二页"
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: "主页"
on_state: if self.state == "down": root.manager.current = 'main'
TabbedPanelItem:
id: first_tab
text: "第一页"
on_state: if self.state == "down": root.manager.current = 'first'
TabbedPanelItem:
id: second_tab
text: "第二页"
BoxLayout:
Label:
text: '第二页'
英文:
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'
答案1
得分: 0
问题出在TabbedPanelItem
中对state
的使用上。在TabbedPanel
中,其中一个TabbedPanelItem
将是当前标签,并且该TabbedPanelItem
的state
将被设置为down
。然后,您的on_state
将会触发,当前的Screen
将会被更改。修复方法是将kv
中的on_state
行替换为类似on_release
的内容。例如,将以下代码:
on_state: if self.state == "down": root.manager.current = 'main'
更改为:
on_release: root.manager.current = 'main'
英文:
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'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论