Es hora de aprender a añadirle una función a nuestro botón en Pyqt!
En la entrada anterior vimos como separar el código funcional de la interfaz gráfica. Creamos nuestra primera aplicación la cual llamamos MiPrograma y constaba de una ventana pequeña con un botón y un label. En esta entrada aprenderemos a interactuar con ellos para crear nuestra primer aplicación funcional con entorno gráfico. Para eso vamos a añadir una función a un botón. Ya se, ya se que sera una tontería..
Lo importante aquí es aprender como funcionaran nuestros programas en la interfaz gráfica. La interacción con botones, menús, barras, etc. Comenzaremos por algo muy básico para no extraviarnos en el código, luego puedes experimentar por ti mismo un poco. También cabe recalcar que es importante conocer los atributos de cada objeto para trabajarlo con soltura. Pero eso lo veremos mas adelante..
Nuestra primera aplicación sencilla con un botón pyqt 5
El objetivo de nuestra aplicación es que al presionar el botón en pyqt el label cambie, mostrando un texto diferente.
En este caso cambie un poco el label y el botón en designer de Miprograma.py, y lo volví a convertir a “_ui.py”. Tal como era antes el mismo código, solo cambio el texto de ambos objetos.
Así que tenemos nuestro archivo Miprograma.py así:
#!/usr/bin/env python # -*- coding: utf-8 -*- # #https://pythones.net import sys #Importamos módulo sys from PyQt5 import uic, QtWidgets #Importamos módulo uic y Qtwidgets qtCreatorFile = "miventana.ui" # Nuestro archivo UI aquí. Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) #El modulo ui carga class VentanaPrincipal(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): #Constructor de la clase QtWidgets.QMainWindow.__init__(self) #Constructor Ui_MainWindow.__init__(self) #Constructor self.setupUi(self) # Método Constructor de la ventana #Aquí ira el código funcional if __name__ == "__main__": #Condicional que comprueba si ha sido ejecutado o importado #NO importamos el módulo Sys app = QtWidgets.QApplication([]) #Creamos app y le pasamos una lista de argumentos vacíos #Borramos todo el resto del código y ahora vamos a instanciar nuestra clase MainWindow: ventana = VentanaPrincipal() #Ahora es hora de mostrar esta ventana: ventana.show() #Aquí creamos el bucle de ejecución app.exec_() #Usamos app.exec_() para crear el bucle de ejecución
Siento dar tanta lata, espero poder grabar vídeos pronto y entonces va a facilitar un poco las cosas!
En fin, edite en Designer nuestro programa así quedando un Label y un Button:
Función; cambiar el texto del Label
Ahora le agregaremos la funcionalidad, pues en este momento al presionar el botón no sucede nada. Para eso primero vamos a crear una función que luego le asignaremos al evento “Click” del botón.
def FuncionPresionar(): self.label.setText("Un clavito clavo Pablito")
A estas alturas es obvio que sabes crear una función, así que nos vamos a concentrar en explicar el código dentro de ella. Este código es un método del objeto “label” que como su nombre lo indica es el encargado de “setear el texto dentro de el”. El mismo se utiliza para cambiar o establecer el texto del label. Estos métodos y atributos de los objetos luego vamos a tratar de expresarlos y explicarlos a todos, en una tablita con ejemplos.
Seguimos, esta función va a cambiar el texto del Label “label”. Si te fijas en el código de miventana_ui.py puedes ver que allí se encuentra el objeto “label“. En el caso que añadiéramos varios labeles, automáticamente se llamaría “label2” por ejemplo. Estos nombres de los objetos los puedes editar en Designer.
Conectar el botón en pyqt a la función:
Ahora vamos a conectar el botón para que al hacer click en el se ejecute esta función que creamos. Para eso recurrimos al siguiente método brindando como argumento nuestra función:
self.pushButton.clicked.connect(FuncionPresionar)
Siempre que quieras añadir una función a un botón mediante el evento click procura que la función a la cual conectas este declarada antes. Recuerda que no puedes llamar a una función que aun no existe, o no fue creada antes del código que esta llamándola.
En definitiva nuestro código final quedaría así:
#!/usr/bin/env python # -*- coding: utf-8 -*- # #https://pythones.net import sys #Importamos módulo sys from PyQt5 import uic, QtWidgets #Importamos módulo uic y Qtwidgets qtCreatorFile = "miventana.ui" # Nuestro archivo UI aquí. Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) #El modulo ui carga class VentanaPrincipal(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): #Constructor de la clase QtWidgets.QMainWindow.__init__(self) #Constructor Ui_MainWindow.__init__(self) #Constructor self.setupUi(self) # Método Constructor de la ventana #Función que se llama al presionar def FuncionPresionar(): self.label.setText("Un clavito clavo Pablito") #Acción al presionar el botón self.pushButton.clicked.connect(FuncionPresionar) if __name__ == "__main__": #Condicional que comprueba si ha sido ejecutado o importado #NO importamos el módulo Sys app = QtWidgets.QApplication([]) #Creamos app y le pasamos una lista de argumentos vacíos #Borramos todo el resto del código y ahora vamos a instanciar nuestra clase MainWindow: ventana = VentanaPrincipal() #Ahora es hora de mostrar esta ventana: ventana.show() #Aquí creamos el bucle de ejecución app.exec_() #Usamos app.exec_() para crear el bucle de ejecución
Resultado luego de clickear el botón:
Nuestro programa funciona correctamente pero no se conserva el estilo de texto del label. Para solucionar esto podemos incluir los estilos directamente dentro del argumento de la función. Si te fijas en la linea 46 de miventana_ui.py es el siguiente:
<html><head/><body><p><span style=\" font-size:18pt; color:#55aa00;\">Un clavito clavo Pablito</span></p></body></html>"
Quedando nuestra función así:
def FuncionPresionar(): self.label.setText("<html><head/><body><p><span style=\" font-size:18pt; color:#55aa00;\">Un clavito clavo Pablito</span></p></body></html>")
Ahora si nuestra primer aplicación final con interfaz gráfica!
Todo esto parece una tontería, es que en realidad lo es!! :B . Nos vemos en la siguiente entrada muy pronto!
Saludos!! Quisiera agregar lo siguiente, el código tal cuál lo tienes no me ha funcionado, es decir, clickeo en el boton y no hace nada, sin embargo, si se modifica la sección del código función del botón me realiza correctamente el evento:
El cambio es que el evento del click del botón debo especificarlo dentro del apartado del constructor de ventana, por lo tanto, a la función debe agregarlo “self.” antes, si no, me arroja error al ejecutar. Y como la función tiene “self.” antes al definir la función “FuncionPresionar” entre parentesis se debe escribir “self” y quedar como “def FuncionPresionar(self):”
Nota: Desconozco si este error es general o sólo me ocurrió a mí.
Nota2: La solución no es mía, la encontré navegando y probando códigos.
Nota3: No entiendo del todo por que la solución funciona… En teoría supongo tiene sentido, declarar el evento a ocurrir en la sección de la ventana, al estar en dicha sección debo agregarle (self) para que lo reconozca y al agregarle (self) la función debe tener este nombre para llamarla correctamente. Pero no estoy seguro si es así… Si alguien puede explicar por que esto funcionó, estaría agradecido, o si hay otras alternativas, quedo atento.
Tu app funciona porque el decalrador self es iguala la matriz interna del sistema de computación que se escoge a traves del modulo d-4&€2 sin mediacion del promedio self.
Lo dicho abajo 👇.