Python - Kivy - .parent y actualizar variable en otro archivo

 
Vista:
Imágen de perfil de Jorge Alberto
Val: 137
Ha disminuido 1 puesto en Python (en relación al último mes)
Gráfica de Python

Kivy - .parent y actualizar variable en otro archivo

Publicado por Jorge Alberto (48 intervenciones) el 03/08/2021 19:43:00
Hola. ¿Cómo andan? Sigo practicando con kivy y ahora me encontré con dos problemas. Uno en realidad cumple la función, pero sé que hay una manera más sencilla de escribir el código. El otro no funciona.
Estoy creando un juego sencillo para practicar con la aplicación y el uso de varios archivos. La idea del juego es que, dada una frase, las vocales son reemplazadas por un "_" y el usuario tiene que adivinar qué vocales van en su lugar (Por ejemplo: la frase "NO HAY VOCALES" se reemplaza por "N_ H_Y V_C_L_S"). Los archivos que escribí son:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from kivy.app  import App
from kivy.uix.gridlayout import GridLayout
 
class FugaDeVocales(GridLayout):
    vowel_chosen = '_'          # Vocal elegida por el usuario
 
    def __init__(self, **kwargs):
        super(FugaDeVocales, self).__init__(**kwargs)
 
    def chose_vowel(self, instance):
        '''Devuelve la vocal elegida'''
 
        self.vowel_chosen = instance.text
        return self.vowel_chosen
 
class MainFugaApp(App):
    def build(self):
        return FugaDeVocales()
 
if __name__ == '__main__':
    MainFugaApp().run()


El archivo .kv es:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#:kivy 1.9.0
#:import frase frase
 
<[email protected]>:
    size_hint: (1, 0.2)
    background_color: (1,0,0)
    on_press: self.parent.parent.parent.chose_vowel(self)
 
<FugaDeVocales>:
    cols: 1
    RelativeLayout:
        # Only to add buttons later on
        pos_hint: {'top': 1}
        size_hint: 1, 0.05
        Label:
            background_color: 0, 0, 1, 0.7
            canvas.before:
                Color:
                    rgba: self.background_color
                Rectangle:
                    pos: self.pos
                    size: self.size
 
    StackLayout:
        size_hint: 1, 0.7
        id: _frase_and_vowels
 
        Frase:
            # Acá va la frase sin vocales.
            id: _frase
            vowels: _vowels
            fuga_de_vocales: root
            size_hint: 0.9, 1
 
        StackLayout:
            # El canvas esta sólo para verificar el espacio que ocupa.
            canvas.before:
                Color:
                    rgba: 0.2, 0.6, 1, 1
                Rectangle:
                    pos: self.pos
                    size: self.size
            pos_hint: {'center_x': 0.5}
            # StackLayout con las vocales
            id: _vowels
            frase: _frase
            fuga_de_vocales: root
            size_hint: 0.1, 1
            VowelButton:
                text: 'A'
            VowelButton:
                text: 'E'
            VowelButton:
                text: 'I'
            VowelButton:
                text: 'O'
            VowelButton:
                text: 'U'
 
    Label:
        # Only to add a bottom margin
        size_hint: 1, 0.05
        background_color: 0, 1, 0, 0.5
        canvas.before:
            Color:
                rgba: self.background_color
            Rectangle:
                pos: self.pos
                size: self.size

No le den importancia a la línea 11 y 59 (RelativeLayout y Label). Por el momento están sólo para corroborar que los tamaños y posiciones este bien definidos.

Y un segundo archivo .py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from fugadevocales import FugaDeVocales
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from random import choice
from fugadevocales import FugaDeVocales
 
lista_de_frases = ['VOY A NECESITAR UNA FRASE MUY LARGA SOLAMENTE PARA COMPROBAR SI SE ADAPTA BIEN A LA VENTANA, PERO NO ES DEFINITIVA']
 
class Frase(StackLayout):
 
    def __init__(self, **kwargs):
        super(Frase, self).__init__(**kwargs)
 
        self.my_button = Button(text='A')
        self.frase = choice(lista_de_frases)
        self.size_letter = (0.1, 9/((len(self.frase))))
        self.vocales = ['A', 'E', 'I', 'O', 'U']
 
        self.new_frase()
 
    def new_frase(self):
        '''Reemplaza las vocales por "_" y añade los widgets'''
        for item in self.vocales:
            self.frase = self.frase.replace(item, '_')
 
        for letra in self.frase:
            self.add_widget(Label(text=letra, size_hint= self.size_letter))
 
    @staticmethod
    def change_variable():
        return FugaDeVocales.vowel_chosen
 
    def on_touch_down(self, touch):
        '''Debería cambiar el "_" por la vocal, pero no lo hace.'''
 
        if self.collide_point(touch.x, touch.y):
            variable = self.change_variable()
            self.text = variable
            print(variable)
        return super().on_touch_down(touch)


El primer problema esta en la línea 7 del archivo kv. Como pueden ver, para llamar a la función dentro de los botones 'VowelButton' tengo que usar muchas veces parent. Sé que hay una forma de usar id, pero cuando las uso me arrojan distintos errores. Si por ejemplo agrego una id a <FugaDeVocales> (línea 10 del kv), de esta forma:
1
2
3
4
5
6
7
8
<[email protected]>:
    size_hint: (1, 0.2)
    background_color: (1,0,0)
    on_press: self.fuga_de_vocales.chose_vowel(self)
 
<FugaDeVocales>:
    id: fuga_de_vocales
...
Me arroja el error "AttributeError: 'VowelButton' object has no attribute 'fuga_de_vocales'"

Y si uso:
1
2
3
4
5
6
7
8
9
10
11
<[email protected]>:
    size_hint: (1, 0.2)
    background_color: (1,0,0)
    on_press: fuga_de_vocales.chose_vowel(self)
 
<FugaDeVocales>:
    id: fuga_de_vocales
...
 
# Modifico la línea 47 del archivo por
            fuga_de_vocales: fuga_de_vocales

Me arroja "NameError: name 'fuga_de_vocales' is not defined".

Este sería el error 'fácil'. El segundo problema esta en el segundo archivo py. La idea del juego es que cuando hago click en uno de los '_' de la frase, modifique el texto por la vocal seleccionada, pero la variable "variable" (valga la redundancia) no se actualiza, si no que queda siempre como '_'. ¿Alguna idea de cómo solucionar el problema?

En fin... un poco largo el post, pero espero que este bien explicado.

Muchas gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder