Tag browsing: QML

Ubuntu for phones

January 2nd, 2013

Ubuntu for phones

Hoy en Londres, Mark Shuttleworth ha presentado en sociedad Ubuntu for phones, la gente de Canonical ha tomado el mismo camino que Firefox OS, están usando un kernel Android personalizado para poder utilizar todos los drivers existentes en esa plataforma y permitirles a los actuales fabricantes comenzar a integrar Ubuntu for phones en sus actuales y futuros productos sin tener que hacer grandes inversiones de tiempo y dinero.

La versión actual de pruebas de Ubuntu for phones corre en un Galaxy Nexus y una imagen e instrucciones serán liberadas dentro de algunas semanas para que desarrolladores puedan comenzar a conocer y trabajar en la plataforma, ya sea usando HTML5 o el entorno nativo basado en Qt5 y QML.

A continuación pueden ver un video en donde Mark Shuttleworth explica su visión y la propuesta de Canonical, tanto para los fabricantes, desarrolladores como usuarios finales, también pueden ver a partir del minuto 5, la interfaz de usuario y su funcionamiento, que por cierto tiene muchos puntos interesantes, algunos novedosos y otros que son una reinterpretación, pero con mejoras, de funciones y características presentes en otros OSs, lamentablemente tendremos que esperar hasta 2014 para poder ver los primeros Ubuntu phones en la calle, una espera demasiado larga para mi gusto, esperemos que la gente de Canonical sume apoyos y pueda acortar los plazos.

Announcements , , , , 1 response

Acceder a Nokia Maps desde QML

May 14th, 2012

Hoy encontré un link a mi blog desde este thread en Nokia Developer en donde preguntaban como abrir la aplicación Nokia Maps (ex Ovi Maps) con unas coordenadas especificas desde una app Qt, hacer esto desde QML es muy fácil, solo debemos usar el método openUrlExternally del objeto Qt de la siguiente manera:

MeeGo
Qt.openUrlExternally("geo:-34.603611,-58.381667")
Symbian
Qt.openUrlExternally("http://m.ovi.me/?c=-34.603611,-58.381667")

Ademas de poder abrir Nokia Maps en una ubicación precisa, con openUrlExternally también es posible, hacer llamados telefónicos, enviar SMSs, emails, abrir una dirección web en el navegador nativo y algunas otras cosas mas, pueden ver algunos ejemplos de esto y su implementación en esta entrada en la wiki de Nokia Developer

Development , , , , No response

Intro a QJson

May 11th, 2012

Hace unos días navegando por los proyectos públicos en Nokia Developer, me tope con un fork de QJson que incluye ciertas modificaciones para poder integrar QJson de forma mas natural con QML, antes ya había escrito como consumir JSON con QML, pero usar esta versión de QJson es mucho mas simple y eficiente.

Para empezar, lo primero que hay que hacer es bajar el proyecto y copiarlo en una carpeta con nombre el QJson en la carpeta raíz de nuestro proyecto.

Luego en el .pro de nuestro proyecto debemos hace un include al .pri de QJson.

include(./QJson/json.pri)

También en el .pro hay que declarar que vamos a usar la función network.

QT += network

En el main.cpp de nuestra app solo hay que crear los includes para QtDeclarative y para QJson y registrar el Type.

#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"

#include <QtDeclarative>
#include "QJson/qjson.h"

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));

    qmlRegisterType<QJson>("QJson", 1, 0, "QJson");

    QmlApplicationViewer viewer;
    viewer.setMainQmlFile(QLatin1String("qml/QColor/main.qml"));
    viewer.showExpanded();

    return app->exec();
}

En la parte QML empezamos agregando un import a QJson, luego crearemos un objeto QJSon y por ultimo vamos a declarar que cuando se dispare el evento Component.onCompleted se le asignara la url a parsear al objeto QJson y luego iteraremos la data resultante de la consulta he iremos asignando lo valores obtenidos a los campos correspondientes del modelo.

