使用python和.kv文件将静态小部件树转换为动态

时间:2016-02-08 20:38:38

标签: python widget kivy

我正在开发一个应用程序,我希望在垂直BoxLayout中添加n个图像帧。 n帧的数量取决于桌面屏幕大小。在此旁边,帧将动态填充图像。我能够以固定数量的帧以静态方式开发它。 现在我试图将其转换为动态解决方案,其中将根据屏幕的高度创建n个框架小部件(在下面的示例中为7个小部件)。而我迷路了..... :(

框架应该“坐着”。在顶栏和底栏之间。在.kv文件中,这由#Ilist:line。

表示

我有以下问题:

1)如何使用.kv文件动态添加这些小部件?

2)我如何参考这些单独的框架小部件来动态分配图像?例如:frame [idx] = swid?

非常感谢您的时间和提前分享知识。

Python文件pplay.py:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import StringProperty

class IListItem(Widget):
    sid = StringProperty('')
    image = StringProperty('')
    label = StringProperty('')
    pass

class IList(Widget):
    pass

class pplayHome(BoxLayout):

    def init_player(self):
        global swid

        self.Ilayout = IList()

        for idx in range (1, 7):
            swid = IListItem(
                    sid = "s" + str(idx),
                    image = 'empty_image.png',
                    label = 'Image' + str(idx)
            )
            self.Ilayout.add_widget(swid)

class pplayApp(App):
    def build(self):
        Window.clearcolor = (1,1,1,1)
        Window.borderless = True
        Window.size = 275, 1080
        homeWin = pplayHome()
        homeWin.init_player()
        return homeWin

if __name__ == "__main__":
    pplayApp().run()

和Kivy文件pplay.kv

# File: pplay.kv

<IList@BoxLayout>
    pid: self.pid
    source: self.source
    label: self.label
    size_hint_y: None
    height: "120dp"

    BoxLayout:
        orientation: "vertical"
        Label:
            size_hint: None, 1
            text: root.label

        Image:
            size_hint: None, 1
            source: root.source

<pplayHome>:
    orientation: "vertical"
    ActionBar:
        font_size: 8
        size: (275,25)
        # background color in Kivy acts as a tint and not just a solid color.
        # set a pure white background image first.
        background_image: 'white-bg.png'
        background_color: 0,.19,.34,1
        ActionView:
            ActionPrevious:
                with_previous: False
                app_icon: 'trButton.png'
            ActionOverflow:
            ActionButton:
                icon: 'butt_exit.png'
                on_press: root.exit_player()

#    Ilist:


    BoxLayout:
        height: "10dp"
        size_hint_y: None
        pos_x: 0
        canvas.before:
            Color:
                rgb: 0.55,0.77,0.25     # groen
            Rectangle:
                pos: self.pos
                size: self.size

1 个答案:

答案 0 :(得分:0)

你其实非常接近。 这是稍微更改的kv文件,添加了彩色矩形以说明尺寸:

# File: pplay.kv

<IListItem@Widget>
    source: ''
    label: ''
    size_hint_y: None
    height: "120dp"
    canvas.before:
        Color:
            rgb: 0.55,0.77*self.idx/7,0.25     # groen
        Rectangle:
            pos: self.pos
            size: self.size
    BoxLayout:
        orientation: "vertical"
        size: root.size
        pos: root.pos

        Label:
            size_hint: None, 1
            text: root.label
            canvas.before:
                Color:
                    rgb: 0.77*root.idx/7,0.55,0.25     # groen
                Rectangle:
                    pos: self.pos
                    size: self.size
        Image:
            size_hint: None, 1
            source: root.source

<pplayHome>:
    orientation: "vertical"
    ActionBar:
        font_size: 8
        size: (275,25)
        # background color in Kivy acts as a tint and not just a solid color.
        # set a pure white background image first.
        background_image: 'white-bg.png'
        background_color: 0,.19,.34,1
        ActionView:
            ActionPrevious:
                with_previous: False
                app_icon: 'trButton.png'
            ActionOverflow:
            ActionButton:
                icon: 'butt_exit.png'
                on_press: root.exit_player()

    IList:
        id: ilist
        orientation: 'vertical'
    BoxLayout:
        height: "10dp"
        size_hint_y: None
        pos_x: 0
        canvas.before:
            Color:
                rgb: 0.55,0.77,0.25     # groen
            Rectangle:
                pos: self.pos
                size: self.size

pplay.py中,关键部分是使用IList检索self.ids['ilist']窗口小部件。它还显示了如何通过区分属性检索其子项(IListItems)。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.properties import StringProperty, NumericProperty

class IListItem(Widget):
    idx = NumericProperty(1)
    sid = StringProperty('')
    image = StringProperty('')
    label = StringProperty('')
    pass

class IList(BoxLayout):
    pass

class pplayHome(BoxLayout):

    def init_player(self):
        #global swid

        print self.ids
        ilayout = self.ids['ilist']

        for idx in range (0, 7):
            swid = IListItem(
                    sid = "s" + str(idx),
                    image = 'empty_image.png',
                    label = 'Image' + str(idx),
                    idx=idx
            )
            ilayout.add_widget(swid)
        children_ids = [il.sid for il in ilayout.children]
        print children_ids
        print ilayout.children[children_ids.index('s3')]

class pplayApp(App):
    def build(self):
        # Window.clearcolor = (1,1,1,1)
        Window.borderless = True
        Window.size = 275, 1080
        homeWin = pplayHome()
        homeWin.init_player()
        return homeWin

if __name__ == "__main__":
    pplayApp().run()