How to change value in widget according to another widget

40 views
Skip to first unread message

husam alkdary

unread,
Apr 5, 2020, 2:37:59 AM4/5/20
to Kivy users support
I want a general method to How I can  call a class in other class
for example I have 

class MyLabel(Label):
 
def labeltext(self):
 
pass
class MyProgressBar:(BarProgressBar):
 
pass


and in kv file 

BoxLayout:
 
MyLabel:
  id
: MyLabel_id
 
MyProgressBar:
  id
: MyProgressBar_id

change the label text depends on the value of the ProgressBar so i want to use labeltext function in the MyLabel class to change the label text according to the value of the ProgressBar
I want the label text to be variable so i need to call the ProgressBar value in labeltext function

I tried to use
self.ids.MyProgressBar_id.value


in my labeltext function but i get error


Elliot Garbus

unread,
Apr 5, 2020, 11:52:56 AM4/5/20
to kivy-...@googlegroups.com

First a few reference materials:

https://kivy.org/doc/stable/api-kivy.lang.html?highlight=lang#value-expressions-on-property-expressions-ids-and-reserved-keywords

https://blog.kivy.org/2019/06/widget-interactions-between-python-and-kv/

 

Here are a few key points:

Each ‘rule’ or root widget in kivy has it’s own ids dictionary.  A rule starts with <MyWidget>:  in the far left column.

Inside a rule in kv the name space is flat.  You can access any widgets attributes or methods using the id.

In kv  is a keyword that points to the current running app,  this requires a method call in Python (see below)

 

In Python the id for each widget is put into an ids dictionary.  The dictionary associates the id with an object.

You can get the app object using the call:

app= App.get_running_app()  # I do it like this so the access looks the same in python and kv

app.root is the root object

app.root.ids is the ids dict of the root object.

If you are using multiple screens you need to use get_screen(‘screen name’) to get the screen widget.

https://kivy.org/doc/stable/api-kivy.uix.screenmanager.html?highlight=get_screen#kivy.uix.screenmanager.ScreenManager.get_screen

 

 

Print these out app, self. Ids… to see how then work.

An example:

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.progressbar import ProgressBar
from kivy.clock import Clock

kv =
"""
<ScreenOne@Screen>:
    Button:
        id: button
        text: 'Press to start ProgressBar'
        on_release: app.root.ids.sm.current = 'screen_two'

<ScreenTwo@Screen>:
    Button:
        id:button
        text: 'Press to stop ProgressBar'
        on_release: app.root.ids.sm.current = 'screen_one'

BoxLayout:
    orientation: 'vertical'
    ScreenManager:
        size_hint_y: .5
        id: sm
        ScreenOne:
            name: 'screen_one'
        ScreenTwo:
            on_enter:pb.start()
            on_leave:pb.stop()
            name: 'screen_two'
    AutoProgressBar:
        id: pb
        size_hint_y: .15
        id: pb
        max: 10
    Label:  
        id: pb_label
        size_hint_y: .15
        text: str(pb.value)   # using an id within the same kv 'rule' or 'root'.
        font_size: 20
    Button:
        id: ids_button
        size_hint_y: .15
        text: 'print ids'
        on_release:
            print('From KV:')
            print(f'app: {app}')
            print(f'app.root: {app.root}')
            print(f'app.root.ids: {app.root.ids}')
            print(f'app.root.ids.sm.get_screen("screen_one"): {app.root.ids.sm.get_screen("screen_one")}')
            print(f'app.root.ids.sm.get_screen("screen_one").ids: {app.root.ids.sm.get_screen("screen_one").ids}')
            pb.print_ids_from_python()  # using id to access a method
            
            
"""


class AutoProgressBar(ProgressBar):
   
def __init__(self, **kwargs):
       
self.schedule = None
       
super().__init__(**kwargs)

   
def _go(self, *args):
       
self.value = self.value + 1 if self.value < self.max else 0

   
def start(self):
       
self.schedule = Clock.schedule_interval(self._go, 1)

   
def stop(self):
       
self.schedule.cancel()

   
def print_ids_from_python(self):
        app = App.get_running_app()
       
print('\nFrom Python')
       
print(f'app: {app}')
       
print(f'app.root: {app.root}')
       
print(f'app.root.ids: {app.root.ids}')
       
print(f'app.root.ids.sm.get_screen("screen_one"): {app.root.ids.sm.get_screen("screen_one")}')
       
print(f'app.root.ids.sm.get_screen("screen_one").ids: {app.root.ids.sm.get_screen("screen_one").ids}')
       
# change the text on a screen button:
       
button_text = app.root.ids.sm.get_screen("screen_one").ids.button.text
        app.root.ids.sm.get_screen(
"screen_one").ids.button.text = button_text.upper()


class RunPbApp(App):
   
def build(self):
       
return Builder.load_string(kv)


RunPbApp().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/6409579b-de36-4b53-a034-d60f7a57bebb%40googlegroups.com.

 

Elliot Garbus

unread,
Apr 5, 2020, 12:11:13 PM4/5/20
to kivy-...@googlegroups.com

In kv  is a keyword that points to the current running app,  this requires a method call in Python (see below)

Should say:

In kv app  is a keyword that points to the current running app,  this requires a method call in Python (see below)

husam alkdary

unread,
Apr 5, 2020, 5:07:38 PM4/5/20
to Kivy users support
I'm sure that all the information that i get from your replies are very useful and i understand many things from it but
I can't find the solution of my idea yet
because  I  mean how to refer to a class in other class not one of them is a root

class mainwindow(BoxLayout):
 
pass
class MyLabel(Label):
 
def labeltext(self):
 
self.text = self.app.root.ids.ProgressBar_id.value # here i want to get the MyProgressBar value and what i tried is not work
class MyProgressBar(BarProgressBar):
 
pass

kv file

BoxLayout:
 
MyLabel:
  id
: MyLabel_id
 
MyProgressBar:
  id
: MyProgressBar_id


my idea is get some code to refer to any class in other class
I want to refer to MyProgressBar in MyLabel class in labeltext function
and this a simple example because I want the text on the label to be " the value is less then 100" when the value is less then 100 and "the value is not less then 1000" if is not less then 100

I hope my idea is clear new
after all this 
I'm really appreciate your help

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

Elliot Garbus

unread,
Apr 5, 2020, 5:14:31 PM4/5/20
to kivy-...@googlegroups.com

class MyLabel(Label):
 
def labeltext(self):

  app = App.get_running_app()
 
self.text = str(app.root.ids.MyProgressBar_id.value)

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/dd49e60f-4615-46fb-be73-26c33689ee83%40googlegroups.com.

 

Message has been deleted

Elliot Garbus

unread,
Apr 6, 2020, 7:38:49 PM4/6/20
to kivy-...@googlegroups.com

I don’t understand your question.  Please post a small runnable example and show an image of what you have vs what you want.

 

 

 

From: husam alkdary
Sent: Monday, April 6, 2020 3:11 PM
To: Kivy users support
Subject: Re: [kivy-users] How to change value in widget according to another widget

 

i want to change the text size in 

MyLabel 

class with this code

 

text_size: self.size

 because this line make my text aligned to the left side of the screen that's what I get when I tried it in separate project in a kv file but when I tried this my project that contains multi screens 

simply the text disappears when I put the text_size code in my kv file 
so I want to make the text on my label to be  aligned to the left side
also the text on labe is two line but the first one is disappears and I move the above code line the text is appears again but in default position in the center of the label

--
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.

ZenCODE

unread,
Apr 7, 2020, 2:47:13 PM4/7/20
to Kivy users support
Try adding

   halign: "center"
Reply all
Reply to author
Forward
0 new messages