Python Kivy遍历Widget树

时间:2018-06-17 17:19:13

标签: python kivy

我正在为学校建立一个小项目,我需要一个界面,所以我认为我会使用KivyPython,但是我被困在了UI,主要是如何在树中访问小部件。我一直在搜索,但kivy文档不是很有帮助,我发现哪些问题和答案似乎并不相关。

我想要做的是在顶部栏中放置一些按钮,在屏幕管理器下面有单独的预定义屏幕,但我不确定如何遍历树以完成我需要的操作。< / p>

因此,例如,第一个按钮将始终显示名为Dashboard的屏幕。我尝试了一些我找到的东西,但是我得到了#34;名称仪表板未定义&#34;

    #!/usr/bin/env python 
    from kivy.app import App 
    from kivy.uix.widget import Widget 
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
    from kivy.properties import ObjectProperty


    class Container(FloatLayout):
        pass

    class UpperMenu(BoxLayout):
        def change_screen(self,argument):
            self.ids.screens.ids.manager.current = argument


    class Screens(ScreenManager):
        pass

    class Dashboard(Screen):
        pass

    class Player(Screen):
        pass

    class Weather(Screen):
        pass

    class Map(Screen):
        pass

    class Carousel(BoxLayout):
        pass

    class CarlApp(App):
        def build(self):
            return Container()

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

这是我的KV文件:

    #:kivy 1.10.0

    <Container>:
        id: container
        UpperMenu:
            id: uppermenu
            pos: root.x, root.top - self.height
        Screens:
            id: screens

    <UpperMenu>:
        size_hint: 1,.15
        Button:
            text: ""
            id: ButtonCeasuri
            on_release: root.change_screen(dashboard)
            Image:
                source: 'dashboard.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasurii
            Image:
                source: 'play-button.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasuriii
            Image:
                source: 'distance.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasuriiii
            Image:
                source: 'temperature.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y

    <Screens>:
        size_hint: 1,.85
        Dashboard:
            name: 'Dashboard'
            label: "Dashboard Screen"
            id: dashboard
            Button:
                text: "Stuff"
                on_release: pass
        Player:
            name: 'Player'
            label: "Player Screen"
            id: Player
            Button:
                text: "Stuff2"
        Weather:
            name: 'Weather'
            label: "Weather Screen"
        Map:
            name: 'Map'
            label: "Map Screen"

我一直试图了解在过去的3-4天内如何做到这一点,但我不明白。

2 个答案:

答案 0 :(得分:0)

从您的代码中,您似乎已经在仪表板屏幕上,无论如何将屏幕更改为另一个屏幕,这是一个帮助您做到这一点的示例代码

<UpperMenu>:
size_hint: 1,.15
Button:
    text: ""
    id: ButtonCeasuri
    on_release: root.change_screen("Dashboard")

名称仪表板未定义,因为kv文件无法引用它,然后在您的代码中您也可以这样做,

class UpperMenu(BoxLayout):
    def change_screen(self,argument):
        self.parent.children[0].current = argument

你可以致电print(self.parent.children)看看它打印出来的内容,我希望这会有所帮助

答案 1 :(得分:0)

要更改屏幕,有两种方法可以执行此操作。第一种方法都是在kv文件中完成的。第二种方法是在Python文件中完成的。在该示例中演示了两种方法。

方法1 - kv文件

您可以将用于更改屏幕的代码放在kv文件中 替换:

root.change_screen(dashboard)

app.root.ids.screen.current = 'Dashboard'    # 'Dashboard' name of screen

方法2 - Python&amp; kv文件

  1. kv 文件中,将屏幕的名称传递给 change_screen()功能,例如root.change_screen('Dashboard')
  2. Python 文件中,将self.ids.screens.ids.manager.current替换为self.parent.ids.screen.current方法中的change_screen()
  3. 注意

    AttributeError的

         self.ids.screens.ids.manager.current = argument
     AttributeError: 'super' object has no attribute '__getattr__'
    

    说明

    self - 关键字 self 引用“当前窗口小部件实例”,即类UpperMenu()

    ids - 关键字 ids 引用查找对象,它是字典类型属性。在这种情况下,所有Button小部件都在kv文件中的类规则&lt; UpperMenu&gt;:下用id标记。

    屏幕 - 关键字屏幕引用屏幕的 id 但它在 self.ids 下不存在。因此,Kivy抛出了AttributeError。添加 print(self.ids) 以显示 self.ids 中找到的所有 ID

    实施例

    test.kv

    #:kivy 1.10.0
    
    <Container>:
        id: container
        UpperMenu:
            id: uppermenu
            pos: root.x, root.top - self.height
        Screens:
            id: screens
    
    <UpperMenu>:
        size_hint: 1,.15
        Button:
            text: ""
            id: ButtonCeasuri
            on_release:
                root.change_screen('Dashboard')    # Method 2
    
            Image:
                source: 'dashboard.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasurii
            on_release:
                app.root.ids.screens.current = 'Player'    # Method 1
    
            Image:
                source: 'play-button.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasuriii
            Image:
                source: 'distance.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
        Button:
            text: ""
            id: ButtonCeasuriiii
            Image:
                source: 'temperature.png'
                allow_stretch: False
                center_x: self.parent.center_x
                center_y: self.parent.center_y
    
    <Screens>:
        size_hint: 1,.85
        Dashboard:
            id: dashboard
            name: 'Dashboard'
            label: "Dashboard Screen"
            Button:
                text: "Stuff"
                on_release: pass
        Player:
            name: 'Player'
            label: "Player Screen"
            id: Player
            Button:
                text: "Stuff2"
        Weather:
            name: 'Weather'
            label: "Weather Screen"
        Map:
            name: 'Map'
            label: "Map Screen"
    

    main.py

    #!/usr/bin/env python
    from kivy.app import App
    from kivy.uix.widget import Widget
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
    from kivy.properties import ObjectProperty
    
    
    class Container(FloatLayout):
        pass
    
    
    class UpperMenu(BoxLayout):
        def change_screen(self, argument):
            self.parent.ids.screens.current = argument
    
    
    class Screens(ScreenManager):
        pass
    
    
    class Dashboard(Screen):
        pass
    
    
    class Player(Screen):
        pass
    
    
    class Weather(Screen):
        pass
    
    
    class Map(Screen):
        pass
    
    
    class Carousel(BoxLayout):
        pass
    
    
    class TestApp(App):
        def build(self):
            return Container()
    
    
    if __name__ == '__main__':
        TestApp().run()
    

    输出

    单击第二个按钮

    Img01 - Second Screen Displayed after clicking second button

    点击第一个按钮

    Img02 - First Screen Displayed after clicking first button