Python Kivy: 使用Screenmanager将TabbePanel连接到屏幕

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

Python Kivy: Connect TabbePanel to Screen using Screenmanager

问题

我一直在开发一个Python应用程序,包括一个main.py和一个gui.kv文件。所有屏幕(“Main”,“First”,“Second”)都由ScreenManager管理,就像main.py中的示例一样。
现在我想将每个屏幕链接到一个选项卡。通过按下相应的选项卡,屏幕应该切换。到目前为止,我已经成功将一个具有3个选项卡(“Main”,“First”,“Second”)的TabbedPanel添加到gui.kv中。

问题:TappedPanelItem事件(on_release: root.manager.current= 'first')的工作方式不如预期。当我单击“First”选项卡时,程序会切换到一个空白屏幕,并且“Main”选项卡仍然亮起。第二次按下“First”选项卡时,“First”屏幕最终显示“First”屏幕,并且“First”选项卡标记会亮起。

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

class TabbedTest(TabbedPanel):
    pass

class MainScreen(Screen):
    pass

class FirstScreen(Screen):
    pass

class SecondScreen(Screen):
    pass

class TabTest_with_Screenmanager_V2(App):

    def build(self):
        root = FloatLayout()

        sm = ScreenManager(size_hint_y=0.99, pos_hint={'y': 0}, transition=NoTransition())
        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:

<MainScreen>:
    id: main
    TabbedPanel:
        do_default_tab: False
        TabbedPanelItem:
            text: "Main"
            BoxLayout:
                Label:
                    text: 'Main'
        TabbedPanelItem:
            text: "First"
            on_release: root.manager.current = 'first'
        TabbedPanelItem:
            text: "Second"
            on_release: root.manager.current = 'second'

<FirstScreen>:
    id: first
    TabbedPanel:
        do_default_tab: False
        TabbedPanelItem:
            text: "Main"
            on_state: if self.state == "down": root.manager.current = 'main'
        TabbedPanelItem:
            text: "First"
            BoxLayout:
                Label:
                    text: "first"
        TabbedPanelItem:
            text: "Second"
            on_state: if self.state == "down": root.manager.current = 'second'

<SecondScreen>:
    id: second
    TabbedPanel:
        do_default_tab: False
        TabbedPanelItem:
            text: "Main"
            on_state: if self.state == "down": root.manager.current = 'main'
        TabbedPanelItem:
            text: "First"
            on_state: if self.state == "down": root.manager.current = 'first'
        TabbedPanelItem:
            text: "Second"
            BoxLayout:
                Label:
                    text: 'second'

目标:当我点击选项卡时,程序应立即切换到相应的屏幕并点亮相应的选项卡。你有什么想法,哪种事件可能会起作用,或者是否有更好的解决方案?

英文:

I’ve been working on a Python app consisting of a main.py and a gui.kv. All screens (“Main”, “First”, “Second”) are managed by the ScreenManager as shown in the example main.py.
Now I would like to link a tab to each screen. By pressing the corresponding tab the screen shall switch. What I managed so far is the addition of a TabbedPanel with 3 TabbedPanelItems (“Main”, “First”, “Second”) to the gui.kv.

The problem: The TappedPanelItem event (on_release: root.manager.current= 'first') doesn’t work as intended. When I press the tab “First” once, the program switches to a blank screen and the “Main” tab marking is still illuminated. The second time I press the tab “First” the “First” screen finally shows the “First”-Screen and the “First“ tab marking illuminates.

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


class TabbedTest(TabbedPanel):
    pass
class MainScreen(Screen):
    pass
class Firstscreen(Screen):
    pass
class Secondscreen(Screen):
    pass

