Share variables between .py and different .kv and properties between .kv and .kv in kivy

1

Community, I have a problem when I want to share variables and properties between different .kv files or different classes in the kv program. Does anyone have an idea of how I could do it directly in kv programming? Then I show the test I'm doing

windows.py

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty, NumericProperty, StringProperty, ListProperty
from kivy.config import Config
from kivy.uix.bubble import Bubble

Config.set('graphics', 'width', '1024')
Config.set('graphics', 'height', '738')
Config.set('graphics', 'resizable', False)
Config.set('kivy', 'keyboard_mode', 'system')


class idioma(FloatLayout):

    def __init__(self):
        super(idioma, self).__init__()

class idioma_kvApp(App):
    pass

if __name__== '__main__':
    idioma_kvApp().run()

idioma.kv

#: include dos.kv


idioma:
<idioma>:

    lenguaje: lenguaje

    Label:
        text: 'uno' if lenguaje.text == 'Espanol' else 'one' if lenguaje.text == 'English' else 'um'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.9}

    Label:
        text: 'dos' if lenguaje.text == 'Espanol' else 'two' if lenguaje.text == 'English' else 'dois'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.8}

    Label:
        text: 'tres' if lenguaje.text == 'Espanol' else 'tree' if lenguaje.text == 'English' else 'tres'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.7}

    Label:
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.6}
        text: 'cuatro' if lenguaje.text == 'Espanol' else 'four' if lenguaje.text == 'English' else 'quatro'

    Label:
        text: 'cinco' if lenguaje.text == 'Espanol' else 'five' if lenguaje.text == 'English' else 'cinco'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.5}

    Label:
        text: 'seis' if lenguaje.text == 'Espanol' else 'six' if lenguaje.text == 'English' else 'seis'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.4}

    Label:
        text: 'siete' if lenguaje.text == 'Espanol' else 'seven' if lenguaje.text == 'English' else 'sete'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.3}

    dos:

    Spinner:
        id: lenguaje
        text: "Espanol"
        values: ["Espanol", "English", "portugues"]
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.5, 'y': 0.6}
        #on_state: root.seleccion(self.text)

dos.kv

<dos@FloatLayout>
    Label:
        text: 'ocho' if lenguaje.text == 'Espanol' else 'eight' if lenguaje.text == 'English' else 'oito'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.2}

    Label:
        text: 'nueve' if lenguaje.text == 'Espanol' else 'nine' if lenguaje.text == 'English' else 'nove'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.1}

Thanks for the help

    
asked by diego1012 05.02.2018 в 17:38
source

2 answers

0

First of all, keep in mind that the ids are only shared within the rule tree where it is declared . Which implies that you can not use the id within the definition of the dynamic class, something else is in the instance of it.

The problem is not really that the code is divided into two kv files, the reason why it does not work is due to the order in which the code is evaluated.

If you do something like:

<RootWidget>:
    lenguaje: lenguaje

    Label:
        id: lenguaje
        text: "Espanol"

    Dos:


<Dos@FloatLayout>
    lenguaje: self.parent.lenguaje
    Label:
        text: 'ocho' if root.lenguaje.text == 'Espanol' else 'eight'

You will get an error of the type:

> AttributeError: 'NoneType' object has no attribute 'text'

This is because when Dos is instantiated in the MainWidget rule, the code is evaluated before the ObjectProperty lenguaje is linked to the parent's Label widget. So the property lenguaje of Dos is None at that moment so it does not have the attribute text defined.

In your case, the simplest option is that instead of sharing the complete widget simply share a StringProperty (variable text Spinner). Unlike with the whole object, you can give a default value to the property within the dynamic class.

  

Note: I recommend that when you name a class, always begin with a capital letter as the conventions indicate. This will avoid problems and confusion when differentiating them from the properties (they always start with a lowercase).

Your code could look like this:

windows.py :

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.config import Config


Config.set('graphics', 'width', '1024')
Config.set('graphics', 'height', '738')
Config.set('graphics', 'resizable', False)
Config.set('kivy', 'keyboard_mode', 'system')


class Idioma(FloatLayout):
    pass


class IdiomaApp(App):
    pass


if __name__== '__main__':
    IdiomaApp().run()

idioma.kv:

#: include dos.kv

Idioma:

<Idioma>:

    lenguaje: lenguaje.text

    Label:
        text: 'uno' if root.lenguaje == 'Espanol' else 'one' if root.lenguaje == 'English' else 'um'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.9}

    Label:
        text: 'dos' if root.lenguaje == 'Espanol' else 'two' if root.lenguaje == 'English' else 'dois'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.8}

    Label:
        text: 'tres' if root.lenguaje == 'Espanol' else 'tree' if root.lenguaje == 'English' else 'tres'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.7}

    Label:
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.6}
        text: 'cuatro' if root.lenguaje == 'Espanol' else 'four' if root.lenguaje == 'English' else 'quatro'

    Label:
        text: 'cinco' if root.lenguaje == 'Espanol' else 'five' if root.lenguaje == 'English' else 'cinco'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.5}

    Label:
        text: 'seis' if root.lenguaje == 'Espanol' else 'six' if root.lenguaje == 'English' else 'seis'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.4}

    Label:
        text: 'siete' if root.lenguaje == 'Espanol' else 'seven' if root.lenguaje == 'English' else 'sete'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.3}

    Dos:
        lenguaje: root.lenguaje

    Spinner:
        id: lenguaje
        text: "Espanol"
        values: ["Espanol", "English", "portugues"]
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.5, 'y': 0.6}
        #on_state: root.seleccion(self.text)

dos.kv

<Dos@FloatLayout>
    lenguaje: 'Espanol'
    Label:
        text: 'ocho' if root.lenguaje == 'Espanol' else 'eight' if root.lenguaje == 'English' else 'oito'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.2}

    Label:
        text: 'nueve' if root.lenguaje == 'Espanol' else 'nine' if root.lenguaje == 'English' else 'nove'
        size_hint: (0.1, 0.1)
        pos_hint:{'x': 0.2, 'y': 0.1}
    
answered by 05.02.2018 / 20:14
source
0

You must understand that everything you do in the .kv is used to design the add-ons and create new objects, therefore completely to base the functions of the program on the .kv is not a good practice.

You should try to create your complements to pure python and use kv only for the design, try to use the properties as NumericProperty.

I use a lot of args because I do not know how many parameters will go through the function.

class MiObjeto(Widget):
    Altura = NumericProperty()
    def __init__(self,**kwargs):
        super(MiObjeto, self).__init__(kwargs)

    def on_Altura(self, *args):
        print args



MiComplemento0 = MiObjeto()
MiComplemento1 = MiObjeto()
def Compartir_Informacion(self,*args):
    MiComplemento0.Altura = args[1] 

MiComplemento0.bind(on_Altura = Compartir_Informacion)
    
answered by 18.02.2018 в 16:17