import QtQuick 1.1
import QJson 1.0
import com.nokia.symbian 1.1

Page {
    id: mainPage

    ListModel {
        id:colorsModel
    }

    Component {
        id:colorsDelegate
        ListItem {
            height: 100
            Image {
                id:icon
                smooth: true
                width: parent.width
                height: parent.height
                source: imageUrl
                Rectangle {
                    width:parent.width
                    height: 28
                    color:"#000"
                    anchors.bottom: parent.bottom
                    anchors.bottomMargin: 0
                    opacity: 0.750
                    ListItemText {
                        role: "SubTitle"
                        text:title +" by " + userName
                        horizontalAlignment: Text.AlignHCenter
                    }
                }
            }
        }
    }

    ListView {
        anchors.fill: parent
        model: colorsModel
        delegate: colorsDelegate
    }

    QJson {
        id: json
        onError: {
            console.log("line:"+line)
            console.log("message:"+message)
        }
    }

    Component.onCompleted: {
        var data = json.parse("http://www.colourlovers.com/api/palettes/new&format=json")

        for(var p in data){
            colorsModel.append({
                                   "title"   : data[p]["title"]
                                   ,"userName"  : data[p]["userName"]
                                   ,"imageUrl": data[p]["imageUrl"]
                               })
        }
    }
}

Para este ejemplo use el API de ColorLovers para poder consultar las ultimas paletas que se han agregado a su DB, el resultado de este pequeño ejemplo pueden apreciarlo en la siguiente imagen.

QColor Demo

Development , , , , 4 responses

[Actualizado] Qt Developer Guides

November 29th, 2011

Hace unos días en el blog oficial de Qt anunciaron el lanzamiento de las nuevas Qt Developer Guides, no quería escribir sobre estas guiás sin antes darles una mirada en profundidad, las guiás son muy completas, están dividas en varios capítulos en donde se abordan diferentes conceptos y funcionalidades, los cuales son aplicados en el desarrollo de una aplicación de ejemplo a lo largo de toda la guiá.

Las dos primeras guiás liberadas se centran en el desarrollo usando Qt Quick y JavaScript, tanto para Symbian (aunque todo lo explicado puede ser aplicado en MeeGo) como para Desktop, con estas guiás pueden aprender sobre el uso de Qt Quick Components, Animations, Transitions, States, persistencia de datos usando Offline Storage, creación de controles personalizados y mucho mas.

Si recién están empezando a trabajar con Qt y con Qt Quick, les recomiendo que lean y hagan los ejercicios que vienen en estas guiás, son una forma rápida de experimentar todo el proceso de desarrollo de una aplicación y van a aprender fácilmente, conceptos, buenas practicas y la forma de aplicarlos en sus propios desarrollos.

Programming with Qt Quick for Symbian^3 Devices

Pueden descargar esta guiá en los siguientes formatos:

Si se topan con algún error o tienen sugerencias, pueden dejarlas aquí

Qt Quick Application Developer Guide for Desktop

Pueden descargar esta guiá en los siguientes formatos:

Si tiene ideas, sugerencias o encuentran algún bug pueden reportarlo aquí

Espero estas guiás les sean útiles y manténganse atentos que pronto se vienen muchas mas.

Programming with Qt Quick for Symbian^3 Devices

Actualización – 13/12/2011

La guiá Programming with Qt Quick for Symbian^3 Devices ha sido actualizada hoy, ha pasado a llamarse Programming with Qt Quick for Symbian and MeeGo Harmattan Devices y se le ha agregado todo un nuevo capitulo con consejos y buenas practicas para portar aplicaciones Symbian a MeeGo.

Actualización – 12/01/2012

La gente de Zona Qt ha traducido al español la guiá Programming with Qt Quick for Symbian and MeeGo Harmattan Devices, pueden acceder a ella desde aquí.

Development , , , , 1 response

[Actualizado] Integrando Mapas con QML

November 14th, 2011

El objetivo de este post es mostrarles de forma practica, un par de opciones para que puedan integrar mapas en sus aplicaciones Qt, tanto en Symbian como en MeeGo, la primera opción hace uso de la Location API incluida en QtMobility, la segunda opción permite integrar servicios como Google Maps, Bing Map o Nokia Maps (ex Ovi Maps) haciendo uso de QtWebKit.

Usted esta aquí

Las opciones que describo en este post permiten ubicar en el mapa un punto especifico, este punto lo podemos obtener de diversas maneras, desde una DB, ingresando los datos manualmente u obteniendo las coordenadas desde el GPS del dispositivo, para hacer esto ultimo solo debemos primero, agregar a nuestro proyecto la dependencia a la Location API de QtMobility

import QtMobility.location 1.2

Luego vamos a declarar unas propiedades en las cuales almacenaremos la longitud y la latitud que obtendremos usando el elemento PositionSource, para luego mostrarlos usando un elemento Text.

property double mapLat
property double mapLong
mapLat: positionSource.position.coordinate.latitude
mapLong: positionSource.position.coordinate.longitude

PositionSource {
    id: positionSource
    active: true
    updateInterval: 1000
}

Text {
    color:"#fff"
    text: "Latitud: " + mapLat + "<br/>" + "Longitud: " + mapLong
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.verticalCenter: parent.verticalCenter
}

QML & Maps - Get Position Demo

Simulando el GPS

Si no cuentan con un dispositivo para probar, pueden simular el uso del GPS usando la opciones de Location que vienen incluidas en Qt Simulator.

QML & Maps - Qt Simulator

QtMobility Location API

Esta opción hace uso de algunos de los elementos QML que nos provee la Location API, en este ejemplo usaremos un elemento Coordinate, para almacenar la latitud y la longitud que obtenemos del PositionSource, luego crearemos un elemento Map, el cual a su vez contiene una MapImage, tanto la propiedad center del Map, como la propiedad coordinate del MapImage van a usar los datos de la Coordinate previamente declarada.

property double mapLat
property double mapLong
mapLat: positionSource.position.coordinate.latitude
mapLong: positionSource.position.coordinate.longitude

PositionSource {
    id: positionSource
    active: true
    updateInterval: 1000
}

Coordinate { 
    id: defaultMapCenter
    latitude: mapLat
    longitude: mapLong
}

Map {
    id: map
    anchors.fill: parent
    plugin : Plugin {name : "nokia"}
    size.width: parent.width
    size.height: parent.height
    zoomLevel: 16
    center: defaultMapCenter

    MapImage {
        id : pin
        coordinate: defaultMapCenter
        source:"images/pin.png"
    }
}

QML & Maps - Qt Mobility Sample

QtWebKit y Nokia Maps

Esta opción quizás no se integra de forma 100% nativa de la misma manera que podemos hacer usando la Location API, pero tiene la ventaja de que podemos usar a nuestro proveedor preferido y ademas nos permite reutilizar código que hayamos creado con anterioridad, este ejemplo hace uso de la API de Nokia Maps y para comenzar crearemos una pagina web con el siguiente código (ver abajo) y la incluiremos en nuestro proyecto, el código en si no tiene mucha magia, al principio hay una referencia a la librería de Nokia Maps, luego inicializamos el mapa, configuramos los elementos que vamos a utilizar en el, el nivel de zoom, una posición por default y finalmente crearemos la función setLocation que sera la encargada de ubicar el pin y centrar el mapa usando las coordenadas obtenidas por el PositionSource

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Ovi Maps</title>
<script src="http://api.maps.ovi.com/jsl.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
    var map;
    function initialize() {
        map = new ovi.mapsapi.map.Display(document.getElementById("map"), {
        components: [
            new ovi.mapsapi.map.component.ZoomBar(),
            new ovi.mapsapi.map.component.Overview(),
            new ovi.mapsapi.map.component.TypeSelector()],
            'zoomLevel':16,
            'center':[-34.603000, -58.380000]
        });
        
        ovi.mapsapi.util.ApplicationContext.set("defaultLanguage", "es-ES")
        map.addComponent(new ovi.mapsapi.map.component.panning.Drag());
        map.addComponent(new ovi.mapsapi.map.component.panning.Kinetic());
    }

    function setLocation(lat, lon) {
        pin = new ovi.mapsapi.map.Marker([lat, lon], { icon: "images/pin.png" }),
        map.objects.add(pin);
        map.setCenter(new ovi.mapsapi.geo.Coordinate(lat,lon));
    }
