Efecto Fade en Qt

El efecto de desvanecimiento, tanto a la entrada como a la salida de las interfaces genera una sensación de transición, y aplicado en ciertos puntos mejora la apariencia de la misma.

El día de hoy quiero compartir con ustedes la forma de crear widgets con el efecto fadein.

El código fuente puede ser descargado desde el este link.

El efecto de FadeIn consiste simplemente en la variación de la transparencia en un periodo determinado de tiempo. Para este ejemplo lo que implementaremos será crear un Widget que tenga el color de fondo del la ventana padre, está ubicado sobre está e irá desapareciendo gradualmente generando el efecto deseado .

class FaderWidget : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QColor fadeColor
               READ fadeColor
               WRITE setFadeColor)
    Q_PROPERTY(int fadeDuration
               READ fadeDuration
               WRITE setFadeDuration)
public:
    FaderWidget(QWidget *parent);
    QColor fadeColor() const { return color; }
    void setFadeColor(const QColor &newColor);
    int fadeDuration() const { return duration; }
    void setFadeDuration(int milliseconds);
    void start();
protected:
    void paintEvent(QPaintEvent *event);
private:
    QTimer *timer;
    int currentAlpha;
    QColor color;
    int duration;
};

Implementación:

La propiedad fadeColor controla el color desde el cual vamos a realizar el desvanecimiento. La fadeDuration representará el tiempo en milisegundos que durará en completarse el efecto.

Constructor:

FaderWidget::FaderWidget(QWidget *parent)
    : QWidget(parent)
{
    if (parent)
        startColor = parent->palette().window().color();
    else
        startColor = Qt::white;
    currentAlpha = 0;
    duration = 333;
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),
            this, SLOT(update()));
    setAttribute(Qt::WA_DeleteOnClose);
    resize(parent->size());
}

El constructor inicializa el color del widget. La duración del efecto es ajustada en 333 mili-segundos, esto es suficientemente corto como para no generar distracción en el usuario.

También podemos ver que activamos el atributo Qt::WA_DeleteOnClose, ya que el FaderWidget es un widget de corta vida que se elimina a si mismo una vez que finaliza el efecto. Por otra parte creamos un QTimer para llamar repetidamente la función update, finalmente cambiamos el tamaño del widget al del parent para cubrirlo completamente.

void FaderWidget::start()
{
    currentAlpha = 255;
    timer->start(33);
    show();
}

La función star inicia el efecto. Esta asigna el valor de 255 (Totalmente opaco) a la variable currentAlpha. Para poder obtener un efecto a una rata de 30 FPS, dentro del rango de lo apropiado para una buena visualización del mismo, usamos una frecuencia de 33 ms

Ahora cada vez que el QTimer emita la señal timeout obtendremos un paintEvent(), este se verá así:

 void FaderWidget::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter(this);
    QColor semiTransparentColor = startColor;
    semiTransparentColor.setAlpha(currentAlpha);
    painter.fillRect(rect(), semiTransparentColor);

    currentAlpha -= 255 * timer->interval() / duration;
    if (currentAlpha stop();
        close();
    }
}

Creamos un color basados en el color original y el valor del canal alfa. Llenamos el widget con este color y decrementamos ligeramente el valor de la transparencia de tal manera que transcurrido el tiempo de duración del efecto el widget ya sea transparente.

Puesta en Marcha

Ahora implementaremos nuestra clase en un ejemplo de Qt para poder apreciar su funcionamiento. Usaremos el ejemplo “dialogs/configdialog”, simplemente necesitamos añadir un nuevo slot privado y un QPointer.

private slots:
    void fadeInWidget(int index);
private:
    QPointer faderWidget;

En el constructor del QStackedWidget conectamos la señal currentChanged() a nuestro nuevo slot:

connect(pagesWidget, SIGNAL(currentChanged(int)),
        this, SLOT(fadeInWidget(int)));

Y finalmente el slot:

void ConfigDialog::fadeInWidget(int index)
{
    if (faderWidget)
        faderWidget->close();
    faderWidget = new FaderWidget(
                              pagesWidget->widget(index));
    faderWidget->start();
}

Primero verificamos si tenemos un FaderWidget, aquí es donde un QPointer es muy util, ya que, a diferencia de un puntero estándar se vuelve cero cuando el objeto apuntad es eliminado. Si existe un FaderWidget este es cerrado ya que no necesitamos mas de uno al mismo tiempo.

En cualquier caso, creamos un nuevo FaderWidget, y llamamos la función star(), el resto es historia, solo hace falta que lo veas tu mismo.

Espero este corto tutorial les sea de utilidad a la hora de mejorar el aspecto visual de sus aplicaciones.

Creditos

Este tutorial está basado en una guia publicada por Trenton Schulz en la Qt Quarterly licenciado bajo Creative Commons Attribution-Share Alike 2.5

Anuncios

Tu opinión nunca está de más...

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: