KivyMD How to add images in the Lists items from py? - kivy

I know that I can add images or icons to the items of the list in the kivy file. For example:
ScrollView:
MDList:
id: elements_list_container
TwoLineAvatarListItem:
text: "Hello World"
secondary_text: "Secondary text"
ImageLeftWidget:
source: "image.png"
However, if I create the list from the python file, I dont know how to add those images and how to add functionallity whene is clicked. I just know how to add text:
for i in range(20):
items = TwoLineListItem(text="Producto" + str(i), secondary_text="Categoria",)
self.ids.elements_list_container.add_widget(items)

from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd.app import MDApp
from kivymd.uix.list import IRightBodyTouch, OneLineAvatarIconListItem
from kivymd.uix.selectioncontrol import MDCheckbox
from kivymd.icon_definitions import md_icons
KV = '''
<ListItemWithCheckbox>:
IconLeftWidget:
icon: root.icon
RightCheckbox:
MDBoxLayout:
ScrollView:
MDList:
id: scroll
'''
class ListItemWithCheckbox(OneLineAvatarIconListItem):
'''Custom list item.'''
icon = StringProperty("android")
class RightCheckbox(IRightBodyTouch, MDCheckbox):
'''Custom right container.'''
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
def on_start(self):
icons = list(md_icons.keys())
for i in range(30):
self.root.ids.scroll.add_widget(
ListItemWithCheckbox(text=f"Item {i}", icon=icons[i])
)
MainApp().run()```

Related

Not able to remove Widgets which were dynamically added to screen in Kivy

I am trying to add buttons dynamically when some text is typed on a text input. In order to achieve search select combo box in KIvy.
Even though i am able to add widgets when some text is typed , not able to remove those added widgets when the text typed is removed.
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix import dropdown
from kivy.uix.textinput import TextInput
# from kivymd.app import MDApp
kivy.require('1.9.0')
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.base import runTouchApp
from kivy.uix.screenmanager import ScreenManager,Screen
class ScreenOne(Screen):
def change_text(self,root,val):
pass
def create_dropdown(self,root,value):
print("value is :" + value)
if value == "":
result = ""
print(root.ids)
else:
lang = ["aa","aaa", "bsa","cds","dds", "ddyus"]
result = list(filter(lambda x: x.startswith(value), lang))
for i in range (0,len(result)):
self.textinput = Button()
self.textinput.id = 'textinput'+ str(i)
self.textinput.text = result[i]
self.textinput.size_hint= (.3, .06)
self.textinput.font_size= '14sp'
self.textinput.pos_hint= {'center_x': 0.5, 'center_y': 0.8-(i+1)/10, }
root.ids.screen1.add_widget(self.textinput)
sm = Builder.load_string("""
ScreenManager:
ScreenOne:
id: screen1
name: "screen_one"
TextInput:
id: input1
hint_text:'Select input Language'
size_hint: (.3,.06)
font_size: '14sp'
pos_hint:{'center_x':0.5,'center_y':0.8,}
on_text: root.ids.screen1.create_dropdown(root,input1.text)
""")
class demo(App):
def build(self):
return sm
app=demo()
# app.run()
runTouchApp(sm)
in UI when a is typed cahn see the below image
but when i clear the input text , i am still able to see the widgets added previously
I neet some logic to remove the added widgets when the text typed in input box is cleared.
Try adding this:
result = list(filter(lambda x: x.startswith(value), #from your cod
lang)) #from your code
if result == [] :
for widget in root.ids.screen1.children:
root.ids.screen1.remove_widget(widget)

How to use random with button in Kivy

I just want to have 2 buttons in my KIVY APP.
One with text "Hello" and other having a random number from 0-9.
My code
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from random import random
Builder.load_string("""
<Highest>:
r1c1: "hello"
r1c2: random.randrange(10)
GridLayout:
cols: 1
Button:
text: root.r1c1
Button:
text: root.r1c2
""")
class Highest(Screen):
pass
# Create the screen manager
sm = ScreenManager()
sm.add_widget(Highest(name='Highest'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
My code works if I just have one button with text - Hello. Random seems not working.
Perhaps it's because randrange isn't returning a string, but an int. You could try:
r1c2: str(random.randrange(10))
OR
Try adding it as a function to your root widget:
class Highest(Screen):
def get_rand(self):
return str(random.randrange(10))
And your kv would look like this:
r1c2: root.get_rand()

Implement android back button function in Kivy

Firstly, i have gone thru many examples, but could not figure out this, so asking here.
My app is to be run on android. Screen 1 have a button which will go to screen 2 on click.
All i need is code to move back to screen 1 on pressing back button on screen 2
My code:
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from random import random
from random import choice
from kivy.properties import StringProperty
import time
from kivy.clock import Clock
from functools import partial
from kivy.utils import platform
from kivy.core.window import Window
Builder.load_string("""
<MenuScreen>:
Button:
text: "move to next screen 2"
on_press: root.manager.current = 'game_mode'
<GameMode>:
Label:
text: "screen 2"
""")
class MenuScreen(Screen):
pass
class GameMode(Screen):
pass
sm = ScreenManager()
menu_screen = MenuScreen(name='menu')
sm.add_widget(menu_screen)
sm.add_widget(GameMode(name='game_mode'))
class TestApp(App):
def build(self):
self.bind(on_start=self.post_build_init)
return sm
def post_build_init(self,ev):
if platform == 'android':
import android
android.map_key(android.KEYCODE_BACK, 1001)
win = Window
win.bind(on_keyboard=self.key_handler)
def key_handler(self, window, keycode1, keycode2, text, modifiers):
if keycode1 == 27 or keycode1 == 1001:
sm.go_back()
return True
return False
if __name__ == '__main__':
TestApp().run()
Please help. I want solution based on screen manager. I would really appreciate if you can improve my code to provide solution.
Finally, figured it out
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from random import random
from random import choice
from kivy.properties import StringProperty
import time
from kivy.clock import Clock
from functools import partial
from kivy.core.window import Window
Builder.load_string("""
<MenuScreen>:
Button:
text: "move to next screen 2"
on_press: root.manager.current = 'game_mode'
<GameMode>:
Label:
text: "screen 2"
""")
class MenuScreen(Screen):
pass
class GameMode(Screen):
pass
sm = ScreenManager()
menu_screen = MenuScreen(name='menu')
sm.add_widget(menu_screen)
sm.add_widget(GameMode(name='game_mode'))
class TestApp(App):
def build(self):
self.bind(on_start=self.post_build_init)
return sm
def post_build_init(self,ev):
from kivy.base import EventLoop
EventLoop.window.bind(on_keyboard=self.hook_keyboard)
def hook_keyboard(self, window, key, *largs):
if key == 27:
print sm.current
if(sm.current=='menu'):
App.get_running_app().stop()
sm.current='menu'
return True
if __name__ == '__main__':
TestApp().run()
ScreenManager has a previous() method that should solve your problem:
Builder.load_string("""
<MenuScreen>:
Button:
text: "move to next screen 2"
on_press: root.manager.current = 'game_mode'
<GameMode>:
BoxLayout:
orientation: "vertical"
Button:
text: "go back"
on_press: root.manager.current = root.manager.previous()
Label:
text: "screen 2"
""")

Change button text value for on_press event in Kivy

My application has a single button with text value as '2'. I want to change the text value to 100 on on_press event
My attempt:
#!/usr/bin/kivy
import kivy
kivy.require('1.7.2')
from random import random
from random import choice
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
r1c2=random()
Builder.load_string("""
<Highest>:
r1c2: str(2)
GridLayout:
cols: 1
Button:
text: root.r1c2
on_press: root.new()
""")
class Highest(Screen):
def new(self):
r1c2=str(100)
# Create the screen manager
sm = ScreenManager()
sm.add_widget(Highest(name='Highest'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Error: Currently, nothing happens when the button is pressed. Please help
You should be using kivy properties available. See kivy.properties for more information.
Add this import for access to string property:
from kivy.properties import StringProperty
And your Highest class should be:
class Highest(Screen):
r1c2 = StringProperty(str(2))
def new(self):
self.r1c2 = str(100)
At initialization r1c2 value is equal to '2'. When the function new() is called value of r1c2 will become '100'. Button text is bind to the string property r1c2 so it will automatically change.
You don't need r1c2=str(2) in your builder string.
Builder.load_string("""
<Highest>:
GridLayout:
cols: 1
Button:
text: root.r1c2
on_press: root.new()
""")

How to create simple Kivy app (form with field name)

How to create simple Kivy app?
If user type text into field "Name" using keyboard like on android
phone, this name is display
I need this to learn
Here's as simple an example as i can figure out.
Here's the KVLANG code.
<LblTxt#BoxLayout>:
orientation: 'horizontal'
lblTxtIn: 'default'
theTxt: iAmTxt
Label:
text: root.lblTxtIn
TextInput:
id: iAmTxt
text: 'txt'
<MyLayout#BoxLayout>:
orientation: 'vertical'
LblTxt:
id: lt0
lblTxtIn: 'LblTxtInput0'
LblTxt:
id: lt1
lblTxtIn: 'LblTxtInput1'
LblTxt:
id: lt2
lblTxtIn: 'LblTxtInput2'
Button:
text: 'print LblTxtInput [0, 1, 2]'
on_release: print lt0.theTxt.text, lt1.theTxt.text, lt2.theTxt.text
MyLayout
Here's the Python code.
import kivy
kivy.require('1.8.0') # replace with your current kivy version !
from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
from kivy.core.window import Window
Window.size = (400,130)
from kivy.uix.boxlayout import BoxLayout
class LblTxt(BoxLayout):
from kivy.properties import ObjectProperty
theTxt = ObjectProperty(None)
class MyApp(App):
def build(self):
self.root = Builder.load_file('simpleForm.kv')
return self.root
if __name__ == '__main__':
MyApp().run()
Here's a run screenshot. It will print a b c to the command line when the 'print LblTxtInput [0, 1, 2]' button is released.
I hope this helps you out.

Resources