class TabTest_with_Screenmanager_V2(App):

    def build(self):
        root = FloatLayout()
        #self.tabbedtest = TabbedTest(size_hint_y=0.5, pos_hint={&#39;top&#39;: 1.0})
        #root.add_widget(self.tabbedtest)

        # Create the screen manager
        sm = ScreenManager(size_hint_y=0.99, pos_hint={&#39;y&#39;: 0},transition=NoTransition())
        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;MainScreen&gt;:
    id: main

    TabbedPanel:
        do_default_tab: False

        TabbedPanelItem:
            text:&quot;Main&quot;
            BoxLayout:
                Label:
                    text:&#39;Main&#39;
              
        TabbedPanelItem:
            text:&quot;First&quot;  
            on_release: root.manager.current= &#39;first&#39;
            
       
        TabbedPanelItem:
            text:&quot;Second&quot; 
            on_release:root.manager.current= &#39;second&#39;
           

&lt;Firstscreen&gt;:
    id: first
    TabbedPanel:
        do_default_tab: False

        TabbedPanelItem:
            text:&quot;Main&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;main&#39;

        TabbedPanelItem:
            text:&quot;First&quot;
            BoxLayout:
                Label:
                    text:&quot;first&quot;

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


&lt;Secondscreen&gt;:
    id: second
    TabbedPanel:
        do_default_tab: False

        TabbedPanelItem:
            text:&quot;Main&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;main&#39;

        TabbedPanelItem:
            text:&quot;First&quot;
            on_state: if self.state == &quot;down&quot;:root.manager.current= &#39;first&#39;

        TabbedPanelItem:
            text:&quot;Second&quot;
            BoxLayout:
                Label:
                    text:&#39;second&#39;
          

Objective: When I press a tab the program shall switch to the corresponding screen and illuminate the corresponding tab, immediately.
Do you have any idea what kind of event might work or is there better solution?

答案1

得分: 0

可以使用一些ids和每个Screenon_enter()方法来实现这个功能。

首先,在TabbedPanel上分配一个id,并为您希望在进入该Screen时打开的默认选项卡分配另一个id。例如:

<MainScreen>:
    id: main

    TabbedPanel:
        id: tab
        do_default_tab: False

        TabbedPanelItem:
            id: home_tab
            text: "主页"
            BoxLayout:
                Label:
                    text: '主页'

        TabbedPanelItem:
            text: "第一项"
            on_release: root.manager.current = '第一个'

        TabbedPanelItem:
            text: "第二项"
            on_release: root.manager.current = '第二个'

然后,在该Screen上添加一个on_enter()方法:

class MainScreen(Screen):
    def on_enter(self, *args):
        tab = self.ids.tab
        home_tab = self.ids.home_tab
        Clock.schedule_once(lambda *args: tab.switch_to(home_tab))

相同的ids方案可以添加到每个Screen上,并且可以向每个Screen添加相同的on_enter()方法。

英文:

You can use some ids and the on_enter() method of each Screen to do this.

First, assign an id to the TabbedPanel and another to the default tab that you want to be opened when you enter that Screen. For example:

&lt;MainScreen&gt;:
    id: main

    TabbedPanel:
        id: tab
        do_default_tab: False
        
        TabbedPanelItem:
            id: home_tab
            text:&quot;Main&quot;
            BoxLayout:
                Label:
                    text:&#39;Main&#39;
              
        TabbedPanelItem:
            text:&quot;First&quot;  
            on_release: root.manager.current=&#39;first&#39;
       
        TabbedPanelItem:
            text:&quot;Second&quot; 
            on_release:root.manager.current= &#39;second&#39;

Then add an on_enter() method to that Screen:

class MainScreen(Screen):
    def on_enter(self, *args):
        tab = self.ids.tab
        home_tab = self.ids.home_tab
        Clock.schedule_once(lambda *arges: tab.switch_to(home_tab))

The same scheme of ids can be added to each Screen, and the identical on_enter() method can be added to each Screen.

答案2

得分: 0

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 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(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()
英文:

main.kv

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 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(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()

答案3

得分: 0

<TabTest_with_Screenmanager_V2.kv>:
    <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 = '第一项'

            TabbedPanelItem:
                id: second_tab
                text: "第二项"
                on_release: root.manager.current = '第二项'

    <Firstscreen>:
        id: first
        TabbedPanel:
            id: tabbedpanel
            do_default_tab: False
            TabbedPanelItem:
                id: home_tab
                text: "主页"
                on_state: if self.state == "down": root.manager.current = '主页'
            TabbedPanelItem:
                id: first_tab
                text: "第一项"
                BoxLayout:
                    Label:
                        text: "第一项"

            TabbedPanelItem:
                id: second_tab
                text: "第二项"
                on_state: if self.state == "down": root.manager.current = '第二项'

    <Secondscreen>:
        id: second
        TabbedPanel:
            id: tabbedpanel
            do_default_tab: False
            TabbedPanelItem:
                id: home_tab
                text: "主页"
                on_state: if self.state == "down": root.manager.current = '主页'
            TabbedPanelItem:
                id: first_tab
                text: "第一项"
                on_state: if self.state == "down": root.manager.current = '第一项'
            TabbedPanelItem:
                id: second_tab
                text: "第二项"
                BoxLayout:
                    Label:
                        text: '第二项'
英文:

TabTest_with_Screenmanager_V2.kv:

&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;

huangapple
  • 本文由 发表于 2023年6月13日 04:27:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460106.html
匿名

发表评论

匿名网友

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

确定