Here is an example creating 2 custom attributes and using them in Python and in kv.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
kv = """
<TwoLabels>:
orientation: 'vertical'
Label:
text: root.text_1
Label:
text: root.text_2
BoxLayout:
TwoLabels:
text_1: 'This is Text 1 from kv'
text_2: 'This is Text 2 from kv'
"""
class TwoLabels(BoxLayout):
text_1 = StringProperty()
text_2 = StringProperty()
class CustomAttribApp(App):
def build(self):
return Builder.load_string(kv)
def on_start(self):
w = TwoLabels(text_1='text 1 from Python', text_2='text 2 from python')
self.root.add_widget(w)
CustomAttribApp().run()
--
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/af64c08d-570a-4414-8d3d-5b4697fd8812n%40googlegroups.com.
On May 16, 2021, at 11:02 PM, Nobody999 <Andrea...@bleiguba.de> wrote:
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/6ade9090-b695-4cd6-9beb-2a008ea9ee15n%40googlegroups.com.
The code below is a fix for your current approach. The __init__() method takes a **kwargs argument, and super() is used to call the __init__ for the parent.
I removed your build method. Because the kv file has the same method name as app the kv file loads automagically.
If you wanted to have a single update method you could for example create a string property in app, and bind that value to the labels that you wanted to display. For example:
MyApp(App):
time_of_day = StringProperty()
current_date = StringProperty()
In the lv code:
Label:
text: app.time_of_day
Label:
text: app.current_date
… and update these properties in your update method.
Your python code updated:
======
import time
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
class ScreenMain(Screen):
pass
class ScreenTwo(Screen):
pass
class ScreenMngr(ScreenManager):
pass
class MyLabel
(Label):
text_format = StringProperty()
def __init__(self, **kwargs): # init method gives a build error
super().__init__(**kwargs)
Clock.schedule_interval(self.update, 1) # How can I add a Clock to update the time/date
def update(self, dt):
self.text = time.strftime(self.text_format, time.localtime())
class CustomAttribApp(App):
def on_start(self):
Window.clearcolor = (0.9, 0.9, 0.9, 1)
#Clock.schedule_interval(app.root.ids.timelabel.update, 1) # possibly something like this with an id on the label?
CustomAttribApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/6f6c80d3-1c98-48a2-9153-587d9ef0b361n%40googlegroups.com.
I’d recommend you use super(), it is safer and adds flexibility of you change the parent class – you do not have this dependency. It is also the convention.
I used something like: super(MyLabel, self).__init__(**kwargs)
This is how it was done in Python 2, This is simplified in Python3 to: super().__init__(**kwargs)
Keeping all of this in the MyLabel class may require a parameter that tells the update routine which of the different strings to pass to the MyLabel.text. Also it would create multiple clock schedulers. This may not be advantageous regarding performance. (Meanwhile I found this not to be an problem... find mor on that below.)
How do you think about that?
In general you can waste a lot of development time being concerned about potential performance issue before they come up. In this particular case I would not be concerned.
Is there a more elegant way to call update() while initiating the MyLabel objects although App still is not running? Probably something like on_start() ?
If you are using a kivy property to display the data, you could initialize the kivy property with the initial data you want.
time_of_day = StringProperty(‘time of day call’)
I suspect the issue you are seeing is that you are setting self.text in __init__() this is before the kv code gets processed so your kv code is overwriting the value you set here.
The dt attribute is providing information to the callback about how delayed the call back was from the time requested. I don’t understand your question about different schedule intervals. The natural way to it might be to use schedule_once() with a delay to start another schedule.
From: Nobody999
Sent: Wednesday, May 19, 2021 11:18 AM
To: Kivy users support
Subject: Re: [kivy-users] Custom Attributes in KV-File
This all works great. Thank you very much - you helped me a lot.
(Label):
text_format = StringProperty()
def __init__(self, **kwargs): # init method gives a build error
super().__init__(**kwargs)
Clock.schedule_interval(self.update, 1) # How can I add a Clock to update the time/date
def update(self, dt):
self.text = time.strftime(self.text_format, time.localtime())
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/7710f9f8-3604-4956-bd7c-c6105aec783bn%40googlegroups.com.
If you are using a kivy property to display the data, you could initialize the kivy property with the initial data you want.
time_of_day = StringProperty(‘time of day call’)
I suspect the issue you are seeing is that you are setting self.text in __init__() this is before the kv code gets processed so your kv code is overwriting the value you set here.
The dt attribute is providing information to the callback about how delayed the call back was from the time requested. I don’t understand your question about different schedule intervals. The natural way to it might be to use schedule_once() with a delay to start another schedule.