Este es uno de los capítulos del tutorial Desarrollar una aplicación para Ubuntu Phone OS. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.
Superado la primera parte, «Desarrollando mi primera aplicación para Ubuntu Phone OS (I)«, que se centraba básicamente en la instalación de las herramientas necesarias para el desarrollo de aplicaciones para Ubuntu Phone OS y en el diseño del primer interfaz; en este segundo artículo, quiero centrarme en explicar con detalle los diferentes objetos que constituyen el diseño del artículo anterior, y algunas características propias de los componentes del SDK de Ubuntu.
Desgranando la aplicación
El primer paso va a ser ir «desgranando» la interfaz gráfica que hicimos el otro día. Para ello, voy a revisar los diferentes objetos que van apareciendo y a describir someramente cada uno de ellos. Empezamos por las primeras líneas de código:
Rectangle { id: root width: units.gu(60) height: units.gu(30) /*color: "lightgray"*/ property real margins: units.gu(2) property real buttonWidth: units.gu(9)
Item
Aunque no aparece en el código, empiezo por esta, porque es el objeto visual más básico de QtQuick, y del que heredan muchos de los objetos visuales. Para aquellos que no sabéis mucho de programación o que os quedasteis en aquel lejano «basic», indicar que la herencia es una interesante cualidad de la programación orientada a objetos, que permite que los objetos derivados tengan las características del padre (además de aquellas nuevas que queramos definirles,claro)
EL objeto Item tiene diferentes propiedades que puedes consultar en Item, sin embargo, me quiero centrar en algunas que utilizaremos de forma masiva, y es interesante tener en mente.
anchors
Esta propiedad o grupo de propiedades, nos permite definir la posición del Item respecto de otros, o de su padre. Por ejemplo, definimos dos rectangulos (está feo utilizarlo sin haberlo presentado, pero es lo más gráfico), y la posición de uno de ellos la indicamos con coordenadas, y la del otro rectángulo mediente «anchors», para indicar que «test2» está a la derecha de «test1» (anchors.left: test1.right), y que coinciden sus verticalmente sus centros (anchors.verticalCenter: test1.verticalCenter). Así
import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(60) height: units.gu(30) /*color: "lightgray"*/ Rectangle{ id: test1 x:units.gu(10) y:units.gu(10) width: units.gu(10) height: units.gu(10) color: "red" } Rectangle{ id: test2 width: units.gu(10) height: units.gu(10) anchors.left: test1.right anchors.verticalCenter: test1.verticalCenter color: "blue" } }
Y el resultado sería algo como:
O incluso podíamos haber centrado nuestro primer rectángulo fácilmente utilizando:
Rectangle{ id: test1 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: units.gu(10) height: units.gu(10) color: "red" }
Con el siguiente resultado:
Como puedes ver la ventaja es que no tienes que definir nuevamente la posición de test2, puesto que sigue en la misma posición relativa respecto a test1. Desde luego, que esto puede no tener fin, poniendo ejemplos. Lo mas sencillo es que hagas diferentes pruebas jugando con todas las posibilidades que permite anchors, incluido anchors.leftMargin, etc y también con la posición relativa z, que te permitirá definir quien está encima de quien, de otra manera, el ultimo definido es el que estará encima de los demás:
import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(60) height: units.gu(30) /*color: "lightgray"*/ Rectangle{ id: test1 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: units.gu(10) height: units.gu(10) color: "red" z: 1 } Rectangle{ id: test2 width: units.gu(10) height: units.gu(10) anchors.left: test1.right anchors.top: test1.top anchors.leftMargin: units.gu(-1) anchors.topMargin: units.gu(1) color: "blue" } }
y su resultado:
¿Que es eso de units.gu?
Esto nos permite definir unidades de medida que son (aproximadamente) independientes del equipo que se utilice, así:
- En la mayoría de los ordenadores 1 gu = 8 px
- Para equipos con Retina 1 gu = 16 px
- Para teléfonos móviles 1 gu = 18 px
De esta forma nos podemos (casi) despreocupar de que aspecto tendrá nuestra aplicación en los diferentes equipos que podamos utilizar.
Rectangle
Nos permite definir un rectángulo con un color de fondo, y un borde, incluyendo el redondeado del borde y su color, e incorporando los gradientes. Así nuestro Rectangle «test1», puede llegar a tener el siguiente aspecto:
Para ello tenemos que definirlo de la siguiente forma:
Rectangle{ id: test1 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: units.gu(10) height: units.gu(10) z: 1 opacity: 0.5 rotation: 30 antialiasing: true /*Las opciones de Rectangle*/ border.color: "red" border.width: units.gu(1) radius: units.gu(3) gradient: Gradient { GradientStop { position: 0.0; color: "darkgreen" } GradientStop { position: 1.0; color: "lime" } } }
Además de las nuevas propiedades de Rectangle, que están indicadas, he añadido «z» (que indica quien está encima de quien), «opacity» para permitir hacer un Item transparente, y «rotation», que nos permite girar el Item. En cuanto a rectangle, puedes ver las propiedades respecto al borde (tanto ancho como color), «radius» que te permite redondear tu rectángulo y «gradient» para definir un gradiente, que siempre va de la parte superior a la inferior, con lo que si quieres cambiarlo de dirección, tendrás que girar el objeto.
Label
Hereda entre otros de Text, y permite escribir texto. Ejemplo:
Label { id: title font.family: "Arial" font.pixelSize: units.gu(6) text: "Ubuntu" color: "red" anchors { verticalCenter: test1.verticalCenter horizontalCenter: test1.horizontalCenter } rotation: 45 opacity: 0.5 }
Con un resultado como éste:
De entre las diferentes propiedades de Text, que como indico es de donde hereda Label, existen dos muy interesantes, contentHeight y contentWidth, que nos indican el alto y ancho, respectivamente del texto. No me quiero extender en las propiedades de Text, pero si que es interesante jugar con ellas para ver los diferentes resultados y todo lo que podemos hacer.
TextField
Es el objeto que permite al usuario introducir texto y números. En este caso, TextField, al igual que Label corresponden al Toolkit de Ubuntu, aunque heredan de QtQuick. Algunas de las posibilidades con TextField, las puedes ver en el siguiente ejemplo (prácticamente autoexplicativo):
import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(60) height: units.gu(30) /*color: "lightgray"*/ TextField { id: text1 anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter placeholderText: "Haz clic aquí" } TextField { id: text2 anchors.top: text1.bottom anchors.horizontalCenter: parent.horizontalCenter placeholderText: "Sin botón para limpiar" hasClearButton: false } TextField { id: text3 anchors.top: text2.bottom anchors.horizontalCenter: parent.horizontalCenter placeholderText: "Introduce tu contraseña" echoMode: TextInput.Password } TextField { id: text4 anchors.top: text3.bottom anchors.horizontalCenter: parent.horizontalCenter placeholderText: "De solo lectura" readOnly: true } TextField { id: text5 errorHighlight: false anchors.top: text4.bottom anchors.horizontalCenter: parent.horizontalCenter inputMask:'99.999.999-A;_' } TextField { errorHighlight: false id: text6 anchors.top: text5.bottom anchors.horizontalCenter: parent.horizontalCenter placeholderText: "Longitud limitada" maximumLength:10 } }
Button
Con este objeto permitiremos al usuario que interactué con la aplicación. Al igual que los anteriores, también es un objeto perteneciente al toolkit de Ubuntu, y puedes ver alguna de sus características en el siguiente ejemplo:
import QtQuick 2.0 import Ubuntu.Components 0.1 Rectangle { id: root width: units.gu(60) height: units.gu(30) color: "palegoldenrod" Column { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter spacing: units.gu(3) Button { width: units.gu(30) text: "Haz clic aquí" onClicked: print("Has pulsado el primer botón") } Button { width: units.gu(30) iconSource: "icon.png" color: "green" onClicked: print("Has pulsado el segundo botón") rotation: 15 antialiasing: true z: 1 } Button { width: units.gu(30) iconSource: "icon.png" text: "Un icono a la izquierda" iconPosition: "left" onClicked: print("Has pulsado el tercer botón") onPressAndHold: print('Mantienes pulsado el tercer botón') } } }
y que da como resultado:
De este ejemplo, quiero destacar el uso de Column, que es un objeto de QtQuick, que nos permite poner diferentes objetos en forma de columna, y la posibilidad de introducir imágenes dentro de los botónes con tan solo indicar la dirección. Para utilizar la imagen tiene que estar en el mismo directorio que el archivo «qml» o bien referida a el de forma relativa.
Conclusiones
En este artículo hemos realizado un repaso de los diferentes objetos disponibles para desarrollar nuestras aplicaciones, como se comportan y como trabajar con ellos. El siguiente paso, que veremos en el próximo artículo, tratará directamente con la programación de eventos mediante Javascript, que nos permitrá interactuar entre los distintos objetos de nuestra interfaz y el usuario.
Que bien explicado. Muchas gracias.
Esta muy bien… pero cuando es en HTML/CSS/Javascript … como es??