Sustituyendo la interfaz gráfica por QML (parte III)

Buenas,

En el apartado anterior nos quedamos con lo siguiente:

  1. errorWidget
  2. remoteUserDisplayLabel
  3. videoPreviewWidget
  4. videoWidget
  5. callStackedWidget
  6. dtmfStackedWidget

Así que eso nos pide hacer lo correspondiente en QML si queremos que el programa funcione igual. Si véis el código, podéis ver que he añadido componentes para hacer casi todo. El error widget no lo he mantenido porque no le veo una buena utilidad ahora mismo, así que de momento lo mantendré fuera.

El resto de cosas aparecen, de una forma u otra. Los Widgets que pone Stacked son porque están, como dice su nombre, apilados. Esto quiere decir que para que se muestre uno tiene que ocultarse el otro etc, que están puestos unos encima de los otros. En mi caso, el dtmf (el teclado numérico) irá en una ventana independiente para no tapar lo que hay debajo, que sería el vídeo en el programa original.

El remoteUserDisplayLabel sí que será apilado con el vídeo y se turnarán, porque si ves el vídeo no necesitas ver el avatar del tipo con el que hablas y la intención del Label simplemente es decirte a quién llamas cuando todavía no te ha cogido. En el archivo Main.qml podéis ver como funciona eso en la función showVideo() se intercambia la visibilidad entre la etiqueta y el vídeo.

Una vez hemos visto lo que hay, lo suyo es ir a cada una de las funciones, señales y slots de cada bloque y replicarla en el archivo QML. De modo que la interfaz pueda comunicarse igual que antes. En el Main.qml podéis ver que tiene señales de salida y de entrada, algunas sirven para avisar de cuándo se ha pulsado un botón interno (de la interfaz) y otras sirven para avisar de que se ha pulsado un botón externo y el icono intero tiene que actualizarse.

Para gestionar todo esto con más sencillez he creado una clase que maneja la pantalla, que se llama qml-interface (buscad aquí) y una que se llama dtmf-qml para controlar el dtmf.

En ambas utilizo QDeclarativeView (seguramente tenga que usar KDeclarativeView 😦 ) para cargar el archivo QML que necesito y utilizarlo como si fuera un único Widget que será añadido como Widget central a la aplicación:

void CallWindow::setupQmlUi()
{
    d->qmlUi = new QmlInterface( this );
    setCentralWidget(d->qmlUi);
}

Las equivalencias se basan en enviar señales que hagan lo mismo que antes y que funcionen como un pegamento. Además, como se pueden conectar señales a señales nos aseguramos por ejemplo que, cuando pulsemos el botón de la interfaz nueva, el icono de la barra de menú cambie (setActivated()) y se efectúe la función necesaria al mismo tiempo.

Y simplemente, como ya sabemos que tenemos todos los widgets necesarios, vamos a todas las veces en las que aparecen y sustituimos el código antiguo por el nuevo. Si no se puede de primeras, es que nos falta algo, así que lo desarrollamos y listo. 🙂

Un par de ejemplos, lo comentado es lo antiguo:

1.) Como el Dtmf ya no es stacked hay que sustituir el índice (que nos indica su posición en la pila) por hide y show de la nueva interfaz:

void CallWindow::toggleDtmf(bool checked)
{
//d->ui.dtmfStackedWidget->setCurrentIndex(checked ? 1 : 0);
    if(checked){
        d->dtmfQml->show();
    }else{
        d->dtmfQml->hide();
    }    
}

2.) Los vídeos funcionan diferente:

        //QGst::ElementPtr localVideoSink = constructVideoSink();
        QGst::ElementPtr localVideoSink = d->qmlUi->getVideoPreviewSink();
        if (localVideoSink) {
            //d->ui.videoPreviewWidget->setVideoSink(localVideoSink);
            //d->videoContentHandler->linkVideoPreviewSink(localVideoSink);
            d->videoContentHandler->linkVideoPreviewSink(localVideoSink );
        }

3.) El vídeo tampoco está stacked:

    if (newState == NoVideo) {
        //d->ui.callStackedWidget->setCurrentIndex(0);
        d->qmlUi->showVideo(false);

 

Y más, os recomiendo que os bajéis el código y lo miréis un poco mejor comparando con el original y veréis como la estructura del programa se mantiene casi idéntica.

Y eso es todo. Es tedioso pero es lo que hay que hacer.

🙂

Anuncios

3 pensamientos en “Sustituyendo la interfaz gráfica por QML (parte III)

  1. Sustituyendo la interfaz gráfica por QML (parte II) – Mi PFC

  2. Te sigo compi, buen blog, muy didáctico.
    Estoy también con QML y QT experimentando y aprendiendo, grandes los improvements a telepathy 😉
    Una pregunta, te basas en algún guideline para el diseño de la interfaz?

    • En este caso seguí una maqueta que me pasó David Edmunson de unas pruebas que había hecho él, pero lo demás es cosa mía.
      Gracias por el comentario!

Responder

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