kivy dynamically add and remove dropdown entries - python

my app should dynamically add and remove items in the dropdown menu. The adding of buttons works, but I didn't get it working to remove the added buttons.
py:
import kivy
kivy.require('1.7.2') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
class HomeScreen(Screen):
addButton = ObjectProperty(None)
removeButton = ObjectProperty(None)
top_layout = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(HomeScreen, self).__init__(*args, **kwargs)
def resetBoxes(self):
self.ids.btn_release.text = "Release"
self.ids.btn_version.text = "Version"
self.ids.btn_device.text = "Device"
return
def removeButtonPressed(self):
self.dropdown.remove_widget(self)
return
def addButtonPressed(self):
self.dropdown = DropDown()
notes = ['Features', 'Suggestions', 'Abreviations', 'Miscellaneous']
for note in notes:
btn = Button(text=note, size_hint_y=None, height=20)
btn.bind(on_release=lambda btn: self.dropdown.select(btn.text))
self.dropdown.add_widget(btn)
self.ids.btn_release.bind(on_release=self.dropdown.open)
self.dropdown.bind(on_select=lambda instance, x: setattr(self.ids.btn_release, 'text', x))
return
def btn_releaseClicked(self):
self.ids.btn_release.text="clicked"
def btn_versionClicked(self):
self.ids.btn_version.text="clicked"
def btn_deviceClicked(self):
self.ids.btn_device.text="clicked"
class dropdApp(App):
def build(self):
return HomeScreen()
if __name__ == '__main__':
dropdApp().run()
kv:
<HomeScreen>:
id: home_screen
addButton: addButtonID
removeButton: removeButtonID
top_layout: topLayoutID
orientation: 'vertical'
FloatLayout:
size_hint: 1, 1
Button:
id: addButtonID
text: 'Add'
pos_hint: {'x': .35, 'y': .70}
size_hint: .3, .08
valign: 'middle'
halign: 'center'
text_size: self.size
on_release: root.addButtonPressed()
Button:
id: removeButtonID
text: 'Remove'
pos_hint: {'x': .35, 'y': .60}
size_hint: .3, .08
valign: 'middle'
halign: 'center'
text_size: self.size
on_release: root.removeButtonPressed()
BoxLayout:
id: topLayoutID
size_hint: 1, .05
pos_hint: {'x': 0, 'y': .90}
Button:
id: btn_release
text: 'Release'
on_press: root.btn_releaseClicked()
Button:
id: btn_version
text: 'Version'
on_press: root.btn_versionClicked()
Button:
id: btn_device
text: 'Device'
on_press: root.btn_deviceClicked()

Use clear_widgets() to get the result you want - removing all buttons from dropdown - or store some reference to those buttons in dropdown somewhere and remove only desired ones.
def removeButtonPressed(self):
self.dropdown.clear_widgets()

Related

Apply screen transition direction to an element card inside an expansion panel and screen kivy/kivymd

I am a new programmer, working on a Kivy app and I need to use screens (screen manager), the issue is that I am using element cards as but buttons, and it is supposed that when using on_release it will change the screen, however if I include root.manager.transition.direction = "left" I get the error AttributeError: 'MyContentComunes' object has no attribute 'screen'. I don't know if anyone could help me with this.
Here is a piece of code.
from kivy.app import App
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelTwoLine
from kivy.core.window import Window
from kivymd.color_definitions import colors
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.screen import MDScreen
KV = '''
WindowManager:
id: screen_manager
PrincipalWindow:
LenghtWindow:
<PrincipalWindow>:
name: "principal"
BoxLayout:
MDToolbar:
title: "Conversor"
pos_hint: {"top": 1}
ScrollView:
pos_hint: {"center_x": .5, "center_y": .5} #UbicaciĆ³n
size_hint: 0.90, 0.75
GridLayout:
halign: 'center'
cols: 1
adaptive_height: True
id: box
<LenghtWindow>:
name: "Lenght"
md_bg_color: 0.34,0.024,0.292,1
MDBoxLayout:
orientation: "vertical"
MDToolbar:
title: "Conversor"
pos_hint: {"top": 1}
Button:
text: "Back"
font_size: 32
on_release:
app.root.current = "principal"
root.manager.transition.direction = "right"
<MyContentComunes>:
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
ElementCard:
image:"1490820814-13_82405.png"
text:"Longitud"
id:longitud
on_release:
app.root.current = "Lenght"
root.manager.transition.direction = "left"
<ElementCard#MDCard>:
md_bg_color: app.theme_cls.primary_color
padding: dp(15)
spacing: dp(15)
size_hint: 1, None
ripple_behavior: True
# on_release: print("worked")
image:''
text:""
items_count:""
subtext:''
orientation: "vertical"
Image:
source:root.image
halign:"center"
padding: dp (4)
spacing: dp(4)
MDBoxLayout:
orientation: "vertical"
MDLabel:
halign:"center"
text:root.text
MDLabel:
halign:"center"
font_style:"Caption"
text:root.subtext
'''
Window.size = 324, 720
class Conversor(MDApp):
def build(self):
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.list_items = [] # Dictionary where the items are stored
self.category_list1 = ['Comunes']
def on_start(self):
for category in self.category_list1:
self.root.get_screen('principal').ids.box.add_widget(
MDExpansionPanel(
icon="3.png",
content=MyContentComunes(),
panel_cls=MDExpansionPanelTwoLine(
text=category,
secondary_text="Ver las unidades"
)
)
)
class MyContentComunes(BoxLayout):
pass
class PrincipalWindow(Screen):
pass
class LenghtWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
Conversor().run()
The element card is inside an expansion panel, which is also inside a screen.
Try adding Screen to class MyContentComunes.
class MyContentComunes(BoxLayout, Screen):
pass
And I recommend you to organize your code like this. It will make your work more eaisier.
from kivy.app import App
from kivymd.app import MDApp
# import libraries ...
KV = '''
# Your KV File
'''
Window.size = 324, 720
class MyContentComunes(BoxLayout, Screen):
pass
class PrincipalWindow(Screen):
pass
class LenghtWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class Conversor(MDApp):
def build(self):
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
def __init__(self, **kwargs):
# Code
.
.
.
def on_start(self):
# Code
.
.
.
Conversor().run()

MDSelectionList properties cannot be modified

I am using an MDSelectionList inside a tab with an MDNavigationRail to switch between screens, however, when I try to customize the MDSelectionList, none of the visual changes apply. I thought that maybe it is a problem with the widget itself but then I separated it and the property changes worked. How can I make the changes apply to the selection list? (I am using kivymd 0.104.2.dev0 from the master branch)
My Code:
from kivy.config import Config
Config.set('graphics', 'width', '850')
Config.set('graphics', 'height', '530')
Config.set('graphics', 'minimum_width', '850')
Config.set('graphics', 'minimum_height', '530')
from kivy.lang import Builder
from kivymd.uix.card import MDCard
from kivymd.uix.tab import MDTabsBase
from kivymd.app import MDApp
class SettingsTab(MDCard, MDTabsBase):
pass
class Example(MDApp):
def __init__(self, **kwargs):
super(Example, self).__init__(**kwargs)
self.kv = Builder.load_string('''
#:kivy 2.0.0
<SettingsTab>:
orientation: "vertical"
size_hint: .95, .95
pos_hint: {"center_x": .5, "center_y": .5}
border_radius: 5
radius: [5]
elevation: 20
BoxLayout:
MDNavigationRail:
color_active: app.theme_cls.primary_color
MDNavigationRailItem:
icon: "list-status"
on_release:
screens.current = "downloads_screen"
MDNavigationRailItem:
icon: "cog"
on_release:
screens.current = "settings"
MDNavigationRailItem:
icon: "information"
on_release:
screens.current = "activity_log"
ScreenManager:
id: screens
Screen:
name: "downloads_screen"
Screen:
name: "activity_log"
Screen:
name: "settings"
MDTabs:
SettingsTab:
title: "DOWNLOAD"
MDSelectionList:
overlay_color: 1, 0, 0, .5
icon_bg_color: 0, 0, 0, 0
icon_check_color: 0, 0, 0, 0
OneLineIconListItem:
text: "Just me!"
IconLeftWidget:
icon: "circle-outline"
pos_hint: {"center_x": .5, "center_y": .5}
OneLineIconListItem:
text: "Just me!"
IconLeftWidget:
icon: "circle-outline"
OneLineIconListItem:
text: "Just me!"
IconLeftWidget:
icon: "circle-outline"
OneLineIconListItem:
text: "Just me!"
IconLeftWidget:
icon: "circle-outline"
SettingsTab:
title: "COLOR"
SettingsTab:
title: "INFO"''')
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Blue"
self.theme_cls.accent_palette = "Teal"
return self.kv
if __name__ == '__main__':
Example().run()
Try something like this.
from kivy.lang import Builder
from kivymd.uix.card import MDCard
from kivymd.uix.tab import MDTabsBase
from kivymd.app import MDApp
kv = ("""
<Check#ILeftBodyTouch+MDCheckbox>:
group: 'group'
size_hint: None, None
size: dp(48), dp(48)
<SettingsTab>:
orientation: "vertical"
size_hint: .95, .95
pos_hint: {"center_x": .5, "center_y": .5}
border_radius: 5
radius: [5,]
elevation: 20
BoxLayout:
MDNavigationRail:
color_active: app.theme_cls.primary_color
MDNavigationRailItem:
icon: "cog"
on_release:
screens.current = "settings"
ScreenManager:
id: screens
Screen:
name: "settings"
MDTabs:
SettingsTab:
title: "DOWNLOAD"
MDList:
spacing: 10
OneLineAvatarIconListItem:
text: "Just me!"
Check:
OneLineAvatarIconListItem:
text: "Just me!"
Check:
OneLineAvatarIconListItem:
text: "Just me!"
Check:
""")
class SettingsTab(MDCard, MDTabsBase):
pass
class Example(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.kv = Builder.load_string(kv)
def build(self):
return self.kv
if __name__ == '__main__':
Example().run()

Why is my RecycleView Kivy table not refreshing?

So whenever I try to delete an existing item from the recycleview, I have to close the application and open it again to see the deletion. I want to make it so it will automatically refresh the recycleview and show the deletion.
To navigate the application, start by going to Record new Automation, then type a name at the top and press Save in the bottom right hand corner. Then you must close the application and reopen it before pressing Open old Automation. Then click on the item you made and press Delete at the bottom. As you can see, the data is deleted, but the visual has no updated.
kek.py
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.properties import NumericProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.storage.jsonstore import JsonStore
store = JsonStore('automations.json')
class CustomScreen(Screen):
hue = NumericProperty(0)
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
global selected
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
selected = '{0}'.format(rv.data[index])[10:-2]
else:
print("selection removed for {0}".format(rv.data[index]))
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x)} for x in store]
class RVScreen(Screen):
def storedelete(self):
try:
store.delete(selected)
refresh_view_attrs(self, rv, index, data)
except Exception:
print("Select Something")
class NewAutoScreen(Screen):
def recordname(self, inputname):
if inputname:
try:
store.put(inputname, )
except Exception:
print("error")
class AutrumApp(App):
def build(self):
root = ScreenManager()
root.add_widget(CustomScreen(name='Autrum'))
root.add_widget(RVScreen(name='RVScreen'))
root.add_widget(NewAutoScreen(name='NewAutoScreen'))
return root
if __name__ == '__main__':
AutrumApp().run()
autrumapp.kv
#:kivy 2.0
<CustomScreen>:
hue: 4
canvas:
Color:
hsv: self.hue, .5, .3
Rectangle:
size: self.size
Label:
font_size: 42
text: root.name
Button:
text: 'Record new Automation'
size_hint: None, None
pos_hint: {'right': 1}
size: 200, 75
on_release:
root.manager.current = "NewAutoScreen"
root.manager.transition.direction = 'left'
root.manager.transition.duration = .25
Button:
text: 'Open old Automation'
size_hint: None, None
pos_hint: {'left': 1}
size: 200, 75
on_release:
root.manager.current = "RVScreen"
root.manager.transition.direction = 'right'
root.manager.transition.duration = .25
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RV>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
<RVScreen>:
id: old
FloatLayout:
orientation: "vertical"
RV:
Button:
text: 'Back'
pos_hint: {'right': 1}
size_hint: .1, .1
on_release:
root.manager.current = "Autrum"
root.manager.transition.direction = 'left'
root.manager.transition.duration = .25
Button:
text: 'Open'
pos_hint: {'center_x': .05}
size_hint: .1, .1
Button:
text: 'Edit'
pos_hint: {'center_x': .15}
size_hint: .1, .1
Button:
text: 'Delete'
pos_hint: {'center_x': .25}
size_hint: .1, .1
on_press:
old.storedelete()
<NewAutoScreen>:
id: recorder
FloatLayout:
Button:
text: 'Back'
size_hint: .1, .1
pos_hint: {'left': 1, 'bottom': 1}
on_release:
root.manager.current = "Autrum"
root.manager.transition.direction = 'right'
root.manager.transition.duration = .25
TextInput:
id: entry
size_hint: .5, .05
pos_hint: {'center_x': .5, 'top': 1}
multiline: False
text: ""
Button:
size_hint: .1, .1
pos_hint: {'right': 1, 'bottom': 1}
text: "Save"
on_press: recorder.recordname(entry.text)
Button:
size_hint: .2, .1
pos_hint: {'center_x': .4, 'bottom': 1}
text: "Start Recording"
Button:
size_hint: .2, .1
pos_hint: {'center_x': .6, 'bottom': 1}
text: "Stop Recording"
You must also update the data attribute of the RecycleView to reflect the deletion. You can do that by first modifying the kv to provide easy access to the RecycleView like this:
<RVScreen>:
rv: rv # handy reference to the RV
id: old
FloatLayout:
orientation: "vertical"
RV:
id: rv # the id referenced above
And using the reference to the RecycleView in your storedelete() method:
class RVScreen(Screen):
def storedelete(self):
try:
store.delete(selected)
self.rv.data = [{'text': str(x)} for x in store] # Update RecycleView
except Exception:
print("Select Something")

Changing text of 2 buttons from MDDropdownMenu in KivyMD

I have problems with changing button text on 2 different buttons after clicking on the MDMenuItem from MDDropdownMenu - there is only one button can change self text.
Each button have to change the text separately.
In that case - two buttons, two dropdownmenus, different labels in differend menus and each button have their own text from choosen in dropdown list.
There is main.py:
from kivy.app import App
from kivymd.theming import ThemeManager
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
def toast(text):
from kivymd.toast.kivytoast import toast
toast(text)
class MyScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.menu_items = [
{
"viewclass": "MDMenuItem",
"text": "text%d" % i,
"callback": self.callback,
}
for i in range(1, 3)
]
def change_variable(self, value):
print("\nvalue=", value)
self.VARIABLE = value
print("\tself.VARIABLE=", self.VARIABLE)
def callback(self, *args):
toast(args[0])
class MainApp(App):
title = "KivyMD MDDropdownMenu Demo"
theme_cls = ThemeManager()
def build(self):
return MyScreen()
if __name__ == "__main__":
MainApp().run()
There is main.kv:
#:import MDDropdownMenu kivymd.menus.MDDropdownMenu
#:import MDRaisedButton kivymd.button.MDRaisedButton
<MDMenuItem>:
on_release:
app.root.change_variable(self.text)
app.root.ids.mainbutton.text = self.text
<MyScreen>:
name: 'myscrn'
AnchorLayout:
anchor_y: 'center'
BoxLayout:
orientation: 'vertical'
size_hint: 0.1, 0.5
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
spacing: dp(10)
MDRaisedButton:
id: mainbutton
size_hint: None, None
size: 3 * dp(48), dp(48)
text: 'MDButton1'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
opposite_colors: True
on_release: MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
MDRaisedButton:
id: secondbutton
size_hint: None, None
size: 3 * dp(48), dp(48)
text: 'MDButton2'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
opposite_colors: True
on_release: MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
Thanks for help and sorry for bad English!
The solution requires the following enhancements to the Python code and kv file.
main.py
Add a class attribute, self.menu_button = None in the constructor of class MyScreen
Snippets - py file
class MyScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
...
self.menu_button = None
kv file
Initialize root.menu_button in the on_release event of MDRaisedButton:
Replace app.root.ids.mainbutton.text with app.root.menu_button.text
Snippets - kv file
<MDMenuItem>:
on_release:
...
app.root.menu_button.text = self.text
<MyScreen>:
...
MDRaisedButton:
id: mainbutton
...
on_release:
root.menu_button = mainbutton
MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
MDRaisedButton:
id: secondbutton
...
on_release:
root.menu_button = secondbutton
MDDropdownMenu(items=root.menu_items, width_mult=4).open(self)
Output

Python : How to get value of dynmaic row

I am new to python and kivy.
I am trying to get value of dynamic row.But now i am getting value like this
Column2
Column1
Can someone tell me how to get value like this ?
1,column1,column2
2,column1,column2
Because i have three column in my database table like id,name,value and i want to insert value in database table through loop
I am using this code
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
for ch in row.children:
if isinstance(ch, TextInput):
values.append(ch.text)
lenArray = len(values)
for x in range(0, lenArray):
print (values[x])
demo.py
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.uix.textinput import TextInput
Window.size = (450, 525)
class display(Screen):
def add_more(self):
self.ids.rows.add_row()
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
for ch in row.children:
if isinstance(ch, TextInput):
values.append(ch.text)
lenArray = len(values)
for x in range(0, lenArray):
print (values[x])
class Row(BoxLayout):
button_text = StringProperty("")
id = ObjectProperty(None)
class Rows(BoxLayout):
orientation = "vertical"
row_count = 0
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
self.add_row()
def add_row(self):
self.row_count += 1
self.add_widget(Row(button_text=str(self.row_count),id=str("test"+str(self.row_count))))
class test(App):
def build(self):
self.root = Builder.load_file('demo.kv')
return self.root
if __name__ == '__main__':
test().run()
demo.kv
<Row>:
orientation: "horizontal"
spacing: 0, 5
Button:
text: root.button_text
size_hint_x: .2
TextInput:
text:"Column1"
size_hint_x: .8
TextInput:
text:"Column2"
size_hint_x: .8
display:
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
Button:
size_hint_x: .2
text: "+Add More"
valign: 'bottom'
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
Label:
size_hint_x: .2
text: "SN"
valign: 'bottom'
Label:
size_hint_x: .8
text: "Value"
valign: 'bottom'
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
padding : 10, 0
spacing: 10, 10
size_hint: .5, .7
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
on_release:
root.insert_value()
Button:
text: 'Cancel'
on_release: root.dismiss()
To maintain a structure we must create a list of lists, then in each list the first parameter is the text of the Button that we filter through isinstance(), and the other elements are concatenated.
[...]
from kivy.uix.button import Button
class display(Screen):
def add_more(self):
self.ids.rows.add_row()
def insert_value(self):
values = []
rows = self.ids.rows
for row in reversed(rows.children):
vals = []
for ch in reversed(row.children):
if isinstance(ch, TextInput):
vals.append(ch.text)
if isinstance(ch, Button):
vals.insert(0, ch.text)
values.append(vals)
for val in values:
print("{},{},{}".format(*val))
[...]
One option is to add a ListProperty to your Row class that stores the values of the row in the order you want, which makes it easier to obtain them later.
You can use a ListView to show the rows.
Demo.kv:
<Row>:
values: row_id.text, col1.text, col2.text
orientation: "horizontal"
spacing: 0, 5
size_hint_y: None
height: 30
Button:
id: row_id
text: root.button_text
size_hint_x: .2
TextInput:
id: col1
text:"Column1"
size_hint_x: .8
TextInput:
id: col2
text:"Column2"
size_hint_x: .8
<Rows>:
content: content
BoxLayout:
id: content
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
Display:
rows: rows
BoxLayout:
orientation: "vertical"
padding : 20, 20
BoxLayout:
orientation: "horizontal"
Button:
size_hint_x: .2
text: "+Add More"
valign: 'bottom'
on_press: root.add_more()
BoxLayout:
orientation: "horizontal"
Label:
size_hint_x: .2
text: "SN"
valign: 'bottom'
Label:
size_hint_x: .8
text: "Value"
valign: 'bottom'
Rows:
id: rows
BoxLayout:
orientation: "horizontal"
padding : 10, 10
spacing: 10, 10
size_hint: .5, .7
pos_hint: {'x': .25, 'y':.25}
Button:
text: 'Ok'
on_release:
root.insert_value()
Button:
text: 'Cancel'
on_release: root.dismiss()
Demo.py:
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, StringProperty, ObjectProperty
from kivy.uix.scrollview import ScrollView
from kivy.clock import Clock
Window.size = (450, 525)
class Display(Screen):
rows = ObjectProperty(None)
def __init__(self, **kwargs):
super(Display, self).__init__(**kwargs)
def add_more(self):
self.rows.add_row()
def insert_value(self):
values = [row.values for row in reversed(self.rows.content.children)]
for row in values:
print(row)
class Row(BoxLayout):
button_text = StringProperty("")
id = ObjectProperty(None)
values = ListProperty()
class Rows(ScrollView):
row_count = 0
content = ObjectProperty(None)
def __init__(self, **kwargs):
super(Rows, self).__init__(**kwargs)
Clock.schedule_once(self.add_row)
def add_row(self, *args):
self.row_count += 1
self.content.add_widget(Row(button_text=str(self.row_count),
id="test" + str(self.row_count)))
class Test(App):
def build(self):
self.root = Builder.load_file('Demo.kv')
return self.root
if __name__ == '__main__':
Test().run()

Categories