2

basado en el ejemplo de esta pregunta quiero hacer un programa que me muestre un texto guardado en una variable, "g". Ahí va el código:

# config
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'system') #¿Para qué sirve esta línea?

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.clock import Clock
from itertools import cycle

import random

Builder.load_file('design.kv')

class MyWidget(BoxLayout):
    random_number = StringProperty()
    string = StringProperty()

    def __init__(self):
        super(MyWidget, self).__init__()
        self.random_number = str(random.randint(1, 100))+'\n'
        self.listText = cycle(('Hola', 'soy', 'una', 'etiqueta'))
        Clock.schedule_interval(self.change_label_text, 0.6) #¿Para qué sirve esta línea?

    def numero_aleatorio(self):
        self.random_number += str(random.randint(1, 100))+'\n'

    def change_label_text(self, *args):
        self.string = next(self.listText)

class myApp(App):
    def build(self):
        return MyWidget()
    def on_pause(self): #¿Para qué sirve esta función?
        return True
    def on_resume(self): #¿Para que sirve esta función?
        pass
g = "Esto es un mensaje guardado en una variable" #Aquí está la variable que guarda el texto que quiero mostrar

if __name__ in ('__main__', '__android__'): #¿Para qué sirve esta línea?
    myApp().run()

Y el archivo design.kv:

<MyWidget>:
    BoxLayout:
        TextInput:
            id: textInp2
            text: g
            multiline: True
            readonly: True
            background_color: 0.92,0.89,0.75,1
            on_focus: self.focus = False 

Al correrlo me da un error: NameError: name 'g' is not defined

¿Cómo puedo hacer para que me muestre la variable g?

Mr. Baldan
  • 1,375
  • 5
  • 22
  • 45

2 Answers2

3

no estoy familiarizado con kivy, pero creo que el problema es que estas definiendo g fuera de tu clase, creo que deberia ser algo así:

class MyWidget(BoxLayout):
    g='el texto que requieras'
    random_number = StringProperty()
    string = StringProperty()


<MyWidget>:
    BoxLayout:
        TextInput:
            id: textInp2
            text: root.g
            multiline: True
            readonly: True
            background_color: 0.92,0.89,0.75,1
            on_focus: self.focus = False 
Jorge Arturo Juarez
  • 2,813
  • 1
  • 11
  • 24
3

Debes crear la variable dentro de tu clase Mywidget. La variable debería ser un StringProperty, si conoce Tkinter es similar a StringVar.

Una vez definida aquí puedes modificarla dentro de la clase cuando quieras. En desing.kv debes hacer referencia al padre de la variable para que sepa localizarla. En este caso el padre es root, por lo que debe ser text: root.g

El código debe ser algo así:

main.py:

# config
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'system')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.lang import Builder

Builder.load_file('design.kv')

class MyWidget(BoxLayout):
    g = StringProperty()
    def __init__(self):
        super(MyWidget, self).__init__()
        self.g = "Esto es un mensaje guardado en una variable"


class myApp(App):
    def build(self):
        return MyWidget()
    def on_pause(self):
        return True
    def on_resume(self): #¿Para que sirve esta función?
        pass

if __name__ in ('__main__', '__android__'):
    myApp().run()

desing.kv:

<MyWidget>:
    TextInput:
        id: textInp2
        text: root.g
        multiline: True
        readonly: True
        background_color: 0.92,0.89,0.75,1
        on_focus: self.focus = False

Veo que tienes varios comentarios preguntando que son esas lines, supongo que son preguntas indirectas encubiertas...XD. Vamos a ver si puedo aclarar algo:

  • Config.set('kivy', 'keyboard_mode', 'system'): el objeto config sirve para configurar,valga la redundancia, aspectos internos del propio kivy. Por ejemplo sirve para indicar los máximos fotogramas por segundo que debe tener la app, icono de ventana, si debe abrirse en pantalla completa, etc.

    En este caso lo que se especifica es el tipo de teclado que debe usar la aplicación, se define como 'system' lo que significa que se usará el teclado que nuestro dispositivo tenga por defecto, el del sistema. Si ejecutamos la app en el ordenador será el teclado físico, si es en Android el teclado que use el teléfono por defecto. Existen otras posibilidades como son los teclados virtuales que proporcina kivy, incluso podemos crear un teclado virtual a medida nosotros mismos definido en un json.

    Puedes ver las opciones completas en la documentación de kivy.config.

  • Clock.schedule_interval(self.change_label_text, 0.6): como su propio nombre indica es un sheduler, permite ejecutar una tarea dada cada x tiempo. En este caso lo que hace es ejcutar el método self.change_label_text cada 0.6 segundos. Si recuerdas el ejemplo de la pregunta anterior había un label que cambiaba el texto automáticamente de forma cíclica, esto es lo que lo permite. La gracia es que a diferencia de métodos como time.sleep() no bloquea la interfaz, es decir el programa sigue funcionando y cada x tiempo hace algo.

  • def on_pause(self) y def on_resume(self): estos métodos estan pensados para Android. En Android puedes abrir la app y minimizarla/pausarla. El método on_pause evita que al minimizar la app esta se cierre de forma que podemos volver a reanudarla posteriormente. El método on_resume especifica el comportamiento al relanzarla.

  • if __name__ in ('__main__', '__android__'):: esto no es una característica de Kivy, puedes ver una explicación extensa en una respuesta que dí en su día a esta pregunta:

    ¿Qué es if __name__ == “__main__”:?

    La única diferencia es que pensando que el programa corra en dispositivos Android se añade '__android__'. Podemos usar este módulo importándolo desde otro, el usar esta construcción evita que al importar se lanze la GUI (cosa que no interesa). En cambio, si se ejecuta como módulo principal si se lanza la GUI al ejecutar el método run().

Puedes cambiar el texto de otras formas, por ejemplo dentro de tu clase MyWidget podrías modificar el texto accediendo al Text edit mediante su id dada en Kivy Languaje. En este caso no usas la StringProperty sino qque modificas el texto del Text edit directamente. Para acceder a cualquier widget mediante su id basta con acceder al atributo ids. Este atributo es un diccionario por lo que se le pasa la id en forma de cadena como clave (self.ids['id_del_widget']):

main.py:

# config
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'system')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.lang import Builder

Builder.load_file('design.kv')

class MyWidget(BoxLayout):
    g = StringProperty()
    def __init__(self):
        super(MyWidget, self).__init__()


        g = "Esto es un mensaje guardado en una variable"
        self.ids['textInp2'].text = g


class myApp(App):
    def build(self):
        return MyWidget()
    def on_pause(self): #¿Para qué sirve esta función?
        return True
    def on_resume(self): #¿Para que sirve esta función?
        pass

if __name__ in ('__main__', '__android__'): #¿Para qué sirve esta línea?
    myApp().run()

desing.kv:

<MyWidget>:
    TextInput:
        id: textInp2
        multiline: True
        readonly: True
        background_color: 0.92,0.89,0.75,1
        on_focus: self.focus = False
FJSevilla
  • 55,603
  • 7
  • 35
  • 58