Asignar función a botón en GUI con Python y Qt Designer

Hoy vamos a asignar una función a botón en nuestra GUI. Como vimos en el anterior post, el diseño de la interfaz gráfica o Graphical User Interface (GUI de aquí en adelante) lo hicimos con Qt Designer, y la llamamos desde nuestro script en python, pero al ejecutarlo solo mostraba la ventana pero no hacia nada al presionar el botón. En esta ocasión asignaremos dicho botón a una función para ejecutar el clásico «Hola mundo».

Primero vamos a re-acomodar los elementos y asignarles un nombre, ya que desde python nos vamos a referir a estos objetos por ese nombre. Para esto abrimos nuestro archivo «interfaz.ui» que hicimos en la sesión pasada.

Vista de Qt Designer para asignarle nombres a los objetos.

El cambio que se hizo fue mover la etiqueta a la parte de abajo, y subir el campo de texto y el botón.

Para cambiar el nombre del objeto simplemente se selecciona en el área de diseño (1) y en el editor de propiedades (2) se cambia el nombre por el que desees. Es recomendable tener nombres que podamos relacionar a su función para tener un código más legible a la hora de programarlo.

Una vez renombrados, podemos verlos en el Inspector de Objetos (3).

En el caso del botón y la etiqueta, podemos cambiarle el texto que tienen por default, esto desde el editor de propiedades, buscamos la propiedad «text» y cambiamos su valor.

Hecho esto tenemos nuestra interfaz lista y con sus nombres definidos, los cuales podemos ver en el inspector de objetos:

Ahora guardamos el archivo «interfaz.ui» y vamos de nuevo a nuestro script en python, donde crearemos una función llamada «saludar» que se activará cada que se de clic en el botón «BT_Hola». Dicha función tomará el valor del texto en «LE_nombre» y cambiara el texto de la etiqueta «LB_Saludo».

Nuestro script cambiará un poco de acuerdo al post anterior, ya que para poder acceder a los objetos y sus propiedades, necesitamos definir una clase. El script de inicio quedaría así:

from PyQt5 import QtWidgets, uic
import sys

class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi('interfaz.ui', self)
        self.show()

app = QtWidgets.QApplication(sys.argv)
window = Ui()
app.exec_()

Los cambios son que ahora llamamos a PyQt5 desde una sola linea, y solicitamos la importación de la librería sys para acceder a los argumentos.

Lo siguiente que necesitamos es crear la clase base donde podamos cargar nuestro archivo «interfaz.ui» en el constructor. Necesitamos llamar al método __init__ de la clase heredada, cargar el archivo .ui en el objeto actual y entonces mostrar la ventana.

Con esto, al ejecutarlo mostrará la ventana normalmente, pero seguirá sin funcionar el botón. Debemos crear la función que tomará el nombre de nuestro campo de texto y lo mostrará en la etiqueta a forma de saludo.

def _saludar(self):
        # Esto se ejecutará cuando presionen el botón
        self.LB_Saludo.setText('Hola '+self.LE_nombre.text())

En la primera línea definimos nuestra función llamada «_saludar()», y como es un método de la misma clase le ponemos «self» como parámetro.

Cuando se ejecuta, le estamos diciendo que cambie el texto del objeto LB_Saludo, que es una etiqueta; con el valor que pasamos como parámetro, en este caso un string ‘Hola’ mas el valor que tenga en ese momento el objeto LE_nombre, en la propiedad text, que es de un campo de texto.

Ya que tenemos la funcionalidad, necesitamos decirle a nuestra clase que se la debe asignar al botón BT_Hola. y para ello lo debemos de hacer desde el constructor de la clase, para ello añadimos el código siguiente en el método __init__ .

self.bt_saludar = self.findChild(QtWidgets.QPushButton, 'BT_Hola')
self.bt_saludar.clicked.connect(self._saludar) 
self.LE_nombre.setText('Mundo')

En la primera línea buscamos el botón con que creamos y que le llamamos «BT_Hola» y lo asignamos a bt_saludar dentro de la clase.

En la segunda línea asignamos la función _saludar a la instancia de BT_Hola que acabamos de crear, con clicked.connect().

Y solo para tener un default en el campo de texto, le asignamos dinámicamente el valor «Mundo», así al iniciar y presionar el botón dirá automáticamente «Hola Mundo».

Ya todo junto,y con comentarios descriptivos, el script queda así:

# Llamamos las librerias que vamos a necesitar
from PyQt5 import QtWidgets, uic
import sys

# Creamos la clase principal, la llamamos Ui por User interface
class Ui(QtWidgets.QMainWindow):
    
    # Definimos el constructor
    def __init__(self):
        super(Ui, self).__init__()
        # Cargamos el archivo de la interfaz que diseñamos en Qt Designer
        uic.loadUi('interfaz.ui', self)
        # Buscamos el botón y lo asignamos
        self.bt_saludar = self.findChild(QtWidgets.QPushButton, 'BT_Hola')
        # A dicho boton lo conectamos con la función _saludar
        self.bt_saludar.clicked.connect(self._saludar)
        # Inicializamos el campo de texto con "Mundo"
        self.LE_nombre.setText('Mundo')
        # Mostramos la instancia de la clase
        self.show()

    # Creamos la función que realizará el botón al ser presionado
    def _saludar(self):
        # Cambiamos el valor de la etiqueta LB_Saludo
        self.LB_Saludo.setText('Hola '+self.LE_nombre.text())

# Creamos una instancia de la aplicación
app = QtWidgets.QApplication(sys.argv)
# Creamos una instancia de la clase donde estan todas las funciones y objetos
window = Ui()
# Ejecutamos el loop principal de eventos de la aplicación
app.exec_()

Y de esta manera ya tenemos una interfaz gráfica realizada en Qt Designer conectada a un script en python y que además es funcional.

El código completo esta aquí por si quieres probarlo, incluye el archivo .ui que se hizo en Qt Designer.

Espero les sirva este pequeño ejercicio. Hasta la próxima.

Te puede interesar: