clear_widgets()
function, it removes all the child widgets. Following is the code.from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.properties import NumericProperty, StringProperty
from kivy.uix.dropdown import DropDown
class CustomTextInput(TextInput):
# Numeric property defined for use in both Python and Kivy (binding)
max_characters = NumericProperty(0)
# Override the default behaviour of the insert_text method
def insert_text(self, substring, from_undo=False):
if len(self.text)==self.max_characters and self.max_characters>0:
substring=""
TextInput.insert_text(self, substring, from_undo)
class ImageLabel(BoxLayout):
source = StringProperty('atlas://data/images/defaulttheme/audio-volume-high')
text = StringProperty('default text')
class ImageLabelButton(ButtonBehavior, ImageLabel):
pass
class ImageLabelButtonTop(ButtonBehavior, ImageLabel):
pass
class DropDownScreen(Screen):
def add_dd_values(self):
dd_input = App.get_running_app().root.get_screen('dropdown_screen').ids.textinput_num.text
print("TextInputBox: ", dd_input, "\n")
print("Length: ",len(dd_input))
print("Data Type: ", type(dd_input))
# Check if the text input box is empty and assign a default string of '0' so that int conversion and numerical operations do not fail with an error.
if dd_input == '':
dd_input="0"
print(int(dd_input)+1)
# Reset dropdown list. Clear all existing child widgets of dropdown including the original 2 buttons defined inside the kv file.
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.clear_widgets()
for x in range(int(dd_input)):
if x%2==0:
print(x,"is an even number")
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.add_widget(ImageLabelButton(source="twitter-48.png",text="Twitter"))
else:
print(x,"is an odd number")
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.add_widget(ImageLabelButton(source="linkedin-2-48.png",text="LinkedIn"))
class MyScreenManager(ScreenManager):
pass
class DropApp(App):
def build(self):
# Initialize root widget
# Screen Manager instance
sm = MyScreenManager()
# DropDown Screen Instance
dds = DropDownScreen()
sm.add_widget(dds)
return sm
if __name__ == '__main__':
# Run application
DropApp().run()
<DropDownScreen>:
name: 'dropdown_screen'
canvas.before:
Color:
rgba: 255/255, 255/255, 255/255, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
Label:
text: 'No. of drop-down buttons:'
markup: True
color: 0, 0, 0, 1
CustomTextInput:
id: textinput_num
max_characters: 2
multiline: False
input_filter: 'int'
BoxLayout:
ImageLabelButtonTop: # conflict in the on_release defined for ImageLabelButton and this instance.
id: parent_button
source: 'expand-arrow-48.png'
text: 'Expand Drop-Down'
on_release:
root.add_dd_values()
dropdown.open(self)
print("self in ImageLabelButtonTop points to ", self, "\n")
on_parent: dropdown.dismiss()
size_hint_y: None
height: '48dp'
DropDown:
id: dropdown
on_select:
# parent_button.text = str(args[1]) # args is a reserved keyword which returns only two values: object alias (0) and data (1).
parent_button.text = args[1][0]
parent_button.source = args[1][1]
print("Invoked inside dropdown")
print(args, app.root, root, self, "\n") # root - Screen, self - DropDown object
ImageLabelButton:
source: 'twitter-48.png'
text: 'Twitter'
ImageLabelButton:
source: 'linkedin-2-48.png'
text: 'LinkedIn'
BoxLayout:
Label:
text: 'Test dynamic drop-down'
markup: True
color: 0, 0, 0, 1
<ImageLabel>:
orientation: 'horizontal'
size_hint_y: None
height: '48dp'
spacing: 1
Image:
keep_ratio: True
source: root.source # root - ImageLabel
Label:
markup: True
text: root.text # root - ImageLabel
color: 0, 0, 0, 1
<ImageLabelButton>:
on_release:
# Tuple returned in dropdown.select() method to pass two values bundled as one.
app.root.get_screen('dropdown_screen').ids.dropdown.select((self.text, self.source))
print("Invoked inside ImageLabelButton rule")
print(app.root, root, self, "\n") # app.root - Screen, root - ImageLabelButton object, self - ImageLabelButton object
<CustomTextInput>:
use_bubble: True
use_handles: True
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.clear_widgets()
What I would like to achieve is this:
I guess, it may work if I store the reference of the dynamically created child widgets in a list or dictionary and then delete them through a separate remove button. But I am not sure how to code it inside a Python function.
Can someone please help?
Thanks
I created the method remove_other_2widets. I assumed that the text on the dropdowns would be unique, and delete the widgets that were not Twitter on LinkedIn. I changed the text on the dynamically created buttons to make my assumption true.
class DropDownScreen(Screen):
def add_dd_values(self):
dd_input = App.get_running_app().root.get_screen('dropdown_screen'
).ids.textinput_num.text
# note: self == App.get_running_app().root.get_screen('dropdown_screen')
print("TextInputBox: ", dd_input, "\n")
print("Length: ",len(dd_input))
print("Data Type: ", type(dd_input))
# Check if the text input box is empty and assign a default string of '0' so that int conversion and numerical operations do not fail with an error.
if dd_input == '':
dd_input="0"
print(int(dd_input)+1)
# Reset dropdown list. Clear all existing child widgets of dropdown including the original 2 buttons defined inside the kv file.
self.remove_other_widgets()
#App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.clear_widgets()
for x in range(int(dd_input)):
if x%2==0:
print(x,"is an even number")
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.add_widget(ImageLabelButton(source="twitter-48.png",text="Not Twitter"))
else:
print(x,"is an odd number"
)
App.get_running_app().root.get_screen('dropdown_screen').ids.dropdown.add_widget(ImageLabelButton(source="linkedin-2-48.png",text="Not LinkedIn"))
def remove_other_widgets(self):
children = self.ids.dropdown.container.children.copy()
for w in children:
if w.text not in ['Twitter', 'LinkedIn']:
self.ids.dropdown.container.remove_widget(w)
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/8723cb5c-e7f5-41c4-88f4-22db6087b04eo%40googlegroups.com.
children = self.ids.dropdown.container.children.copy()
The container holds the dropdown items:
This concept shows up in a few of the widgets. I first ran into it with the TabbedPanel.
From: Shoumik Das
Sent: Sunday, June 21, 2020 10:30 AM
To: Kivy users support
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/e8fa58df-6c5a-4efa-8aa5-e4101f4ba951o%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5eef9f52.1c69fb81.315f7.c178SMTPIN_ADDED_MISSING%40gmr-mx.google.com.