Python en Español

Tutorial de Kivy – Construye aplicaciones con interfaces gráficas usando Python

En los tutoriales anteriores, vimos cómo crear aplicaciones GUI utilizando Tkinter y PyQt5, en este tutorial, continuaremos creando aplicaciones con interfaces gráficas de escritorio, pero esta vez utilizando Kivy.

Kivy es una biblioteca de código abierto de Python que se utiliza para crear aplicaciones en Windows, Linux, MacOS, Android e iOS.

Aprenderás como trabajar con los Kivy buttons, los labels, las recycle views, las scroll views, el Kivy Canvas y otros widgets para familiarizarte con la biblioteca.

Puedes diseñar widgets de Kivy usando un lenguaje intermedio llamado lenguaje Kv lo cual exploraremos mas adelante.

Antes de comenzar con Kivy, necesitas conocimientos de los conceptos básicos de programación en Python. Ahora, comencemos desde la instalación.

 

Instalación

Si tiene varias versiones de Python instaladas en tu computadora, entonces tendrá que instalar Kivy en la versión que deseas usar para el desarrollo.

Suponiendo que Python está instalado, debes seguir los siguientes pasos:

  1. Los paquetes de python se pueden instalar usando pip. Como Kivy necesita compilarse cuando se instala con pip, necesitaras wheels, lo cual es una distribución precompilada de un paquete ya compilado. También puede usar git para instalar Kivy, pero en este tutorial utilizaremos wheel.

Ejecuta el siguiente comando para instalar pip y wheel:

python -m pip install --upgrade pip wheel setuptools

Tutorial de Kivy

  1. Ahora tenemos que instalar las dependencias. Ejecuta los siguientes comandos:
python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew

Luego:

python -m pip install kivy.deps.gstreamer

Instalación

  1. Después de instalar las dependencias para Kivy, instala Kivy usando el siguiente comando:
python –m pip install kivy

Kivy instalado

 

Interfaces gráficas Kivy

En esta sección, vas a aprender cómo crear y ejecutar un programa con Kivy y cómo construir una interfaz básica.

Vamos a crear un archivo con extensión .py.

Para crear una interfaz Kivy, primero debes importar el módulo de la aplicación Kivy en nuestro programa usando la siguiente sentencia:

from kivy.app import App

Ahora importa Label desde kivy.uix.label:

from kivy.uix.label import Label

Llegó el momento de escribir nuestro programa principal.

class FirstKivy(App):

    def build(self):

        return Label(text="Hello Kivy!")

En el fragmento de código anterior, una clase se hereda de la clase App. Luego, para compilar la aplicación, tenemos que devolver un widget en la función build (). En el código anterior, hemos devuelto una etiqueta con el texto “Hello Kivy”.

El último paso es llamar a esta función. Puedes crear un objeto de la clase o simplemente escribir la siguiente declaración:

FirstKivy().run()

El archivo completo de python se estructura de la siguiente forma:

from kivy.app import App

from kivy.uix.label import Label

class FirstKivy(App):

    def build(self):

        return Label(text="Hello Kivy!")

FirstKivy().run()

El resultado de este código será así:

Ejecutar primero la aplicación Kivy

¡Felicidades! Tu primera aplicación con Kivy se ejecutó con éxito.

 

Kivy Button

En esta sección, aprenderás cómo crear un botón, cambiar el color del mismo, habilitarlo / deshabilitarlo, agregar una imagen en el botón y cambiar su tamaño y su posición.

En el último programa, utilizamos el label (etiqueta). Para crear un botón, importa Button en lugar de Label de la siguiente manera:

from kivy.app import App

from kivy.uix.button import Button

class FirstKivy(App):
    
    def build(self):
        
        return Button(text="Welcome to LikeGeeks!")
    
FirstKivy().run()

La salida completa será la siguiente:

Añadir botón a la aplicación Kivy

El botón llena la ventana, no te preocupes, cambiaremos su tamaño más adelante.

Cambiar el color del botón kivy

El color predeterminado de un botón Kivy es gris. El color se puede cambiar especificando la propiedad background_color en el formato (r, g, b, a). En el código puedes observarlo a continuación:

from kivy.app import App

from kivy.uix.button import Button

class KivyButton(App):

    def build(self):

        return Button(text="Welcome to LikeGeeks!", background_color=(155,0,51,53))

KivyButton().run()

Cuando ejecutas el programa, se crea el siguiente botón:

Cambia el color del botón Kivy

Deshabilitar el botón Kivy

Para deshabilitar un botón, debes establecer la propiedad disabled en True.