</script>
</head>
<body onload="initialize()">
    <div id="map"></div>
</body>
</html>

Del lado del QML, lo primero que haremos sera importar a QtWebKit como dependencia.

import QtWebKit 1.0

Luego crearemos una WebView que va a cargar la pagina web anteriormente creada.

Solo resta esperar que se dispare el evento onLoadFinished que ejecutara la función updatePosition que usando el metodo evaluateJavaScript le pasara a la función setLocation que se encuentra en la pagina web, los parámetros que necesita para centrar y ubicar el pin en el mapa.

property double mapLat
property double mapLong
mapLat: positionSource.position.coordinate.latitude
mapLong: positionSource.position.coordinate.longitude

PositionSource {
    id: positionSource
    active: true
    updateInterval: 1000
}

function updatePosition(mapLat, mapLong){
    mapView.evaluateJavaScript("setLocation("+mapLat+","+mapLong+");");
}

WebView {
    id: mapView
    url: "map.html"
    preferredWidth: parent.width
    preferredHeight: parent.height
    scale: 1
    onLoadFinished: {
        updatePosition(mapLat, mapLong);
    }
}

QML & Maps - QtWebKit + Nokia Maps Sample

Algunas consideraciones

Todos los ejemplos descriptos anteriormente son básicos, no intenten usarlos directamente en aplicaciones reales sin antes crear cierta lógica para manejar los fallos y demoras que acompañan siempre a las aplicaciones que dependen del uso del GPS.

¿Cual opción usar?

Mas allá de las ventajas antes descriptas, como por ejemplo, la flexibilidad de proveedores, la reutilización de código o la integración de forma nativa, hay un punto muy importante que deben tener en cuenta a la hora de decidir que camino seguir, este punto es la performance, mi experiencia me ha demostrado que la Location API no tiene un buen rendimiento cuando es usada en Symbian si lo comparamos con MeeGo, el obtener los datos del GPS puede demorar bastante, desde mínimo 5 segundos hasta 30 segundos o mas, en cambio en MeeGo este proceso es casi instantáneo, esto en parte se puede subsanar en Symbian usando un BusyIndicator y pidiendo paciencia al usuario, esta lentitud también se ve reflejada a la hora de cargar el Map, el cual puede tardar entre 5 y 10 segundos en completar su tarea en Symbian, todo lo contrario en MeeGo, en el cual la carga es casi inmediata usando WiFi y demorando no mas de 2 segundos si usamos 3G, es por ello que la opción QtWebKit + Nokia Maps puede llegar a ser útil en algunos casos, ya que su performance no es deslumbrante pero si un poco mejor que la que proporciona la Location API en Symbian, ademas de que es mas consistente y regular en los tiempos de carga del mapa, lo que ayuda a que su rendimiento sea mas predecible.

El porque de esta diferencia de performance de la Location API entre Symbian y MeeGo no he podido dilucidarlo aun, puede ser la diferencia de velocidad entre los dispositivos (N8/C7 680Mhz vs. N9/N950 1Gz ) o una falta de optimización en la versión para Symbian, por mientras pueden usar alguna de las opciones antes detalladas según el caso de uso que quieran resolver.

Actualización – 15/11/2011

Hoy luego de algunas pruebas usando Qt Mobility 1.2.1, versión que esta incluida en el nuevo Qt SDK 1.1.4, pude comprobar que la performance de la versión para Symbian de la Location API ha mejorado bastante, no esta al nivel de la versión para MeeGo aun, pero entra en el terreno de lo usable.

Development , , , , , , No response