Fundamentos del mecanismo de cierre en QT6
En el desarrollo con QT6, el cierre de una ventana desencadena un flujo de eventos específico. Al invocar QWidget::close(), se genera un objeto QCloseEvent que ingresa a la cola de eventos. La implementación de closeEvent determina si la ventana se oculta o se marca para eliminación. Sobrescribir esta función permite interceptar la solicitud, decidiendo entre aceptar o rechazar el cierre mediante los métodos del evento.
// Implementación base del evento de cierre
void VentanaPrincipal::eventoCierre(QCloseEvent *e) {
// Acción predeterminada: aceptar el evento y ocultar la ventana
e->accept();
}
La secuencia completa involucra: detección del cierre (por usuario o programa), creación del QCloseEvent, procesamiento en la función virtual, y ejecución de acciones según accept() o ignore(). Si se acepta y el atributo Qt::WA_DeleteOnClose está habilitado, la ventana se marca para liberación automática de memoria.
Primer enfoque: Diálogo de confirmación interactivo
Para prevenir pérdida de datos, se puede integrar un cuadro de diálogo que solicite confirmación antes de cerrar. Esto implica evaluar el estado de la aplicación dentro del evento.
void EditorDocumentos::eventoCierre(QCloseEvent *evt) {
if (contenidoDocumento->modificado()) {
QMessageBox::StandardButton respuesta;
respuesta = QMessageBox::question(this, "Cambios pendientes",
"El documento tiene modificaciones no guardadas. ¿Proceder?",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Abort);
switch (respuesta) {
case QMessageBox::Save:
if (contenidoDocumento->almacenar()) {
evt->accept();
} else {
evt->ignore();
}
break;
case QMessageBox::Discard:
evt->accept();
break;
default:
evt->ignore();
}
} else {
evt->accept();
}
}
Este patrón asegura que el usuario revise cambios críticos, mejorando la robutsez de la aplicación.
Segundo enfoque: Liberación automática con WA_DeleteOnClose
Configurar el atributo Qt::WA_DeleteOnClose en una ventana permite que QT gestione automáticamente su eliminación tras el cierre, evitando fugas de memoria.
// Asignar atributo en el constructor
VentanaDialogo::VentanaDialogo(QWidget *padre) : QDialog(padre) {
setAttribute(Qt::WA_DeleteOnClose);
}
Al aceptar el evento de cierre, el objeto se destruye después de ocultarse, liberando recursos del sistema sin intervención manual.
Tercer enfoque: Terminación de procesos dependientes
Si la ventana administra procesos secundarios o hilos, es esencial finalizarlos adecuadamente durante el cierre para evitar bloqueos o recursos huérfanos.
void VentanaConProceso::eventoCierre(QCloseEvent *e) {
if (miProceso->state() == QProcess::Running) {
miProceso->kill();
miProceso->waitForFinished(2000); // Espera máxima de 2 segundos
}
e->accept();
}
Esta estrategia garantiza una terminación limpia, manteniendo la estabilidad del sistema.
Cuarto enfoque: Persistencia del estado de la aplicación
Para mejorar la experiencia del usuario, se puede guardar automáticamente el estado de la ventana (como geometría y configuraciones) al cerrar, restaurándolo en la próxima ejecución.
void AplicacionPrincipal::eventoCierre(QCloseEvent *ev) {
QSettings ajustes("MiEmpresa", "MiApp");
ajustes.setValue("geometriaVentana", saveGeometry());
ajustes.setValue("estadoVentana", saveState());
ev->accept();
}
Implementar esto en el evento de cierre asegura que la configuración del usuario se preserve entre sesiones.
Quinto enfoque: Señales personalizadas para comunicación inter-componentes
En arquitecturas complejas, emitir una señal al cerrar la ventana permite que otros componentes reaccionen antes de la destrucción, facilitando tareas como limpieza de recursos o notificación.
class VentanaSecundaria : public QWidget {
Q_OBJECT
signals:
void ventanaCerrada();
public:
void eventoCierre(QCloseEvent *e) override {
emit ventanaCerrada();
e->accept();
}
};
Los slots conectados a esta señal pueden ejecutar lógica adicional, como actualizar vistas o liberar cachés, antes de que la ventana desaparezca.