[Este artículo viene de una revisión de lujo que ha hecho Cristián Maureira-Fredes de los capítulos anteriores. Cristián trabaja como ingeniero de software en el proyecto Qt for Python dentro de The Qt Company. Este artículo lo escribo yo pero a partir de las sugerencias de Cristián por lo que, en este caso, soy un mero intermediario y el autor podría ser él. Gracias, Cristián].
Hasta ahora hemos estado viendos cosas sencillas. Algunas no eran del todo correctas o son mejorables. En este capítulo describo cómo mejorar algunas de las cosas que hemos venido haciendo hasta ahora.
Índice:
- Instalación de lo que vamos a necesitar.
- Qt, versiones y diferencias.
- Hola, Mundo.
- Módulos en Qt.
- Añadimos icono a la ventana principal.
- Tipos de ventana en un GUI.
- Ventana inicial de carga o Splashscreen
- Menu principal. Introducción.
- Mejorando algunas cosas vistas (este capítulo).
- Gestión de eventos o Acción y reacción.
- Introducción a Designer.
- Los Widgets vistos a través de Designer: Primera parte.
- Los Widgets vistos a través de Designer: Segunda parte.
- Los widgets vistos a través de Designer: Tercera Parte.
- Los widgets vistos a través de Designer: Cuarta Parte.
- Los widgets vistos a través de Designer: Quinta Parte.
- Los widgets vistos a través de Designer: Sexta parte.
- TBD… (lo actualizaré cuando tenga más claro los siguientes pasos).
[Los materiales para este capítulo los podéis descargar de aquí]
[INSTALACIÓN] Si todavía no has pasado por el inicio del curso, donde explico cómo poner a punto todo, ahora es un buen momento para hacerlo y después podrás seguir con esta nueva receta.
Partimos del siguiente código:
'''
Curso de creación de GUIs con Qt5 y Python
Author: Kiko Correoso
Website: pybonacci.org
Licencia: MIT
'''
import os
os.environ['QT_API'] = 'pyside2'
import sys
from pathlib import Path
from qtpy.QtWidgets import QApplication, QMainWindow
from qtpy.QtGui import QIcon
class MiVentana(QMainWindow):
def __init__(self):
super().__init__()
self._create_ui()
def _create_ui(self):
self.resize(500, 300)
self.move(0, 0)
self.setWindowTitle('Hola, QMainWindow')
ruta_icono = Path('.', 'imgs', 'pybofractal.png')
self.setWindowIcon(QIcon(str(ruta_icono)))
self.statusBar().showMessage('Ready')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MiVentana()
sys.exit(app.exec_())
Constructor de la clase
Al llamar al constructor de la clase que heredamos, existen varias formas y la mayoria son equivalentes. Podemos ver estas tres:
class MyWidget(QWidget):
def __init__(self):
QWidget.__init__(self)
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
class MyWidget(QWidget):
def __init__(self):
super().__init__()
Sacado de aquí.
Hasta ahora he venido usando la tercera forma. Cristián indica que es correcto llamarlo así pero que él prefiere usar la primera forma, la cual es más explícita y puede ser más evidente y menos liosa en casos de herencia múltiple.
Por tanto, a partir de ahora usaré la primera forma para ser más explícito y respetar el zen de Python (Explicit is better than implicit.).
Padre de un QObject
Cristián indica que es buena práctica incluir un padre en el inicializador, aunque este sea None. Por diseño, todos los QObject tienen que tener un padre así que lo incluiré:
class MyWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
Método show explícito
Hasta ahora, dentro del método _create_ui había una llamada al método show que es el que hace que se abra la ventana. Al hacerlo así se puede perder la noción de porqué se abre la ventana y sería mejor dejarlo dentro del bloque final (if __name__ == '__main__':). De esta forma quedaría así:
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MiVentana()
w.show()
sys.exit(app.exec_())
Resumen
Teniendo en cuenta estas tres cosas, el bloque inicial de código que he puesto quedará así:
'''
Curso de creación de GUIs con Qt5 y Python
Author: Kiko Correoso
Website: pybonacci.org
Licencia: MIT
'''
import os
os.environ['QT_API'] = 'pyside2'
import sys
from pathlib import Path
from qtpy.QtWidgets import QApplication, QMainWindow
from qtpy.QtGui import QIcon
class MiVentana(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self._create_ui()
def _create_ui(self):
self.resize(500, 300)
self.move(0, 0)
self.setWindowTitle('Hola, QMainWindow')
ruta_icono = Path('.', 'imgs', 'pybofractal.png')
self.setWindowIcon(QIcon(str(ruta_icono)))
self.statusBar().showMessage('Ready')
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MiVentana()
w.show()
sys.exit(app.exec_())
Y, por hoy, creo que ya es suficiente.
Como resumen. Hemos aplicado una serie de buenas prácticas que intentaré respetar de aquí en adelante.
Pybonacci