将登录界面与屏幕管理器分开,因为存在选项卡面板。

huangapple go评论65阅读模式
英文:

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={&#39;y&#39;: 0},transition=NoTransition())
        sm.add_widget(LoginScreen(name=&#39;login&#39;))
        sm.add_widget(MainScreen(name=&#39;main&#39;))
        sm.add_widget(Firstscreen(name=&#39;first&#39;))
        sm.add_widget(Secondscreen(name=&#39;second&#39;))
        root.add_widget(sm)

        return root

if __name__ == &#39;__main__&#39;:
    TabTest_with_Screenmanager_V2().run()

TabTest_with_Screenmanager_V2.kv:

&lt;LoginScreen&gt;:
    id: login
    Label:
        text: &quot;Welcome&quot;

&lt;MainScreen&gt;:
    id: main
    TabbedPanel:
        id: tabbedpanel
        do_default_tab: False
        TabbedPanelItem:
            id: home_tab
            text:&quot;Main&quot;

            BoxLayout:
                Label:
                    text:&#39;Main&#39;

        TabbedPanelItem:
            id: first_tab
            text:&quot;First&quot;  
            on_release: root.manager.current= &#39;first&#39;



        TabbedPanelItem:
            id: second_tab
            text:&quot;Second&quot; 
            on_release:root.manager.current= &#39;second&#39;


&lt;Firstscreen&gt;:
    id: first
    TabbedPanel:
        id: tabbedpanel
        do_default_tab: False
        TabbedPanelItem:
            id: home_tab
            text:&quot;Main&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;main&#39;
        TabbedPanelItem:
            id: first_tab
            text:&quot;First&quot;
            BoxLayout:
                Label:
                    text:&quot;first&quot;

        TabbedPanelItem:
            id: second_tab
            text:&quot;Second&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;second&#39;

&lt;Secondscreen&gt;:
    id: second
    TabbedPanel:
        id: tabbedpanel
        do_default_tab: False
        TabbedPanelItem:
            id: home_tab
            text:&quot;Main&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;main&#39;
        TabbedPanelItem:
            id: first_tab
            text:&quot;First&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;first&#39;
        TabbedPanelItem:
            id: second_tab
            text:&quot;Second&quot;
            BoxLayout:
                Label:
                    text:&#39;second&#39;

答案1

得分: 0

问题出在TabbedPanelItem中对state的使用上。在TabbedPanel中,其中一个TabbedPanelItem将是当前标签,并且该TabbedPanelItemstate将被设置为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 == &quot;down&quot;:root.manager.current= &#39;main&#39;

to:

on_release: root.manager.current= &#39;main&#39;

huangapple
  • 本文由 发表于 2023年6月16日 05:00:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76485476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定