In this example I'm adding a ListProperty with a default value. If I write a new value in kv
, it's keeping the default value instead of taking the new one. (here text_list: ["Apple","Orange","Banana"] should replace text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("]) but it's not the case.
Is there a way to write value on new property from .kv file ?
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
KV = '''
BoxLayout:
ChoiceList:
text_list: ["Apple","Orange","Banana"]
'''
class ChoiceList(BoxLayout):
text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("])
def __init__(self, **kwargs):
super().__init__(**kwargs)
for text in self.text_list:
print(text)
class App(MDApp):
def build(self):
self.box = Builder.load_string(KV)
return self.box
App().run()
Thanks to Kivy Discord:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
KV = '''
BoxLayout:
ChoiceList:
text_list: ["Apple","Orange","Banana"]
'''
class ChoiceList(BoxLayout):
text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("])
def on_kv_post(self, base_widget):
super().on_kv_post(base_widget)
for text in self.text_list:
print(text)
class App(MDApp):
def build(self):
self.box = Builder.load_string(KV)
return self.box
App().run()
Related
Expected output: ['name', 'age']
Actual output: ['name']
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
KV = '''
BoxLayout:
Label:
id: name
text: "Bob"
'''
class MyApp(App):
def build(self):
box = Builder.load_string(KV)
box.add_widget(Label(text="24", id="age"))
print(list(box.ids.keys()))
return box
if __name__ == "__main__":
MyApp().run()
What can I do to get id of widget that I add with add_widget ?
The ids dictionary is created when a kv file (or string) is parsed. You cannot add an id to the ids dictionary by adding an id to a widget. However, you can manually add an id to the ids. See this related question.
Let's add this to the official kivy Github !
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
KV = '''
ObjBoxLayout:
Label:
id: name
text: "Bob"
'''
class MyApp(App):
def build(self):
box = Builder.load_string(KV)
box.add_widget(Label(text="24"), key="age")
print(list(box.ids.keys()))
return box
class ObjBoxLayout(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def add_widget(self, widget, index=0, canvas=None, key=None):
if key: self.ids[key] = widget
super(ObjBoxLayout, self).add_widget(widget, index, canvas)
if __name__ == "__main__":
MyApp().run()
Im trying to display a mapview on my naviwindow. However, i dont really know how to implement the class MapviewApp to the naviwindow. Any help would be appreciated since im new to kivy !!
.py file
from kivy.garden.mapview import MapView, MapMarker
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
KV = """
WindowManager:
NaviWindow:
<NaviWindow>:
Label:
text:"hi"
"""
class MapViewApp(App):
def build(self):
map = MapView(zoom=18, lat=1.3099, lon=103.7775, double_tap_zoom = True)
marker_1 = MapMarker(lat=1.3099, lon=103.7775)
map.add_marker(marker_1)
return map
class WindowManager(ScreenManager):
pass
class NaviWindow(Screen):
pass
class MyMainApp(App):
def build(self):
return Builder.load_string(KV)
if __name__ == "__main__":
MyMainApp().run()
This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 3 years ago.
I would like to change a Label-text in Python/Kivy after a swipe event has been detected. Changing the text works basically via the following line
self.Translation.text = "test"
but I have to change the text after detecting a swipe event from another class, in which I call a function to change the label text:
MyWidget.ThisDoesntWork("self_dummy")
In this function the exact same line as above gives me an error.
How can I change the Label-text from class "Swiping_class" calling function "MyWidget.ThisDoesntWork("self_dummy")"?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.base import EventLoop
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.uix.stacklayout import StackLayout
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.properties import ListProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from random import random
import pickle
import random
kv = '''
<ColoredLabel>:
size: (self.size_x,self.size_y)
pos: (0,0) # no effect
background_color:
canvas.before:
Color:
rgba: self.background_color
Rectangle:
pos: self.pos
size: (self.size_x,self.size_y)
'''
Builder.load_string(kv)
class ColoredLabel(Label):
background_color = ListProperty((0,0,0,1))
s_global = Window.size
size_x = s_global[0]
size_y = s_global[1]/3
class MyWidget(BoxLayout):
#init
def __init__(self, **kwargs):
super().__init__(**kwargs)
s_global = Window.size
size_x = s_global[0]
size_y = s_global[1]/3
self.ForeignLanguage = ColoredLabel(text="str_fl", size_hint=(None, None),size = (size_x,size_y), background_color=(0/255,171/255,169/255, 1))
self.Translation = ColoredLabel(text="str_tr", size_hint=(None, None),size = (size_x,size_y), background_color=(45/255,137/255,239/255, 1))
self.Example = ColoredLabel(text="str_ex", size_hint=(None, None),size = (size_x,size_y), background_color=(43/255,87/255,151/255, 1))
self.verticalBox = BoxLayout(orientation='vertical')
self.verticalBox.add_widget(self.ForeignLanguage)
self.verticalBox.add_widget(self.Translation)
self.verticalBox.add_widget(self.Example)
self.Translation.text = "test"
s=Swiping_class()
s.add_widget(self.verticalBox)
self.add_widget(s)
def ThisDoesntWork(self):
print("this is printed")
self.Translation.text = "I wanna change this via fucntion"
print("this is not printed anymore")
class Swiping_class(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.initial = 0
def on_touch_down(self, touch):
self.initial = touch.x
def on_touch_up(self, touch):
if touch.x < self.initial:
print("swiped left")
MyWidget.ThisDoesntWork("self_dummy")
else:
print("swiped right")
class BoxLayoutDemo(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
BoxLayoutDemo().run()
I think I found a solution. Within your Swiping_class, replace this line:
MyWidget.ThisDoesntWork("self_dummy")
with this line:
MyWidget.ThisDoesntWork(self.parent)
That way, instead of passing a string to your method, you pass the label object, which contains the text attribute you are trying to modify.
main:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
class testclass:
def someth(txt):
print (txt)
#how get access to textinput from begin Screen here?
class BeginScreen(Screen):
def __init__(self,**kwargs):
super().__init__()
self.layout =BoxLayout(orientation='vertical',padding=20,spacing=5,)
self.btn=Label(text=str('Hello'))
self.layout.add_widget(self.btn)
self.btn=TextInput(id='test',text='')
self.layout.add_widget(self.btn)
self.btn=Button(text='Button!', on_press=testclass.someth('?'))
# what write in ? to send textinput text to testclass.someth?
self.layout.add_widget(self.btn)
self.add_widget(self.layout)
print(self.layout.ids) #why i have no ids? textinput have id
class TestApp(App):
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '400')
def build(self):
sm = ScreenManager()
sm.add_widget(BeginScreen(name='test'))
return sm
TestApp().run()
So how can i access the textinput? I have id='test' but when i printing layouts id is saying i have noone. Why? Someone can explain me what im doing wrong and how can i make it good?
from functools import partial
To access the textinput in your external method, you could use partial functions or lambda function.
self.ids
You are getting None or empty dictionary because you don't have a kv file.
Note
When your kv file is parsed, kivy collects all the widgets tagged with id’s and places them in this self.ids dictionary type property.
Please refer to my example below for deatils.
Example
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from functools import partial
class testclass:
def someth(*args, txt):
print(txt)
class BeginScreen(Screen):
def __init__(self, **kwargs):
super(BeginScreen, self).__init__(**kwargs)
layout = BoxLayout(orientation='vertical', padding=20, spacing=5)
layout.add_widget(Label(text=str('Hello')))
# layout.add_widget(TextInput(id='test', text='')) # id in python+kivy is deprecated
txtInput = TextInput(text='text input')
layout.add_widget(txtInput)
self.ids['test'] = txtInput
layout.add_widget(Button(text='Button!', on_press=partial(testclass.someth, txt=self.ids.test.text)))
self.add_widget(layout)
print("self.ids={}".format(self.ids))
print("self.ids['test']={}".format(self.ids['test']))
print("self.ids['test'].text={}".format(self.ids['test'].text))
print("self.ids.test.text={}".format(self.ids.test.text))
for key, val in self.ids.items():
print("key={0}, val={1}".format(key, val))
class TestApp(App):
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '400')
def build(self):
sm = ScreenManager()
sm.add_widget(BeginScreen(name='test'))
return sm
TestApp().run()
Output
I'm having issues with parsing a data structure to a widget in Kivy, which would then access the structure and be able to show a value on the screen be updated continuously via a clock interval (not sure of a better to do this yet).
I have highlighted the issues in the (non-working) code below:
main.py
from kivy.app import App
from test import TestWidget
class TestApp(App):
def build(self):
testStructTable = {'randomVal1': 1, 'testVal': 2, 'randomVal2': 3}
# Issue here parsing the table like this?
return TestWidget(testStructTable)
if __name__ == '__main__':
TestApp().run()
test.py
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import NumericProperty
class TestWidget(RelativeLayout):
def __init__(self, testStructTable, **kwargs):
super(TestWidget, self).__init__(**kwargs)
Builder.load_file('test.kv')
sm = ScreenManager()
sm.add_widget(MainScreen(name='MainScreen'))
self.add_widget(sm)
# Error accessing the table
print self.testStructTable
# Have the update_test_val continuously called
#Clock.schedule_interval(MainScreen.update_test_val(testStructTable), 1 / 60)
class MainScreen(Screen):
def __init__(self, **kwargs):
testVal = NumericProperty(0)
def update_test_val(self, testStructTable):
# Get testVal from testStructTable
# Something like:
# self.testVal = testStructTable.testVal + 1 ?
self.testVal = self.testVal + 1
test.kv
<MainScreen>:
FloatLayout:
Label:
text: str(root.testVal)
font_size: 80
My aim is to have the testVal constantly updating on the screen by accessing that data structure, however I am currently unable to achieve this, can you please advise?
In your __init__ method you're passing testStructTable and then you're trying to access self.testStructTable which does not exist untill you explicitly make an assignment:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import NumericProperty
class TestWidget(RelativeLayout):
def __init__(self, testStructTable, **kwargs):
super(TestWidget, self).__init__(**kwargs)
print(testStructTable)
self.testStructTable = testStructTable
print(self.testStructTable)
class TestApp(App):
def build(self):
testStructTable = {'randomVal1': 1, 'testVal': 2, 'randomVal2': 3}
# Issue here parsing the table like this?
return TestWidget(testStructTable)
if __name__ == '__main__':
TestApp().run()