GUI
QT
Optativa 1 TUP: Desarrollo en Python
GUI: QT
Dr. Cristian Martínez | Mag. José I. Tuero
Departamento de Informática
Universidad Nacional de Salta
Setiembre, 2022
1 / 32
GUI
QT
Agenda
1 GUI
2 QT
Hello QT
Segundo ejemplo
Tercer ejemplo
Cuarto ejemplo
Quinto ejemplo
2 / 32
GUI
QT
Muchas veces para resolver un problema computacional, es
necesario disponer de una interfaz visual.
A diferencia del uso de consola, una interfaz visual facilita al
usuario final la carga de datos y la presentación de los mismos.
3 / 32
GUI
QT
Para trabajar con ventanas y componentes visuales en Python,
debemos haccer uso de librerías. Una de ellas es QT.
QT es un conjunto de librerías que permite crear aplicaciones de
escritorio y móviles. A diferencia de Tkinter, ofrece una amplia
variedad de widgets usando un designer para mayor facilidad.
Link: [Link]
Link: [Link]
1dcd57542bdaf3c9d1b0dd526ccd44ff
4 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Sin más, veamos el primer ejemplo con QT. Para ello, tiene que
estar instalado al igual que QT Designer.
Veremos un Hello QT!
Paso 1: Abrir QT Designer
Elegimos Main Window y hacemos clic en Crear.
5 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Paso 2: Setear el UI
Al Window, le agregan un Label simplementen arrastrándolo de la
paleta. Cambian el texto y graban el diseño. Por ejemplo, [Link].
6 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Paso 3: Linkear y correr
Creamos una clase y cargamos el UI. Luego ejecutamos el .py y
listo!
7 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El problema
Para el segundo ejemplo, haremos uso de cuadros de texto
(QTextEdit) y botones (QPushButton).
Los cuadros de texto son útiles para la entrada y salida de texto.
Respecto a los botones, los mismos se usan para ejecutar acciones
(métodos) a partir de la interación del usuario (haciendo clic en
este caso) con la aplicación desarrollada.
Con estos widgets en un window y aprovechando la potencia de
Python para evaluar expresiones matemáticas, desarrollaremos una
calculadora básica.
8 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El UI
Vamos a necesitar un cuadro de texto para ingresar la expresión
matemática y varios botones (ubicados en forma matricial) para los
dígitos, borrar texto, ejecutar la expresión entre otros.
9 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
La lógica
Cuando apretemos (o hagamos clic) sobre los dígitos, comas y
operandos, tenemos que ”lograr” que los mismos se muestren en
pantalla. Y que al apretar el ”=”, se evalúe la expresión ingresada
y obtenga el resultado.
Para esto vamos a usar una clase similar al primer ejemplo, que en
el constructor invoque al ”ui”. Pero además, que setee el
comportamiento sobre los botones (sobre el cuadro de texto en
esto caso no nos interesa).
10 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Agregando comportamiento
def setupUiComponents(self):
[Link]([Link])
[Link](lambda: [Link](’0’))
[Link](lambda: [Link](’+’))
[Link](lambda: [Link]())
def borrarTexto(self):
[Link](””)
def insertaFin(self, caracter):
texto = [Link]()
[Link](texto + caracter)
def evalua(self):
texto = [Link]()
[Link](str(eval(texto)))
11 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Corriendo el .py
12 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El Problema
Seguiremos trabajando con botones pero ahora meteremos más
código y usaremos otros widgets.
El tercer ejemplo consistirá de un cronómetro. Usaremos un
QLCDNumber (tiene mejor estética que un QTextEdit) y 3
QPushButtons para iniciar, pausar y resetear el cronómetro.
13 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El UI
Spbre un MainWindow, arrastramos los widgets y seteamos texto,
nombres y cuestiones de formato.
14 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
La lógica
Cuando hagamos clic en Start, queremos que el Display muestre el
tiempo (por ejemplo en formato HHMMSS). La actualización debe
ser por ejemplo cada décima de segundo.
Al hacer clic en Pause, queremos que el Display se pause. Pero que
se pueda continuar desde el momento en que se detuvo.
Finalmente, el Reset es el encargado de poner en 0 al Display.
15 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Detalles de implementación
Como el Display debe actualizarse varias veces durante la ejecución
del código, la alternativa más usada para hacer esto efectivo es
mediante Threads. Sin embargo, QT ofrece QTimer que permite
invocar un método de manera repetida cada cierto tiempo. De
esta manera, evitamos trabajar con Threads desde 0.
El timer va a invocar a showTime() y si se ha iniciado el proceso
(clic en start), entonces mostrará el Display actualizado. Dicha
actualización se hará con un counter.
16 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Parte del código
def setupUiComponents(self):
[Link] = 0
[Link] = False
[Link]([Link])
[Link] = QTimer(self)
[Link]([Link])
[Link](100)
def start(self):
[Link] = True
def showTime(self):
if [Link]:
[Link] +=1
number = str([Link] / 10)
[Link](str(A) + ’:’ + str(B) + str(C) + ’.’ + str(D))
17 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Corriendo el .py
Si está todo bien, al hacer clic en start deberíamos ver el Display
mostrando el tiempo que se va actualizando.
18 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El problema
Ya sea para el desarrollo de aplicaciones de escritorio, web o móvil,
muchas veces tendremos que mostrar una lista de datos de una
determinada entidad. Pero además de eso, queremos poder
agregar, eliminar y actualizar filas de dicha lista.
Y todo esto, con la posibilidad de mostrar una ventana emergente
para cargar e editar la fila que se desee.
En el cuarto ejemplo, usaremos un QTableWidget para mostrar
datos de una entidad (en forma matricial) y un segundo formulario
que contendrá QDoubleSpinBoxes y QComboBox para editar
fácilmente a la fila elegida.
19 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El UI
Por un lado tenemos un window que contendrá un QTableWidget y
QPushButtons para editar una fila y cerrar la ventana.
20 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El UI2
Los datos que se mostrará en el QTable serán los de Iris, dataset
muy conocido para testear propuestas de DM y ML.
Desde el QTable iremos a un nuevo window que corresponde a un
formulario con QDoubleSpinBox y QComboBox para editar filas de
Iris.
21 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
La lógica
Al cargar el primer window, queremos que se carguen los datos de
Iris en el QTable.
Al hacer clic en alguna celda y modificar el valor de la misma, se
quiere hacer clic en el QpushButton correspondiente para que se
guarden los cambios (en el csv).
Finalmente, al hacer doble clic sobre aguna celda en la última
columna, debe cargarse una nueva ventana con los datos de la fila
para una fácil edición.
22 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Parte del código
def loadTable(self):
myFile = open([Link], ’r’)
try:
reader = [Link](myFile, delimiter=’,’)
rowI=0
for row in reader:
[Link](rowI+1)
if rowI==0:
columns =len(row)
[Link](columns)
columns = len(row)
for columnJ in range(columns):
myValue = row[columnJ]
cell = QTableWidgetItem(str(myValue))
[Link](rowI,columnJ,cell)
rowI = rowI + 1
finally:
[Link]()
23 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Parte del código 2
def loadForm(self,index):
column = [Link]()
if column ==4:
# abro el form
row = [Link]()
sl = [Link](row, 0).text()
sw = [Link](row, 1).text()
pl = [Link](row, 2).text()
pw = [Link](row, 3).text()
variety = [Link](row, 4).text()
self.w = [Link](sl,sw,pl,pw,variety)
[Link]()
24 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Corriendo el .py
25 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
El problema
La mayoría de las aplicaciones sin importar la arquitectura, suelen
contar con un menú principal.
Este nos permite acceder a diferentes funcionalidades de la
aplicación. En nuestro caso, nos gustaría cargar el window que
incluye el QTable con datos de iris.
26 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
La lógica
Vamos a crear un menú con 2 opciones.
La primera permitirá buscar un csv y cargarlo en el window con
QTable. Ahora se cargaría cualquier csv.
La segunda opción cerrará la aplicación.
27 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Detalles de implementación
Para este ejemplo, no necesitamos el QT Designer. Simplemente,
usaremos el menuBar que incluye todo window y agregar las
opciones que se deseen.
Cada opción de menú podría incluir ícono, atajo, título de la
opción y método asociado al elegir dicha opción.
Para abrir archivos usando un cuadro de diálogo, usaremos
QFileDialog. Se puede indicar la carpeta por defecto y los tipos de
archivos permitidos.
28 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Parte del código
def initUi(self):
menubar = [Link]()
fileMenu = [Link](’&File’)
exitAction = QAction(QIcon(’resources/icons/[Link]’), ’&Exit’,
self)
[Link](’Ctrl+Q’)
[Link](’Exit application’)
[Link]([Link])
openAction = QAction(QIcon(’resources/icons/[Link]’),
’&Open’, self)
[Link](’Ctrl+O’)
[Link](’Open CSV’)
[Link]([Link])
[Link](openAction)
[Link](exitAction) 29 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Parte del código 2
def openCSV(self):
fname = [Link](self, ’Open file’,
’/home/’,”CSV files (*.csv)”)
if fname[0]:
[Link] = fname[0]
[Link]().showMessage(’Archivo abierto ’ + [Link])
self.w = [Link]([Link])
[Link]()
else:
[Link]=”
[Link]().showMessage(”No eligio archivo”)
30 / 32
Hello QT
Segundo ejemplo
GUI
Tercer ejemplo
QT
Cuarto ejemplo
Quinto ejemplo
Corriendo el .py
31 / 32
GUI
QT
The End
32 / 32