mybtn.disabled = True

Considera el siguiente código para deshabilitar un botón después de presionarlo:

from kivy.uix.button import Button

from kivy.app import App

from functools import partial

class KivyButton(App):

    def disable(self, instance, *args):

        instance.disabled = True

    def update(self, instance, *args):

        instance.text = "I am Disabled!"

    def build(self):

        mybtn = Button(text="Click me to disable")

        mybtn.bind(on_press=partial(self.disable, mybtn))

        mybtn.bind(on_press=partial(self.update, mybtn))

        return mybtn

KivyButton().run()

En el código anterior, importamos una función partial de functools para poder usar la función bind().

Se crea una clase KivyButton () con 2 métodos personalizados. El primer método disabled(). Puedes nombrarlo como quieras

Luego tenemos el método update() para actualizar el texto de nuestro botón después de hacer clic en él. Además, puedes nombrar tu función como quieras.

La siguiente función es build (). Este método se ejecuta automáticamente cuando se crea un botón. Luego llamamos al método disable() usando la función partial. De manera similar, se llama al método update() para actualizar el texto del botón después de que se deshabilita.

El valor de retorno de la función disable () está vinculado a la función on_press de nuestro botón. Por lo tanto, cuando se presiona el botón, primero se desactiva y luego se actualiza el texto.

La salida es la siguiente:

Deshabilitar el botón Kivy

Cambia el tamaño y la posición de un botón

Usando la propiedad pos y size_hint del widget button, puedes cambiar fácilmente la posición y el tamaño de un botón respectivamente. Puedes cambiar el tamaño y la posición de un botón Kivy de la siguiente manera:

from kivy.app import App

from kivy.uix.button import Button

class KivyButton(App):

    def build(self):

        return Button(text="Welcome to LikeGeeks!", pos=(300,350), size_hint = (.25, .18))

KivyButton().run()

La salida será así:

Cambia el tamaño y la posición de un botón

El parámetro pos especifica la posición del botón, mientras que el parámetro size_hint especifica el tamaño del botón.

Insertar una imagen en un botó Kivy

En esta sección, aprenderás a agregar una imagen en un botón. Usaremos el lenguaje Kv por primera vez para crear nuestros widgets propios en lugar de crear una instancia de ellos desde el código.

A continuación se muestras las librerias de Kivy que vamos a importar:

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout

from kivy.lang import Builder

BoxLayout se utiliza para colocar los widgets de modo que se puedan colocar juntos de manera organizada. En Kivy, hay varios diseños que pueden usarse para organizar los widgets, por ejemplo, diseño de cuadro, diseño de ancla, diseño flotante, etc.

Cargar un string o archivo Kv

De forma predeterminada, Kivy intenta cargar el archivo Kv con el mismo nombre que su clase pero sin la palabra App y en minúscula.

Si tu clase es TestApp, entonces el programa buscara un archivo Test.kv en el mismo directorio para importar los widgets de ahi.

La otra manera es carga un archivo Kv utilizando el Kivy Builder

Kivy Builder es utilizado para cargar widgets de archivos o cadenas Kv. Por ejemplo si quieres crear un widget, puede utilizar lo de la siguiente manera:

Builder.load_string(""" """)

Dentro de las comillas triples, los widgets necesarios se agregan junto con sus propiedades. En el siguiente ejemplo, hemos agregado una clase KivyButton.

Primero, se establecen el texto y el tamaño del botón, luego la imagen se especifica en el atributo source y por ultimo las coordenadas de la imagen.

La imagen se coloca en el mismo directorio, por lo que la ruta de la imagen está bien por los momentos.

Builder.load_string("""

<KivyButton>:

    Button:

        text: "Hello Button!"

        size_hint: .12, .12

        Image:

            source: 'images.jpg'

            center_x: self.parent.center_x

            center_y: self.parent.center_y  
    
""")

Ahora, importemos esta definición y ejecutemos nuestra clase:

from kivy.app import App

from kivy.uix.boxlayout import BoxLayout

from kivy.lang import Builder

Builder.load_string("""

<KivyButton>:

    Button:

        text: "Hello Button!"

        size_hint: .12, .12

        Image:

            source: 'images.jpg'

            center_x: self.parent.center_x

            center_y: self.parent.center_y  
    
""")

class KivyButton(App, BoxLayout):
    
    def build(self):
        
        return self
    
KivyButton().run()

De manera similar, puedes cargar el string Kv desde un archivo separado usando el método load_file de la siguiente forma:

Builder.load_file("myfile.kv")

Este archivo contiene todas las definiciones de los widgets de Kivy.

 

Kivy Label (Etiqueta)

En nuestra primera aplicación de con interfaz gráfica, vamos a agregar un label a nuestro formulario, pero jugaremos con las propiedades de la etiqueta.

Un label se utiliza para agregar texto a nuestra GUI. Las cadenas de caracteres ASCII y Unicode son compatibles con un label Kivy.

 

Cambiar el tamaño de la fuente

El tamaño de la fuente de la etiqueta también se puede cambiar usando la propiedad font_size:

from kivy.app import App

from kivy.uix.button import Label

class KivyButton(App):

    def build(self):

        return Label(text="Hello Label", font_size='30')

KivyButton().run()

Cambiar el tamaño de la fuente

Añadiendo estilo al texto en el label

En esta sección, cambiaremos los estilos del texto en el label.

Por ejemplo, negrita, cursiva, cambiar de color, subrayar y mucho más utilizando el marcado. Considera la siguiente sentencia:

Label(text='[u][color=ff0066][b]Better days[/b][/color] are coming; They are called [i][color=ff9933]Saturday[/i] and [i]Sunday[/color][/i][/u]', markup = True)

Donde

[color][/color]

se utiliza para colorear la fuente.

from kivy.app import App

from kivy.uix.button import Label

class KivyLabel(App):

    def build(self):

        return Label(text='[u][color=ff0066][b]Welcome[/b][/color] To [i][color=ff9933]Like[/i]Geeks[/color][/u]', markup = True)

KivyLabel().run()

Este es el resultado:

Añadiendo estilo al texto en el label

 

Kivy RecycleView

Haz la suposición de que tienes una gran cantidad de widgets para mostrar en pantalla los cuales pueden afectar el rendimiento.

El objetivo de RecycleView es organizar los grupos de vistas en la pantalla.

RecycleView es eficiente en memoria ya que carga los contenidos en memoria de acuerdo con el tamaño de la pantalla, a diferencia de ListView, donde todos los elementos se cargan en memoria.

Una de las características clave de RecycleView es que soporta animaciones. RecycleView puede crear una lista desplazable interactiva y eficiente.

Antes de comenzar a codificar, hay dos conceptos principales en los que tienes que centrarte:

  1. View Holder el cual sostiene una vista y ayuda al reciclaje.
  2. El adapter que se utiliza para adaptar los datos a mostrar en la lista..

Para utilizar RecycleView, debemos importar RecycleView del módulo recycleview de la siguiente manera:

from kivy.uix.recycleview import RecycleView

En el siguiente ejemplo, crearemos una lista vertical de botones. Por lo tanto, los elementos de vista que queremos colocar son los botones:

El primer paso es definir el diseño y la clase de vista de nuestro reciclaje:

Builder.load_string('''

<ExampleRV>:

    viewclass: 'Button'

    RecycleBoxLayout:

        size_hint_y: None

        height: self.minimum_height

        orientation: 'vertical'

''')

Ahora tenemos que definir nuestra clase de recicleview:

class ExampleRV(RecycleView):

    def __init__(self, **kwargs):

        super(ExampleRV, self).__init__(**kwargs)

        self.data = [{'text': str(x)} for x in range(20)]

Este

__init__

es el constructor de la clase con ** kwargs, lo que significa que cualquier número arbitrario de argumentos o argumentos de palabras claves son aceptables. Ahora llamamos a la clase anterior:

class RecycleApp(App):

    def build(self):

        return ExampleRV()

RecycleApp().run()

Entonces el código completo será el siguiente:

from kivy.app import App

from kivy.uix.recycleview import RecycleView

from kivy.lang import Builder

Builder.load_string('''

<ExampleRV>:

    viewclass: 'Button'
    
    RecycleBoxLayout:
    
        size_hint_y: None
        
        height: self.minimum_height
        
        orientation: 'vertical'
        
''')

class ExampleRV(RecycleView):

    def __init__(self, **kwargs):

        super(ExampleRV, self).__init__(**kwargs)

        self.data = [{'text': str(x)} for x in range(20)]

class RecycleApp(App):

    def build(self):

        return ExampleRV()

RecycleApp().run()

Entonces el código completo será el siguiente:

Ejemplo de RecyclerView

 

Kivy ScrollView

El ScrollView en Kivy proporciona una vista desplazable. Usando scrollview, podemos desplazarnos a través del eje x así como el eje y en la pantalla.

Primero, importaremos una nueva función llamada runTouchApp(). Esta función hará que nuestro scrollview touch esté habilitado.

from kivy.base import runTouchApp

Definiremos el scrollView de la siguiente manera:

from kivy.base import runTouchApp

from kivy.lang import Builder

root = Builder.load_string(r'''

ScrollView:

    Label:
    
        text: 'Scrollview Example' * 100
        
        font_size: 30
        
        size_hint_x: 1.0
        
        size_hint_y: None
        
        text_size: self.width, None
        
        height: self.texture_size[1]
        
''')

runTouchApp(root)

La salida será de la siguiente manera:

Kivy ScrollView

 

Kivy Clear text input

En esta sección, crearemos un campo de texto y un botón para borrar el contenido del campo de texto.

Para el campo de texto, necesitas importar el módulo de entrada de texto:

from kivy.uix.textinput import TextInput

Vamos a crear un BoxLayout para agregar nuestros widgets dentro de nuestra clase.

self.box = BoxLayout(orientation='horizontal', spacing=20, pos=(0,550))

Ahora vamos a crear un input field:

self.txt = TextInput(hint_text="Write here",size_hint=(.5,.1))

Después del input field, tenemos que crear un botón que borre el texto.

Para esto, crearemos un método clearText que asigna cadena vacía de texto al campo y lo llamaremos cuando se presione el botón, es decir, utilizando la propiedad on_press del botón.

Por lo tanto, cuando pulsamos el botón se borrará el texto.

self.btn = Button(text='Clear All', on_press=self.clearText,size_hint=(.1,.1))

Ahora tenemos que agregar nuestros widgets (el input filed y el button) al boxlayout:

self.box.add_widget(self.txt)

self.box.add_widget(self.btn)

El método ClearText se muestra a continuación:

def clearText(self, instance):

        self.txt.text = ''

El código completo es el siguiente:

from kivy.app import App

from kivy.uix.button import  Button

from kivy.uix.textinput import TextInput

from kivy.uix.boxlayout import BoxLayout

class ClearApp(App):

    def build(self):

        self.box = BoxLayout(orientation='horizontal', spacing=20)

        self.txt = TextInput(hint_text='Write here', size_hint=(.5,.1))

        self.btn = Button(text='Clear All', on_press=self.clearText, size_hint=(.1,.1))

        self.box.add_widget(self.txt)

        self.box.add_widget(self.btn)

        return self.box

    def clearText(self, instance):

        self.txt.text = ''

ClearApp().run()

El resultado de la salida es este:

Clear Kivy text input

 

Kivy Clock

El objeto Kivy Clock se utiliza para programar la llamada de una función después de intervalos específicos.

En esta sección, crearemos un botón. El texto del botón cambiará después de cada 2 segundos.

Debes importar los siguientes módulos primero:

from kivy.app import App

from kivy.clock import Clock

from kivy.uix.button import Button

Ahora, crea una clase e inicialice una variable de contador de la siguiente manera:

class ClockExample(App):

    i = 0

Luego, crea un botón y usando clock.schedule_interval llamaremos una función cada 2 segundos. Cada vez que se llama a la función, el valor de la variable del contador se incrementará en 1, lo cual se imprimirá en el botón.

    def build(self):

       self.mybtn = Button(text='Number of Calls')

       Clock.schedule_interval(self.Clock_Callback, 2)

       return self.mybtn

    def Clock_Callback(self, dt):

        self.i = self.i+1

        self.mybtn.text = "Call = %d"%self.i

El argumento dt se usa para transcurrir el tiempo entre la programación y la llamada de la función. Si no se pasa ningún argumento, se generará el cual dice que la función toma 1 argumento posicional pero se dieron 2.

El código completo se ve así:

from kivy.app import App

from kivy.uix.button import  Button

from kivy.clock import Clock

class ClockExample(App):

    i=0

    def build(self):

        self.mybtn = Button(text='Number of Calls')

        Clock.schedule_interval(self.clock_callback, 2)

        return self.mybtn

    def clock_callback(self, dt):

        self.i+= 1

        self.mybtn.text = "Call = %d" % self.i

ClockExample().run()

Cada 2 segundos, el texto del botón cambiará como se espera.

Kivy clock

 

Kivy Canvas

La representación gráfica de un widget está representada con Kivy Canvas. Puedes dibujar lo que quieras dentro de un lienzo (canvas).

En esta sección, aprenderá a crear un canvas y cómo dibujar un rectángulo dentro de este.

Vamos a crear un canvas dentro de un boxlayout y luego agregar un rectángulo dentro del canvas.

Importa los siguientes módulos:

import kivy

from kivy.app import App

from kivy.lang import Builder

from kivy.uix.boxlayout import BoxLayout

Observa el siguiente código para crear un canvas:

kvWidget = """

MyWidget:

    orientation: 'vertical'

    canvas:

        Color:

            rgb: (255, 0, 0)

        Rectangle:

            size: self.size

            pos: self.pos

"""

class MyWidget(BoxLayout):

    def __init__(self, **kwargs):

        super().__init__(**kwargs)

En este código, tenemos una clase BoxLayout llamada MyWidget. Ahora la cadena kv de widgets define un canvas con una propiedad de color y un rectángulo con el mismo tamaño y posición del BoxLayout.

El código se muestra a continuación:

from kivy.app import App

from kivy.lang import Builder

from kivy.uix.boxlayout import BoxLayout

kvWidget = """

MyWidget:

    orientation: 'vertical'
    
    canvas:
    
        Color:
        
            rgb: (255, 128, 0)
            
        Rectangle:
        
            size: self.size
            
            pos: self.pos
"""

class MyWidget(BoxLayout):

    def __init__(self, **kwargs):

        super().__init__(**kwargs)

class CanvasApp(App):

    def build(self):

        return Builder.load_string(kvWidget)

CanvasApp().run()

La salida será así:

Kivy canvas color

 

Canvas Image

Para agregar una imagen al canvas, crearemos un rectángulo igual al tamaño del canvas y luego agregaremos una imagen dentro del rectángulo.

La cadena kvWidget se verá como la siguiente:

from kivy.app import App

from kivy.lang import Builder

from kivy.uix.boxlayout import BoxLayout

kvWidget = """

MyWidget:

    orientation: 'vertical'
    
    canvas:
    
        Rectangle:
        
            size: self.size
            
            pos: self.pos
            
            source: 'images.jpg'
            
"""

class MyWidget(BoxLayout):

    def __init__(self, **kwargs):
        
        super().__init__(**kwargs)

class CanvasApp(App):

    def build(self):
        
        return Builder.load_string(kvWidget)

CanvasApp().run()

 

Kivy vs PyQt

Como Kivy, PyQt también se usa para crear aplicaciones GUI, pero PyQt es más conocido por aplicaciones de escritorio.

Aunque hablamos de Kivy aquí para crear aplicaciones de escritorio, Kivy se usa comúnmente para aplicaciones móviles debido a las capacidades de los widgets de Kivy en multitouch.

La biblioteca PyQt está disponible en otros lenguajes de programación como C ++, mientras que Kivy solo está disponible en Python.

Kivy usa interfaces OpenGL para dibujar widgets directamente en la pantalla, de modo que también puedes crear juegos con buenos gráficos.

 

Espero que encuentres el marco GUI de Python adecuado para construir lo que necesitas.

Por fin, discutimos muchos ejemplos para Kivy y previamente Tkinter, PyQt5. ¿Cuál prefieres para construir tus interfaces gráficas?

Mokhtar Ebrahim
Fundadora de LikeGeeks. Estoy trabajando como administrador de sistemas Linux desde 2010. Soy responsable de mantener, proteger y solucionar problemas de servidores Linux para múltiples clientes de todo el mundo. Me encanta escribir guiones de shell y Python para automatizar mi trabajo.

8 thoughts on “Tutorial de Kivy – Construye aplicaciones con interfaces gráficas usando Python

  1. Muy explicativo… pero COMO lo puedo hacer si instalo kivy en un entorno virtual…es decir, ya tengo mi entorno… y qué sigue? … lo hago tal como en django… en una carpeta de proyecto ..
    Otra pregunta … que editor usas? … recomiendas alguno para kivy..?
    gracias

  2. al intentar instalar kivy me da un error en la línea python –m pip install kivy.

    El error dice lo siguiente:
    python –m pip install kivy
    python: can’t open file ”: [Errno 2] No such file or directory

    Alguna manera de poder solucionarlo?
    por cierto la versión de python que estoy utilizando es 3.7.5

  3. Me vi recién el tutorial de tkinter; PyQt y Kivi.
    Son geniales como introducción a las GUI en Python.
    Tkinter es el que me parece más sencillo, pero también te limita.
    Entre Kivi y PyQt, kivi me a parecido más claro y de un uso más sencillo.

    1. Hola
      Cada paquete tiene su propio uso.
      Ej: Kivy se usa para dispositivos móviles, mientras que Tkinter y PyQt no.
      PyQt es más simple para principiantes, etc.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *