kivy dynamically add custom widget to layout via python
Solution 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"
Solution 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.
techknowpro
Updated on June 08, 2022Comments
-
techknowpro almost 2 years
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.