10 Control progreso

Un control de progreso, o gauge en wxWidgets es un control estático, encapsulado en la clase wxGauge. Es estático desde el punto de vista de que no está destinado a obtener información del usuario, sino únicamente a proporcionarla.
En el modo de progreso determinado se usa para indicar el progreso de una tarea que está realizando la aplicación, cuando ese progreso se puede medir, es decir, cuando es calculable tanto los pasos necesarios para completar la tarea como los ya realizados. Esto se aplica, por ejemplo, a bucles donde conocemos los valores iniciales y finales y el valor actual de la iteración.
En rigor esto no es siempre cierto. Por ejemplo, en un crawler, que debe explorar un sitio web, podríamos usar una barra de progreso para indicar cuántas páginas hemos visitado y cuántas quedan por visitar, pero a medida que visitamos nuevas páginas se pueden detectar nuevos enlaces que aumenten el número de páginas a visitar, por lo que la barra a veces avanzará y otras retrocederá. Siempre dependerá de nosotros cómo usar estos controles, y decidir si la información que suministran es o no útil.
Otro ejemplo de uso, que a menudo frustra al usuario, es aplicar barras de progreso a procedimientos en los que cada paso no requiere el mismo tiempo, sobre todo cuando los que más tiempo requieren son los últimos pasos. El ejemplo más evidente de esto son las barras de progreso para la instalación de programas o descargas desde internet, en los que, por alguna razón, el último 1% requiere más tiempo para completarse que los primeros 99%. En estos casos es preferible usar varios controles de progreso, uno para cada tipo de tarea, de modo que el usuario pueda calcular si tiene tiempo para ir a por un café, a comer, a dormir o de vacaciones.
Los controles de progreso soportan un segundo modo, el indeterminado, que se aplica cuando el progreso no se puede medir. En este caso la barra del control no irá creciendo con cada actualización, sino que desplazará un conjunto de bloques a lo largo del control. Se comporta como un control de animación, y se usa principalmente para indicar que la aplicación está realizando una tarea, pero que no se conoce cuánto de esa tarea queda para terminarla.
Estilos
Los estilos de estos controles afectan sólo a su apariencia. Por ejemplo wxGA_HORIZONTAL y wxGA_VERTICAL crean controles con la barra horizontal o vertical, respectivamente. Por defecto se creará una barra de progreso horizontal.
wxGA_SMOOTH, en las plataformas que lo soportan, hace que el avance de la barra sea pixel a pixel.
wxGA_TEXT, sólo soportado por wxQt, muestra un texto en la propia barra con el porcentaje de progreso.
wxGA_PROGRESS muestra el valor actual de progreso en el botón de la barra de tareas de la aplicación.
Insertar controles de progreso
Al tratarse de un control básicamente estático (aunque su apariencia cambie durante la ejecución), su constructor es relativamente simple, y en general no será necesario usar validadores, puesto que no hay valores de retorno que validar.
Los dos primeros parámetros son, como siempre, la ventana padre y el identificador.
El tercero es el rango, o valor máximo del control. El mínimo siempre es cero.
A continuación la posición, el tamaño, el estilo, el validador y el nombre del control.
m_gauge1 = new wxGauge(this, idGauge1, 100, wxDefaultPosition, wxSize(200, wxDefaultCoord), wxGA_SMOOTH);
Modos de funcionamiento
No existen métodos en la clase wxGauge para cambiar el modo directamente. Por defecto se crea en modo determinado, pero se puede cambiar al modo indeterminado usando el método Pulse, y se puede volver al modo determinado usando el método SetRange o SetValue.
Cuando un control de progreso está en modo indeterminado, es decir, si se usa el método Pulse, no será necesario volver a invocar ese método para activar el desplazamiento de los bloques. Ese desplazamiento continuará de forma automática mientras el control siga en ese modo.
Trabajar con controles de progreso
Aunque la interfaz de la clase wxGauge es muy sencilla, trabajar con estos controles no lo es tanto.
Puede parecer tentador usar un bucle dentro de uno de los métodos de nuestra clase diálogo, y actualizar el control desde ese bucle. Sin embargo esto no funcionará como esperamos, ya que el diálogo no recibirá los eventos para actualizar el control en tiempo real. En su lugar, esos eventos se almacenarán internamente hasta que la ejecución del método termine, y sólo entonces el diálogo procesará la cola de eventos.
El resultado es que la aplicación se congelará hasta que termine la ejecución del método y después el control de progreso se actualizará rápidamente.
No es eso lo que queremos, la idea es que el control de progreso refleje fielmente el avance del proceso, de modo que tendremos que actuar de otro modo.
Ese modo es usar hilos o temporizadores, de los que hablaremos en un capítulo posterior.
En el ejemplo de este capítulo hemos usado un temporizador para simplificar. En la práctica, usar temporizadores para realizar tareas repetitivas no es práctico, ya que se desperdicia mucho tiempo de procesador.
Es preferible usar un hilo (thread), que ejecute la tarea en segundo plano y que envíe eventos al cuadro de diálogo para actualizar la barra de progreso, y cualquier otro control que consideremos necesario.
En cualquier momento podremos obtener el valor actual del control mediante el método GetValue y modificarlo mediante SetValue. También podemos modificar el rango mediante SetRange o consultarlo con GetRange.
Ejemplo 10
Nombre | Fichero | Fecha | Tamaño | Contador | Descarga |
---|---|---|---|---|---|
Ejemplo 10 | wx010.zip | 2024-12-02 | 4613 bytes | 6 |