Python和Kivy语言交流

时间:2014-10-04 16:42:39

标签: android python kivy

我在理解Python和Kivy语言之间的沟通方面遇到了问题 - 下面更具体地说。

情况

我有一个应用 - TutorialAppbuild方法返回MyScreenManager()MyScreenManager只管理一个名为FirstScreen的屏幕。在相应的tutorial.kv文件中,我使用FirstScreen BoxLayout id: box小部件。我们说我有一个清单

FILMS = ['Film 1', 'Film 2']

现在,当我运行应用程序时,我想为每部电影添加一个Button小部件到BoxLayout,标识为box。这应该只进行一次,所以我想把它放在__init__函数中,我用super方法覆盖它。这是我的main.py文件:

#!/usr/bin/env python
from kivy.app               import App
from kivy.uix.button        import Button
from kivy.uix.boxlayout     import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen

FILMS = ['Film 1', 'Film 2']

class TutorialApp(App):

    def build(self):
        return MyScreenManager()

class MyScreenManager(ScreenManager):
    pass

class FirstScreen(Screen):

    def __init__(self, **kvargs):
        super(FirstScreen, self).__init__(**kvargs)

        for film in FILMS:
            self.ids.box.add_widget(Button(text=film))

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

这是我的tutorial.kv文件:

<MyScreenManager>:
    FirstScreen:

<FirstScreen>:
    name: 'FirstScreen'
    BoxLayout:
        id: box

但我的方法不起作用。为什么?可能是因为当时调用__init__时没有BoxLayout并且没有id,所以我无法引用它们(至少这是我认为基于日志的内容) ,也通过在不同时间打印self.ids来测试它。

不同方法

现在,我能做的是以下内容。我可以像这样简单地调整代码(仅显示更改的部分),而不是在BoxLayout tutorial.kv文件中创建:

class FirstScreen(Screen):

    def __init__(self, **kvargs):
        super(FirstScreen, self).__init__(**kvargs)

        box = BoxLayout(id='box')
        for film in FILMS:
            box.add_widget(Button(text=film))
        self.add_widget(box)

tutorial.kv

<MyScreenManager>:
    FirstScreen:

<FirstScreen>:
    name: 'FirstScreen'

这有效,但后来我遇到了其他问题。假设我有更多屏幕,并且我想向Button添加FirstScreeen,这将导致不同的屏幕(示例中未指定)。因此,Button将在tutorial.kv内指定,如下所示:

Button:
    text: 'Go somewhere else'
    on_release: app.root.current = 'DifferentScreenName'

但是由于我在__init__函数中创建了这个框,我不能简单地将这段代码放在tutorial.kv中。我可以像这样更改main.py

class FirstScreen(Screen):

    def __init__(self, **kvargs):
        super(FirstScreen, self).__init__(**kvargs)

        box = BoxLayout(id='box')
        for film in FILMS:
            box.add_widget(Button(text=film))
        box.add_widget(Button(text='Go somewhere else',
                              on_release="""WHAT SHOULD GO HERE?"""))
        self.add_widget(box)

但是用这个词来表示什么应该去?我不知道如何更改屏幕。所以,希望你能理解这个问题。我不知道哪种方式更好,我认为,在*.kv文件中指定应用布局的内容越多越好,但如何解决与此类似的情况?

我的猜测

我知道这很长,但我想向你保证,我自己也尝试了一些事情。

首先猜测on_init/on_start内调用tutorial.kv之类的内容,例如:

<MyScreenManager>:
    FirstScreen:
    DifferentScreen:

<FirstScreen>:
    name: 'FirstScreen'
    BoxLayout:
        id:box
        on_start: root.method_which_adds_film_buttons
        Button:
            text: 'Go somewhere else'
            on_release: app.root.current ='DifferentScreen'

希望,当FirstScreen初始化时,这种方法只运行一次。但我找不到这样的方法。

第二次猜测

像这样调整__init__功能:     class FirstScreen(屏幕):

    def __init__(self, **kvargs):
        super(FirstScreen, self).__init__(**kvargs)

        box = BoxLayout(id='box')
        for film in FILMS:
            box.add_widget(Button(text=film))
        box.add_widget(Button(text='Go somewhere else',
                              on_release=app.root.current('DifferentScreen')))
        self.add_widget(box)

或者这个:

class FirstScreen(Screen):

    def __init__(self, **kvargs):
        super(FirstScreen, self).__init__(**kvargs)

        box = BoxLayout(id='box')
        for film in FILMS:
            box.add_widget(Button(text=film))
        box.add_widget(Button(text='Go somewhere else',
                              on_release=self.root.current('DifferentScreen')))
        self.add_widget(box)

两者都没有明显的效果(这就是我在这里问的原因)。这两个例子都显示,我不明白root是如何传递的。有人可以解释/给出我正在寻找的行为的实例吗?

1 个答案:

答案 0 :(得分:1)

感谢Kivy IRC用户,我得到了以下答案,其中有诀窍:gist.github.com/anonymous/cdac178934b73eae51e0