Python Kivy screen manager wiget scope

混江龙づ霸主 提交于 2019-12-12 02:12:27

问题


I am trying to control a screen manager from buttons in a separate class, but I cannot figure out what to set on the button on_press: statements.

Kivy file:

<HeaderSection>:
    anchor_x: 'center'
    anchor_y: 'top'
    BoxLayout:
        orientation: 'horizontal'
        size_hint: 1, .1
        id: header
        Label:
            text: 'My App'

<ContentSection>:
    anchor_x: 'center'
    anchor_y: 'center'
    ScreenManager:
        size_hint: 1, .8
        Screen:
            name: 'home'
            Label:
                text: 'First screen'
        Screen:
            name: 'second'
            Label:
                text: 'Second screen'
        Screen:
            name: 'third'
            Label:
                text: 'Third screen'

<FooterSection>:
    anchor_x: 'center'
    anchor_y: 'bottom'
    BoxLayout:
        orientation: 'horizontal'
        size_hint: 1, .1
        Button:
            text: 'first'
            on_press: root.ContentSection.manager.current = 'first'
        Button:
            text: 'second'
            on_press: root.current = 'second'
        Button:
            text: 'third'
            on_press: ContentSection.ScreenManager.current = 'third'

Python file:

from kivy.app import App
from kivy.lang import Builder
Builder.load_file('MyApp.kv')
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.image import Image

# Declare sections
class HeaderSection(AnchorLayout):
    pass

class ContentSection(AnchorLayout):
    def build(self):

        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(FirstScreen(name='first'))
        sm.add_widget(SecondScreen(name='second'))
        sm.add_widget(ThirdScreen(name='third'))
        return sm

class FooterSection(AnchorLayout):
    pass


class MyAppApp(App):
    def build(self):

        #Create the sections

        fl = FloatLayout()
        hs = HeaderSection()
        cs = ContentSection()
        fs = FooterSection()

        fl.add_widget(hs)
        fl.add_widget(cs)
        fl.add_widget(fs)
        return fl


if __name__ == '__main__':
    MyAppApp().run()

I have tried various methods:

on_press: root.parent.ContentSection.ScreenManager.current = 'home'
on_press: root.parent.ContentSection.manager.current = 'home'
on_press: root.ContentSection.manager.current = 'home'

I feel like it is a scoping issue, errors say things like:

AttributeError: 'FooterSection' object has no attribute 'ContentSection'

So my app has the following hierarchy:

FloatLayout
    HeaderSection
    ContentSection
        ScreenManager
             FirstScreen
             SecondScreen
             ThirdScreen
    FooterSection
        Button for FirstScreen
        Button for SecondScreen
        Button for ThirdScreen

So I need to traverse up a level into FloatLayout, then drill down into ContentSection to access the screen manager.


回答1:


Navigating widget trees has been a pain for me, and AFAIK you can't traverse the widget tree the way you'd like.

You can, however, simplify your widget tree, make sure everything shares the same root, and use ids.

Here's how I did it (I also moved everything to kv language):

kv

FloatLayout:
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        Label:
            size_hint: 1, .1
            text: 'My App'
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'center'
        ScreenManager:
            id: manager
            size_hint: 1, .8
            Screen:
                name: 'first'
                Label:
                    text: 'First screen'
            Screen:
                name: 'second'
                Label:
                    text: 'Second screen'
            Screen:
                name: 'third'
                Label:
                    text: 'Third screen'
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'bottom'
        BoxLayout:
            orientation: 'horizontal'
            size_hint: 1, .1
            Button:
                text: 'first'
                on_press: root.ids.manager.current = 'first'
            Button:
                text: 'second'
                on_press: root.ids.manager.current = 'second'
            Button:
                text: 'third'
                on_press: root.ids.manager.current = 'third'

python

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.image import Image



class MyAppApp(App):
    def build(self):
        return Builder.load_file('MyApp.kv')


if __name__ == '__main__':
    MyAppApp().run()


来源:https://stackoverflow.com/questions/42613955/python-kivy-screen-manager-wiget-scope

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!