kivy dynamically add custom widget to layout via python

我的梦境 提交于 2020-05-27 06:40:49

问题


I was able to get my layout working with static kivy language but I need to be able to add items to my list via python. I've tried several things but can't seem to get anything working correctly. Here's what I have working statically.

main.py

#!/usr/bin/python

import os
import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.core.window import Window
from kivy.logger import Logger

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class CustomButton(Button):
    pass

    def click(button):
        Logger.info(button.title + ": wid=" + button.wid)


class SelectFruit(App, BoxLayout):
    icon = 'ico/fruit.png'
    title = 'Awesome Fruit Picker'

    def build(self):
        Window.size = 400, (4 * 78)     
        return SelectFruit()

if __name__ in ('__main__'):
    SelectFruit().run()

selectfruit.kv

#:kivy 1.8.0

<CustomButton@Button>:
    wid: ""
    image: ''
    title: ''
    label: ''
    on_press: self.click()
    BoxLayout:
        orientation: "horizontal"
        size: self.parent.size      # match the button's size
        pos: self.parent.pos        # match the button's position
        padding: 5   
        spacing: 10

        Image:
            size_hint: None, 1
            source: root.image
            size: 64, 64
            valign: "middle"


        Label:
            size_hint: None, 1
            text: root.label
            valign: "middle"
            size: 400, 64
            text_size: self.size


<SelectFruit>
    orientation: "vertical"
    padding: 2

    CustomButton:
        wid: "0"
        image: "ico/apple.png"
        title: "apple"
        label: "Apple: Super Sweet\nPicked On: 12/26/2014, 2:01 PM"

    CustomButton:
        wid: "1"
        image: "ico/banana.png"
        title: "banana"
        label: "Banana: Want a bunch?\nPicked On: 2/18/2014, 2:01 PM"

    CustomButton:
        wid: "2"
        image: "ico/strawberry.png"
        title: "strawberry"
        label: "Strawberry: Yummy Yummy\nPicked On: 5/6/2014, 2:01 PM"

    CustomButton:
        wid: "3"
        image: "ico/orange.png"
        title: "orange"
        label: "Orange: Florida's Best\nPicked On: 4/21/2014, 2:01 PM"

I just need to be able to add each CustomButton programmatically to my layout rather than via the kivy language file. Any help is greatly appreciated.


回答1:


Here's the working code showing some items added in kivy language and then some additional items added programmatically. I also added the ScrollView, a configuration setting to keep the window from being resized and code to highlight the selected item.

I hope this is helpful to someone in the future. :)

main.py

#!/usr/bin/python

from kivy.config import Config
Config.set('graphics','resizable',0)

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.core.window import Window
from kivy.properties import ObjectProperty, StringProperty
from kivy.logger import Logger

from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button


class ButtonListItem(Button):
    wid = StringProperty('')
    image = StringProperty('')
    title = StringProperty('')
    label = StringProperty('')
    pass

    def click(button):
        global app
        app.clearSelection()
        button.background_color = (0,160,66,.9)
        Logger.info(button.title + ": wid=" + button.wid)

class ButtonList(GridLayout):
    pass

class SelectFruit(App):
    icon = 'ico/fruit.png'
    title = 'Awesome Fruit Picker'

    def build(self):
        Window.size = 400, (4 * 90)

        self.layout = ButtonList()
        self.layout.size = 400, (8 * 78)

        self.root = ScrollView(
                        size_hint=(None, None), 
                        size=Window.size,
                        scroll_type=['bars', 'content']
                    )
        self.root.add_widget(self.layout)

        ib = ButtonListItem(
                wid="0", 
                image="ico/apple.png", 
                title="apple", 
                label="Apple: Super Sweet\nPicked On: 12/26/2014, 2:01 PM"
            )
        self.layout.add_widget(ib)

        ib = ButtonListItem(
                wid="1", 
                image="ico/banana.png", 
                title="banana", 
                label="Banana: Want a bunch?\nPicked On: 2/18/2014, 2:01 PM"
            )
        self.layout.add_widget(ib)

        ib = ButtonListItem(
                wid="2", 
                image="ico/strawberry.png", 
                title="strawberry", 
                label="Strawberry: Yummy Yummy\nPicked On: 5/6/2014, 2:01 PM"
            )
        self.layout.add_widget(ib)

        ib = ButtonListItem(
                wid="3", 
                image="ico/orange.png", 
                title="orange", 
                label="Orange: Florida's Best\nPicked On: 4/21/2014, 2:01 PM"
            )
        self.layout.add_widget(ib)

        return self.root

    def clearSelection(self):
        for child in self.layout.children:
            child.background_color = (1,1,1,1)

if __name__ == "__main__":
    app = SelectFruit()
    app.run()

selectfruit.kv

#:kivy 1.8.0

<ButtonListItem@Button>:
    wid: self.wid
    image: self.image
    title: self.title
    label: self.label
    on_press: self.click()
    BoxLayout:
        orientation: "horizontal"
        size: self.parent.size      # match the button's size
        pos: self.parent.pos        # match the button's position
        padding: 5   
        spacing: 10

        Image:
            size_hint: None, 1
            source: root.image
            size: 64, 64
            valign: "middle"


        Label:
            size_hint: None, 1
            text: root.label
            valign: "middle"
            size: 400, 64
            text_size: self.size


<ButtonList@GridLayout>
    id: output
    cols: 1
    size_hint_y: None
    height: self.minimum_height

    ButtonListItem:
        wid: "0"
        image: "ico/apple.png"
        title: "xapple"
        label: "Apple: Super Sweet\nPicked On: 12/26/2014, 2:01 PM"

    ButtonListItem:
        wid: "1"
        image: "ico/banana.png"
        title: "xbanana"
        label: "Banana: Want a bunch?\nPicked On: 2/18/2014, 2:01 PM"

    ButtonListItem:
        wid: "2"
        image: "ico/strawberry.png"
        title: "xstrawberry"
        label: "Strawberry: Yummy Yummy\nPicked On: 5/6/2014, 2:01 PM"

    ButtonListItem:
        wid: "3"
        image: "ico/orange.png"
        title: "xorange"
        label: "Orange: Florida's Best\nPicked On: 4/21/2014, 2:01 PM"



回答2:


def click(button):

It is normal to call the first argument of a method self, referring to the instance whose method was called.

class SelectFruit(App, BoxLayout):

This seems like a recipe for disaster, there's no need to have the App also be a Widget and it has the potential for weird bugs since it means you'll have two Apps running at once. You should separate this into separate widget and app classes.

I need to be able to add items to my list via python

I'm not clear on exactly which part of this is the problem, but you should be able to add to (for instance) the root widget with App.get_running_app().root.add_widget(your_widget), where your_widget is for instance a new instance of CustomButton.



来源:https://stackoverflow.com/questions/28577828/kivy-dynamically-add-custom-widget-to-layout-via-python

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