3

次のようなレイアウトのテンプレートを作成しようとしています。

|----------|
|          | 
| IMAGE    |   <--- Just an image (square)
|          |
|----------| 
|[btn][btn]|   <--- GridLayout cols=2 of buttons 
|[btn][btn]| 
|[btn][btn]| 
|[btn][btn]| 
|[btn][btn]| 
|[btn][btn]|
|----------|

最初の部分は簡単です (ただし、私は kivy に非常に慣れていないため、間違っている可能性があります)

#:kivy 1.6
[SideBar@BoxLayout]:
    orientation: 'vertical'
    Image:
        source: ctx.image
        size_hint: (1, None)
        height: root.width
    GridLayout:
        cols: 2
        # What do I do here to make it easy to load a list of buttons?
4

2 に答える 2

10
#!/usr/bin/env python2
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button

Builder.load_string('''
#:kivy 1.6
[SideBar@BoxLayout]:
    content: content
    orientation: 'vertical'
    size_hint: ctx.size_hint if hasattr(ctx, 'size_hint') else (1, 1)
    Image:
        source: ctx.image
        size_hint: (1, None)
        height: root.width
    GridLayout:
        cols: 2
        # just add a id that can be accessed later on
        id: content

<Root>:
    Button:
        center_x: root.center_x
        text: 'press to add_widgets'
        size_hint: .2, .2
        on_press:
            # what comes after `:` is basically normal python code
            sb.content.clear_widgets()
            # however using a callback that you can control in python
            # gives you more control
            root.load_content(sb.content)
    SideBar:
        id: sb
        size_hint: .2, 1
        image: 'data/images/image-loading.gif'
''')

class Root(FloatLayout):

    def load_content(self, content):
        for but in range(20):
            content.add_widget(Button(
                                text=str(but)))

class MyApp(App):
    def build(self):
        return Root()

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

インライン コメントが例を十分に明確にしてくれることを願っています。この場合、コンテンツにウィジェットを追加する関数にコンテンツの参照を渡すだけです。

独自のクラスの属性としてウィジェットにアクセスしたい場合があります。その場合は、次の方法を使用できます。

上記のメソッドは基本的に、id と同じ名前のObjectPropertyを追加し、id によって参照されるウィジェットの参照をそれに渡します。これで、簡単にアクセスできるように、Python クラスの id と同じ名前の属性ができました。上記の方法を使用すると、コードは次のようになります。

#!/usr/bin/env python2
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty

Builder.load_string('''
#:kivy 1.6
[SideBar@BoxLayout]:
    content: content
    orientation: 'vertical'
    size_hint: ctx.size_hint if hasattr(ctx, 'size_hint') else (1, 1)
    Image:
        source: ctx.image
        size_hint: (1, None)
        height: root.width
    GridLayout:
        cols: 2
        # just add a id that can be accessed later on
        id: content

<Root>:
    content: sb.content
    Button:
        center_x: root.center_x
        text: 'press to add_widgets'
        size_hint: .2, .2
        on_press:
            sb.content.clear_widgets()
            root.load_content()
    SideBar:
        id: sb
        size_hint: .2, 1
        image: 'data/images/image-loading.gif'
''')

class Root(FloatLayout):

    content = ObjectProperty(None)
    '''This is initialised to None and in kv code at line 28
    above (the one with `content: sb.content`) a ref to the
    actual content is passed'''

    def load_content(self):
        content = self.content
        for but in range(20):
            content.add_widget(Button(
                                text=str(but)))

class MyApp(App):
    def build(self):
        return Root()

if __name__ == '__main__':
        MyApp().run()
于 2013-03-19T15:34:42.703 に答える
0

python-micro-template ( https://github.com/diyism/python-micro-template ) を試してみると、リモートの動的テンプレート ファイルを読み込むことができます。

<:for i in range(30):#{#:>
Button:
    text: '<:=i:><:for j in range(6):#{#:><:=j:><:#}#:>'
    size: 480, 40
    size_hint: None, None
<:#}#:>
于 2014-04-07T12:03:24.690 に答える