el tutorial del desarrollo visual

38
El tutorial del desarrollo visual Antonio Larrosa Jiménez Traductor: Miguel Revilla Rodríguez Revision 1.00.01 (2003-12-27) Copyright © 2003 Antonio Larrosa Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". Visual Tutorial es un tutorial que mostrará al lector la forma de crear aplicaciones visualmente utilizando KDevelop y Qt Designer. Crearemos una aplicación que nos permitirá abrir una imagen y teñirla de diferentes colores. Posteriormente cambiaremos el interfaz para permitir al usuario seleccionar también la intensidad de un canal alfa. Table of Contents 1. Introducción 2. Cómo descargar e iniciar KDevelop y Designer Requisitos Cómo ejecutar KDevelop 3. Creación de la aplicación Creación de un nuevo proyecto Cómo compilar lo generado por KDevelop Comprensión de la estructura básica 4. Primeros cambios al código fuente Eliminación de las partes que no utilizaremos 5. Uso del diseñador Cómo añadir un archivo .ui Uso del diseñador Integración del diseñador con KDevelop 6. Cómo hacer que el widget generado por el diseñador funcione Añadir nombres, slots y conexiones Implementación de los slots 7. Eliminación del parpadeo utilizando un temporizador 8. Carga y manipulación de un mapa de pixels Carga de un mapa de pixels Mezcla de colores 9. Modificación del interfaz de usuario existente Añadir el deslizador de alfa Añadir el botón de selección de color 10. Añadir las implementaciones de los nuevos métodos Soporte para el deslizador alfa Soporte para el botón de color

Upload: aprender-libre

Post on 07-Apr-2018

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 1/38

El tutorial del desarrollo visual

Antonio Larrosa Jiménez

Traductor: Miguel Revilla RodríguezRevision 1.00.01 (2003-12-27)

Copyright © 2003 Antonio Larrosa

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU

Free Documentation License, Version 1.1 or any later version published by the Free Software

Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A

copy of the license is included in the section entitled "GNU Free Documentation License".

Visual Tutorial es un tutorial que mostrará al lector la forma de crear aplicaciones visualmente

utilizando KDevelop y Qt Designer. Crearemos una aplicación que nos permitirá abrir una imagen y

teñirla de diferentes colores. Posteriormente cambiaremos el interfaz para permitir al usuario

seleccionar también la intensidad de un canal alfa.

Table of Contents

1. Introducción

2. Cómo descargar e iniciar KDevelop y Designer

Requisitos

Cómo ejecutar KDevelop

3. Creación de la aplicación

Creación de un nuevo proyecto

Cómo compilar lo generado por KDevelop

Comprensión de la estructura básica

4. Primeros cambios al código fuente

Eliminación de las partes que no utilizaremos

5. Uso del diseñador

Cómo añadir un archivo .ui

Uso del diseñador

Integración del diseñador con KDevelop

6. Cómo hacer que el widget generado por el diseñador funcione

Añadir nombres, slots y conexiones

Implementación de los slots

7. Eliminación del parpadeo utilizando un temporizador

8. Carga y manipulación de un mapa de pixels

Carga de un mapa de pixels

Mezcla de colores

9. Modificación del interfaz de usuario existente

Añadir el deslizador de alfa

Añadir el botón de selección de color

10. Añadir las implementaciones de los nuevos métodos

Soporte para el deslizador alfa

Soporte para el botón de color

Page 2: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 2/38

11. Algunos cambios aquí y allá

Corrección del botón de color.

Corrección de mapa de pixels inicial

12. Añadir más características

Posibilidad de guardar el resultadoAñadir soporte para arratrar y soltar

A. Créditos y licencia

Chapter 1. Introducción

Visual Tutorial es un tutorial que mostrará al lector la forma de crear aplicaciones visualmente

utilizando KDevelop y Qt Designer. Crearemos una aplicación que nos permitirá abrir una imagen y

teñirla de diferentes colores. Posteriormente cambiaremos el interfaz para permitir al usuario

seleccionar también la intensidad de un canal alfa.

Este tutorial complementa mi otro trabajo sobre desarrollo en KDE, que puede encontrar endeveloper.kde.org. Además hay otro excelente tutorial sobre KDevelop y Designer, realizado por

Anne-Marie Mahfouf que se encuentra en women.kde.org. Sobre el orden en el que se deberían leer

los tutoriales mencionados y estos otros, yo únicamente diré una cosa: cuantos más lea, mejor :), y si

también consulta la documentación de las clases que utiliza, mejor que mejor.

Si desea descargar el código de este tutorial junto a la documentación y demás elementos, puede

hacerlo en la página web. Puede seguir este tutorial haciendolo todo usted mismo de la forma que se

indica, o puede descargar cada paso del tutorial de esa página. En el segundo caso, obtendrá cada paso

en un directorio diferente y tendrá que abrir diferentes proyectos de KDevelop para cada uno de ellos.

¿Listo? Vamos a empezar.

Chapter 2. Cómo descargar e iniciar KDevelop y Designer

Requisitos

En este tutorial necesitaremos, además del compilador, alguna otra aplicación como KDevelop o

Qt/Designer. Se dará cuenta de que KDevelop tiene una lista de requisitos y/o aplicaciones

recomendadas, así es que posible que también tenga que instalar esas.

Puede descargar KDevelop de www.kdevelop.org y muy probablemente su distribución incluya

Qt/Designer en algún paquete, normalmente denominado qt-devel, qt3-devel o qt-designer. Si no loencuentra, puede descargarlo de trolltech.com

Necesitará KDE 3.x, lo que significa que también le hará falta Qt 3.x. La última versión estable de

KDevelop en el momento de redacción de este texto es la 2.1.5, mientras que la versión de desarrollo

de KDevelop 3.0 (con nombre clave gideon) se encuentra en estado alpha3. Este documento trata

mayormente sobre gideon, pero también se puede utilizar como referencia en el manejo de KDevelop

2.1.5.

Page 3: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 3/38

Cómo ejecutar KDevelop

Una vez que haya instalado todos los paquetes, puede iniciar gideon (kdevelop) desde el menú K o

desde una ventana de konsole. Es necesario configurar elementos básicos (como la ubicación de la

documentación, etc.). Para hacerlo, basta con que siga las instrucciones en pantalla.

Una vez terminada la configuración, podrá ver una ventana similar a esta:

Ahora ya estamos listos para desarrollar una aplicación.

Chapter 3. Creación de la aplicación

Creación de un nuevo proyecto

Ahora vamos a crear un nuevo proyecto para nuestra aplicación. Para hacerlo, seleccionamos

Proyecto/Nuevo proyecto. Se abrirá un asistente en el que seleccionaremos las opciones del proyecto.

Page 4: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 4/38

Podemos utilizar KDevelop para desarrollar en C++, C, Java, Python o PHP. El asistente de "nuevo

proyecto" se puede utilizar para crear una aplicación sencilla que sirve como estructura de base para la

aplicación final. Si decide crear una aplicación C++, puede generar (en el momento de redacción de

este tutorial): una aplicación de KDE, una aplicación de KDE que utilice KParts, un módulo del

Centro de control, un servicio DCOP, un salvapantallas, una extensión KHTMLPart, un esclavo KIO

(implementación de un protocolo), un módulo de KOffice, una extensión de Kate, un applet de Kicker,

una extensión del panel de navegación de Konqueror, una aplicación KDE sencilla, un módulo de

KDevelop, varios tipos de aplicaciones Qt y una aplicación para terminal basada en C++.

Si decide crear una aplicación en C, KDevelop podrá generar la estructura para una aplicación para

GameBoyAdvance, una aplicación GNOME (sí, es posible utilizar KDevelop para crear aplicaciones

para GNOME), o símplemente una aplicación para terminal basada en C.

Page 5: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 5/38

Si prefiere utilizar Java, KDevelop podrá ayudarle con las estructuras de un proyecto de Ant, una

aplicación de KDE o una extensión de KDevelop, todas ellas con Java (incluso podrá utilizar el

depurador de aplicaciones Java integrado). Por último, también puede utilizar el asistente para crear un

simple guión de PHP, una aplicación Python Qt o un sencillo guión de Python.

Al pinchar en el botón Siguiente, se mostrarán las opciones sobre el sistema de control de versiones

que utilizaremos en el proyecto. Para simplificar nuestro ejemplo, seleccionaremos Ninguno y

continuaremos en las siguientes páginas, donde podremos cambiar la plantilla de la cabecera de los

archivos .h y .cpp. Fíjese en que KDevelop ha utilizado el año actual, su nombre y su dirección de

correo electrónico completos, por lo que probablemente no necesitará modificar nada. Al menos

nosotros no modificaremos nada, así que bastará con pinchar en el botón Finalizar.

Ahora KDevelop generará el proyecto, y estaremos listos para comenzar a desarrollar nuestra

aplicación sobre la estructura básica.

La siguiente instantánea muestra una ventana vacía de KDevelop con el interfaz IDEAL. Puede

cambiar el interfaz de usuario y poner alguno de los modos clásicos a través del menúPreferencias/Configurar Gideon, en la sección Interfaz de usuario, pero en este tutorial utilizaremos el

interfaz IDEAL. Tenga en cuenta que las características de KDevelop son independientes del interfaz

que se utilice, así que puede seleccionar aquel en el que se encuentre más cómodo.

Cómo compilar lo generado por KDevelop

Ahora que ya está hecha una buena parte de la aplicación, vamos a compilarla. Pinche en

Construir/Construir proyecto, tras una corta espera (y en el caso de que no se produzca ningún error

debido a la falta de alguno de los paquetes necesarios), obtendrá una aplicación compilada que podrá

ejecutar por medio de Construir/Ejecutar progama, de forma similar a lo mostrado en la siguiente

instantánea.

Page 6: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 6/38

La aplicación también tiene los menús estándar, y un díalogo de preferencias preparado para que añada

las opciones que considere oportuno. Algo parecido a esto:

Comprensión de la estructura básica

Vamos a revisar ahora el código utilizado por KDevelop. Pinche en la etiqueta Clases que podrá

encontrar a la izquierda para abrir la lista de clases de nuestro proyecto.

Page 7: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 7/38

Puede ver que nuestro proyecto tiene 5 clases, TheTinter (que hereda de KMainWindow),

TheTinterView (que es el widget central de la aplicación donde se mostrarán nuestros

documentos), TheTinterPreferences (el diálogo de preferencias), y

TheTinterPrefPageOne y TheTinterPrefPageTwo (que son dos páginas de configuraciónpara diferentes opciones del diálogo de preferencias).

En primer lugar, vamos a echar un vistazo a la clase TheTinter. Esta clase es la ventana principal

de nuestra aplicación y contiene el menú, las barras de herramientas, etc. TheTinter contiene

algunos métodos interesantes que sin duda utilizaremos:

load(const KURL &url) es el método al que se llamará cuando el usuario quiera cargar un

documento. Tenga en cuenta que en KDE se recomienda utilizar la clase KURL para almacenar la

url de un documento. De esta forma, no nos preocupará si el documento es local, está en un

servidor ftp, si se accede por ssh, etc. La biblioteca KIO se ocupará de todo.

readProperties(KConfig *) y saveProperties(KConfig *) se utilizan paracargar y guardar el estado de la aplicación (por ejemplo, los documentos cargados) cuando se

abre o se cierra la sesión de KDE. De esa forma, los usuarios podrán cerrar la sesión y, cuando

vuelvan a acceder al sistema, encontrarán la aplicación en el mismo estado en que la dejaron.

setupActions() se utiliza para crear las acciones y conectarlas con nuestros slots (si no le

resultan familiares conceptos como señales o slots, puede consultar la documentación de Qt o mi

otro tutorial). Tenga en cuenta que la mayoría de las acciones utilizadas en la aplicación de

plantilla son estándar, de forma que el método contiene código del tipo

KStdAction::open(this, SLOT(fileOpen()), actionCollection()); con el

fin de crear una acción estándar para la entrada de menú Archivo/Abrir que, al ser activada, emite

una señal que se conecta a nuestro slot fileOpen.

Page 8: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 8/38

dragEnterEvent(QDragEnterEvent *event) se utiliza para indicarle al subsistema de

arrastrar y soltar si aceptamos o no un evento de arrastrar y soltar que el usuario está arrastrando

(todavía no soltando) sobre nuestra ventana, mientras que se llama

adropEvent(QDropEvent *event) cuando el usuario suelta algo sobre nuestra ventana,

por lo que es ahí donde debemos procesar el evento de soltar.

TheTinterView es el widget central de nuestra aplicación, es decir, el widget que se coloca debajo

de la barra de herramientas y sobre la barra de estado. En la plantilla de KDevelop, esta clase crea un

componente KPart capaz de leer documentos HTML, pero eliminaremos la mayor parte de esto en el

siguiente paso del tutorial, ya que no nos resulta necesaria tanta complejidad.

Chapter 4. Primeros cambios al código fuente

Eliminación de las partes que no utilizaremos

Lo primero que haremos será eliminar el código que no resulte necesario para nuestra aplicación. Porejemplo, no utilizaremos el comando de impresión, con lo que podemos quitar la linea #include

<kprinter.h> la inicialización de m_printer(0) en el constructor de TheTinter, la linea

KStdAction::print(this, SLOT(filePrint()), actionCollection()); que

añadía una acción estandar para imprimir, y la función TheTinter::filePrint, tanto del fichero

.cpp como del .h así como la variable m_printer de la misma clase y la función

TheTinterView::print .

Tampoco abriremos páginas HTML, con lo que podemos eliminar el código que busca una

componente para tal fin y la utiliza. Este código está en el constructor de TheTinterView, que será

suficiente con dejarlo con las tres primeras lineas: .

// setup our layout manager to automatically add our widgets

QHBoxLayout *top_layout = new QHBoxLayout(this);

top_layout->setAutoAdd(true);

Además, podemos eliminar la variable m_html y algunas funciones que ya no usaremos de

TheTinterView, como son signalChangeStatusbar, signalChangeCaption,

slotOnURL y slotSetTitle (recuerda eliminarlas tanto del .h como del .cpp). Al eliminar la

variable m_html, las funciones currentURL y openURL ya no compilarán, no te preocupes, pues

las vamos a reimplementar dentro de poco, simplemente déjalas vacías (o con un

return "";

en el caso de currentURL).

Como hemos eliminado las señales de TheTinterView, podemos también eliminar el código que

las conectaba en el constructor de TheTinter:

// allow the view to change the statusbar and caption

connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)),

this, SLOT(changeStatusbar(const QString&)));

connect(m_view, SIGNAL(signalChangeCaption(const QString&)),

this, SLOT(changeCaption(const QString&)));

Tampoco vamos a crear un nuevo documento, con lo que podemos eliminar la creación de la acción

estandar openNew con la llamada a KStdAction::openNew igual que hicimos con print, junto

con la función fileNew tanto del .h como del .cpp .

Page 9: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 9/38

Para terminar, podemos eliminar el siguiente trozo de código ya que como el comentario que lo

acompaña dice, no hace nada útil y está sólo para ilustrar como insertar un menú propio de nuestra

aplicación.

// this doesn’t do anything useful. it’s just here to illustrate

// how to insert a custom menu and menu item

KAction *custom = new KAction(i18n("Cus&tom Menuitem"), 0,

this, SLOT(optionsPreferences()),

actionCollection(), "custom_action");

El resultado es el paso 1, s1, del tutorial.

En primer lugar, hemos eliminado la mayor parte del constructor de TheTinterView, ya que no lo

vamos a utilizar para ver HTML. Además, hemos eliminado los métodos innecesarios de esa clase,

 junto con las señales y los slots. Si posteriormente necesitamos más señales o slots, los añadiremos

individualmente.

Chapter 5. Uso del diseñador

Cómo añadir un archivo .ui

En primer lugar, añadiremos un nuevo archivo .ui (interfaz de usuario) a nuestro proyecto. Los

archivos .ui se crean con el diseñador de Trolltech para generar interfaces de usuario para nuestra

aplicación. Para hacerlo, abra la pestaña Nuevo archivo en la parte izquierda, y seleccione Un nuevo

widget. El nombre del archivo que añadiremos es centralviewbase.ui.

Se le mostrará un diálogo en el que configurar el nuevo archivo que se ha añadido al proyecto

(utilizando el Gestor de automake). Seleccionaremos Añadir nuevos archivos a nuestro destino activo,

y a continuación marcaremos la casilla de la parte inferior para utilizar siempre el destino activo sin

necesidad de más preguntas.

Page 10: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 10/38

Esto abrirá una ventana del diseñador con un widget vacío, dispuesto para comenzar el diseño.

Page 11: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 11/38

Uso del diseñador

En este punto tenemos que diseñar el aspecto de nuestra aplicación. Haremos que la imagen aparezca

en la parte superior de la ventana, y habrá tres deslizadores en la parte inferior, para seleccionar los

componentes rojo, verde y azul del color con el que teñiremos el mapa de pixels. Así que nuestro

primer paso será seleccionar un Pixmap label (de la caja de herramientas Display) y crearlo de forma

que cubra la parte superior de nuestra ventana.

A continuación, añadiremos, en la parte de abajo, tres deslizadores y sus correspondientes etiquetas.

Page 12: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 12/38

Las etiquetas contendrán el texto Rojo:, Verde: y Azul:.

En el caso de que se esté preguntando por qué cada etiqueta aparece en el color indicado por su texto,

de diré que (obviamente) no es algo automático. Dejo como ejercicio para lector la búsqueda en los

menús del diálogo Edit Text de la forma de cambiar el color. Además, con la intención de embellecer

un poco el widget, he añadido un Marco (en la pestaña Containers) que contiene los deslizadores y las

etiquetas de texto.

Page 13: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 13/38

Como ya habrá notado, los elementos no han quedado correctamente alineados. Aunque usted crea que

puede hacerlo mejor que yo, compruebe el aspecto del resultado mediante la opción Preview Form en

el menú Preview y redimensione la ventana. Los elementos dentro de nuestro widget están colocados

en una posición fija y con un tamaño fijo. Está claro que esa no es nuestra intención, así que

añadiremos una disposición que se ocupará de la ubicación y el tamaño correctos de los elementos.

En primer lugar, pinche en el marco que contiene los deslizadores y las etiquetas, y pinche en el botón

Lay out in a grid (el que tiene una rejilla verde de 3x3). De esta forma se creará una disposición de

rejilla para el contenedor seleccionado actualmente. El resultado es:

Intente redimensionar el marco contenedor y comprobará que ahora los elementos tienen siempre su

posición y tamaño correctos.

Bien, la parte de los botones ya está prácticamente acabada, ahora debemos darnos cuenta de que en el

nivel más alto sólo hay dos elementos, el widget gráfico y el marco contenedor. Estos dos elementosdeben estar dispuestos verticalmente, así que pincharemos en una zona vacía del widget principal, y

seleccionaremos Lay out vertically en el menú (o el botón con tres rectángulos verdes apilados en la

barra de herramientas). El resultado es:

Page 14: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 14/38

Esta vez seguro que pensará que el resultado es extraño, ¿verdad? Bueno, en realidad no lo es. Ambos

elementos deben estar uno sobre el otro, pero el subsistema de disposición no tiene forma de saber cuál

de los elementos debe ocupar más espacio que el otro, así que los distribuye de forma proporcional.

Para solucionar esto, cambiaremos la política de tamaño del elemento gráfico, de forma que su tipo de

tamaño vertical sea MinimumExpanding. Vaya a la ventana del editor de propiedades, pinche en el

botón "más" a la izquierda de la propiedad sizePolicy y cambie la opción vSizeType a

MinimumExpanding. El resulta ahora es exactamente lo que buscábamos:

Page 15: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 15/38

Ya estamos preparados para volver a KDevelop y comerzar a utilizar esta clase. Pero, primero,

debemos darle un nombre. Pinche en Object Explorer del widget principal o en cualquier parte vacía

del mismo (cerca de los bordes suele haber un pequeño margen que puede utilizar). Después edite la

propiedad name y utilice algo como CentralViewBase.

El diseñador se utiliza normalmente para crear un widget que es la clase base de otra clase en la que se

sobrecargan los métodos importantes. Normalmente se utilizan dos esquemas de nomenclatura, llamar

a la clase base XXXBase y a la clase de implementación XXX o llamar a la clase base XXX y a la clase

de implementación XXXImpl. Prefiero la primera forma, así que esa es la que utilizaremos.

Integración del diseñador con KDevelop

KDevelop generará automáticamente las opciones necesarias del Makefile para que uic (compilador deinterfaz de usuario) produzca los archivos centralviewbase.h y centralviewbase.cpp

con el código fuente necesario. Todo lo que hay que hacer ahora es añadir una nueva clase (Proyecto |

Nueva clase...). En el diálogo que aparecerá, el nombre de la nueva clase será CentralView y

activaremos la casilla Generar clase hija de QWidget, como la clase heredará (indirectamente) de

QWidget, de hecho, vamos a cambiar QWidget (que KDevelop había añadido como Clase base) a

CentralViewBase.

Page 16: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 16/38

Dependiendo de la versión de Gideon que esté utilizando, es posible que necesite ir a la pestaña

Información avanzada y modificar manualmente el constructor para que la llamada sea a

CentralViewBase en vez de a QWidget (sustituyendo el uno por el otro).

Ahora añadiremos una variable protegida class CentralView * m_view; a

TheTinterView, y después una línea m_view=new CentralView(this,"centralview"); al final del constructor, para tener un widget CentralView como único hijo

de TheTinterView. El primer parámetro (this) significa que el widget CentralView será un

hijo del widget this, lo que significa que aparecerá en la pantalla dentro del widget this. El segundo

parámetro es un nombre de metadatos para el objeto, y es posible utilizar el nombre que se quiera.

En este momento estamos preparados para compilar s2 y obtener una aplicación que utilice el widget

que hemos creado en el diseñador.

Page 17: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 17/38

Chapter 6. Cómo hacer que el widget generado por el

diseñador funcione

Como ya habrá notado, el widget se muestra pero no hace nada, así que le haremos trabajar un poco.

Añadir nombres, slots y conexiones

En primer lugar, abra con el diseñador el archivo centralviewbase.ui, utilizando la pestaña

Grupos de archivos (a la izquierda), dentro del bloque Interfaz de usuario.

Dentro del diseñador, seleccione cada uno de los widgets que se utilizarán desde la aplicación, y deles

un nombre. Yo he llamado m_label al elemento gráfico, m_red al deslizador del componente rojo,

y m_green y m_blue a los otros dos, respectivamente. En caso de que usted no esté familiarizado

con el sistema de nomenclatura m_nombre, puedo decirle que este sistema es el mejor invento desde el

pan. Hace que el código sea mucho más sencillo de leer y mucho más comprensible por otros

desarrolladores.

A modo de normas generales del esquema de nomenclatura que utilizo, cito algunas reglas:

1. Siempre se nombra a los componentes en la forma ?maximumSize?, y no como ?MaximumSize?

o ?maximum_size?. La única excepción es en los nombres de las clases, que deben empezar por

mayúscula (?MaximumSize?).

2. Siempre se coloca "m_" como prefijo de los nombres de las variables miembro. De esta forma

siempre se sabe si una variable es local a un método o si depende de clase en la que se encuentra.

3. No utilice nunca getXXX() como nombre para acceder a un método de una clase (lo métodos

normales que únicamente hacen { return m_XXX; };). Es mucho mejor utilizar siempre el

nombre de la propiedad, algo como QFont font() const { return m_font; };. Deesta forma, el método set correspondiente, debería ir precedido por ?set?, de forma que la pareja

Page 18: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 18/38

get/set de una propiedad quede en la forma font() y setFont(const QFont &) en

nuestro ejemplo.

4. Las variables booleanas deben tener siempre nombres positivos, en vez de cosas como bool

m_noBackground . Es mucho más fácil entender el uso de la variable si se llamam_background y después utilizar if (m_background) ... en vez de if 

(!m_noBackground) ....

Bien, ahora nuestro widget tiene nombres que podremos utilizar en la implementación de

CentralView (ya que CentralView hereda de CentralViewBase), pero aún no es suficiente.

También debemos añadir slots a CentralViewBase, y, como son métodos virtuales, los

sobrecargaremos en CentralView. Vamos a hacerlo para que lo entienda mejor.

En primer lugar, abra el diálogo Slots del menú Edit o pulsando el botón derecho del ratón en el

widget principal. Pinche en New Function y dele el nombre setRed(int v), cree otros dos slots

llamados setGreen(int v) y setBlue(int v). Haremos que se llame a estos slots cada vez

que el usuario modifique los deslizadores rojo, verde o azul. Para hacerlo, salga del diálogo yselecione Connect Signals/Slots en el menú Tools, en el icono de la flecha de la barra de herramientas,

o pulsando F3. Después pinche con el botón izquierdo del ratón sobre el deslizador rojo y, sin soltarlo,

muévalo hacia el widget principal (por ejemplo hacia uno de los bordes). Hay un rectángulo magenta

que muestra los widgets que serán conectados. Una vez que se ha determinado el deslizador rojo como

origen y el widget principal como destino, suelte el botón y se le mostrará un diálogo en el que

configurar qué señal del elemento de origen se conectará con qué slot del widget de destino.

En el diálogo, pinche en el campo No Signal y seleccione la señal valueChanged(int). Después,

seleccione el slot setRed(int). Conecte también las señales correspondientes de m_green y

m_blue con setGreen(int) y setBlue(int).

Ahora, conviene recordar que los componentes de color van normalmente de 0 a 255 (y eso es lo que

dice la documentación de QColor), así que lo propio sería que el deslizador nos proporcionase

valores entre 0 y 255. Para hacerlo, seleccionamos cada deslizador y fijamos su propiedad maxValue

(en el editor de propiedades) a 255.

Page 19: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 19/38

Page 20: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 20/38

Ahora vamos a implementar los slots que acabamos de añadir para modificar el valor de m_color.

Utilizaremos el siguiente código:

void CentralView::setRed(int v)

{

m_color.setRgb( v, m_color.green(), m_color.blue() );

updatePixmap();

}

que utiliza el nuevo valor del componente rojo y deja los otros dos sin cambios. También llamamos al

método updatePixmap() que actualizará el mapa de pixels con el color m_color. Ahora vamos a

añadir el método y a implementarlo.

void CentralView::updatePixmap()

{

QPixmap pixmap(128,128);

pixmap.fill(m_color);

m_label->setPixmap(pixmap);

}

La primera línea crea un mapa de pixels de 128x128, y en la segunda línea se rellena del color. La

tercera línea coloca el mapa de pixels en el elemento de imagen. El tamaño 128x128 es un tanto

arbitrario, ya que el elemento gráfico lo redimensionará para que llene todo el área (puede cambiar

esto, si lo desea, en las propiedades).

Este es nuestro código fuente para s3, pronto haremos que cargue una imagen y la tiña con el color, en

vez de que únicamente aparezca este rellenando un rectángulo, pero, antes, trataremos de hacer que no

parpadee (fíjese en que si mueve los deslizadores muy rápido, se produce mucho parpadeo). Ese será

nuestro siguiente objetivo.

Page 21: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 21/38

Chapter 7. Eliminación del parpadeo utilizando un

temporizador

Los objetos QTimer se utilizan cuando se desea hacer algo en un momento determinado, o cada xmilisegundos. Para hacerlo, puede iniciar un temporizador que emita una señal en un momento

concreto. Después conecta esa señal a un slot para que realice el trabajo necesario.

En primer lugar, añadimos una variable protegida QTimer m_timer a CentralView (no olvide

la línea de inclusión #include <qtimer.h> correspondiente). En el constructor de

CentralView, conectamos la señal timeout() que emite m_timer al slot updatePixmap()

que hemos creado en s3. Para hacerlo, utilizaremos connect(&m_timer,

SIGNAL(timeout()), this, SLOT(updatePixmap()));.

Ahora cambiamos los tres slots, setRed, setGreen y setBlue para que inicien el temporizador

en vez de que llamen directamente a updatePixmap. m_timer.start(200,true); inicia un

temporizador de un único ciclo (que únicamente emitirá una señal y se detendrá) con un tiempo deespera de 200 ms. Cada vez que iniciemos un temporizador mientras haya otro funcionando (iniciamos

el segundo temporizador antes de que hayan pasado los 200 ms), se detendrá el más antiguo. Eso

significa que si el usuario mueve el deslizador muy rápido, en vez de producirse muchas llamadas a

updatePixmap(), esperaremos a que el usuario deje de modificar los valores durante 200 ms antes

de hacer el cambio real.

Eso nos lleva a s4. Ahora que hemos corregido el parpadeo (al menos en gran parte, ya que su

corrección completa no entra dentro del objetivo de este tutorial), podemos buscar experiencias más

avanzadas.

Chapter 8. Carga y manipulación de un mapa de pixels

Carga de un mapa de pixels

En primer lugar, añadiremos una variable miembro de QPixmap llamada m_pixmap a

CentralView, además de un método setPixmap que únicamente hará:

void CentralView::setPixmap(const QPixmap &pixmap)

{

m_pixmap=pixmap;

updatePixmap();

}

Ahora vamos a implementar el método que KDevelop creó como futura ubicación de un método de

carga de un documento en TheTinterView.

Page 22: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 22/38

void TheTinterView::openURL(const KURL& url)

{

QString tmpFile;

if (KIO::NetAccess::download(url, tmpFile))

{

// cargar el archivo (el destino es siempre local)m_view->setPixmap( tmpFile );

// y eliminar el archivo temporal

KIO::NetAccess::removeTempFile(tmpFile);

}

}

KIO::NetAccess::download se utiliza para descargar la URL url y guardarla en un archivo

temporal local cuya ruta completa se almacena en tmpFile. Si tiene éxito, devolverá true y el

documento será cargado.

Habrá notado que CentralView::setPixmap admite un parámetro QPixmap, mientras que

nosotros hemos utilizado como parámetro aquí un QString, ¿por qué? Si tiene experiencia en C++ yha leido un poco la documentación de QPixmap, sabrá que QPixmap tiene un constructor que admite

un único parámetro QString, y, por lo tanto, esa línea es equivalente a:

QPixmap pixmap( tmpFile );

m_view->setPixmap( pixmap );

He olvidado mencionar que el constructor de QPixmap que obtiene un parámetro QString, carga el

mapa de pixels indicado en dicho parámetro.

Por último, KIO::NetAccess::removeTempFile(tmpFile); hace algo muy interesante.

Elimina el archivo tmpFile únicamente si se trata realmente de un archivo temporal. Conviene

reseñar que en caso de que esté tratando de acceder a un archivo local,KIO::NetAccess::download devuelve el archivo real en vez de copiarlo a una ubicación

temporal (lo que sería absurdo) y KIO::NetAccess::removeTempFile no hace nada,por lo que

es seguro llamarlo aunque el archivo no sea temporal, porque KIO::NetAccess guarda una lista de

los archivos que se han descargado (y son realmente temporales) y los archivos reales que no deben

ser eliminados.

Mezcla de colores

Ahora vamos a hacer que CentralView realice operaciones sobre el mapa de pixels. Cambiaremos

la implementación de updatePixmap a:

void CentralView::updatePixmap()

{

QImage image= m_pixmap.convertToImage();

KImageEffect::blend(m_color, image, 0.5);

QPixmap pixmap;

pixmap.convertFromImage(image);

m_label->setPixmap(pixmap);

}

La primera línea convierte el mapa de pixels a una imagen, que es otra clase que puede albergar

imágenes. La diferencia es que QImage almacena las imágenes localmente, mientras que QPixmap

lo hace en el servidor X, de forma que habrá que utilizar uno un otro dependiendo del objetivo que se

quiera lograr. En este caso resultará más sencillo teñir una imagen.

Page 23: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 23/38

KImageEffect::blend(m_color, image, 0.5); utiliza KImageEffect (de

kdelibs/kdefx) para mezclar un color con una imagen. KImageEffect es una clase que contiene

métodos muy útiles para aplicar efectos a imágenes. El primer parámetro es el color, el segundo la

imagen (que será modificada por este método) y el tercero es la intensidad de opacidad.

Continuamos volviendo a convertir la imagen a un mapa de pixels y colocándola, al igual que antes, en

el elemento gráfico.

Esto significa que hemos terminado con s5, y ya podemos abrir imágenes y teñirlas, pero aún no

hemos acabado.

Chapter 9. Modificación del interfaz de usuario existente

Ahora vamos a cambiar el interfaz de nuestra aplicación para añadirle un nuevo deslizador que nos

permita modificar el componente de opacidad (o alfa) del tinte.

Page 24: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 24/38

Añadir el deslizador de alfa

En primer lugar, en la pestaña Grupos de archivos, seleccionamos el archivo

centralviewbase.ui, y KDevelop abrirá el diseñador. Lo primero que haremos es romper las

disposiciones. Usted se preguntará, ¿romper las disposiciones? Sí, eso se hace para poder decir: "Dejade manejar las posiciones actuales de los elementos, porque vamos a añadir otros nuevos".

Pinche para seleccionar el widget principal, y después pinche en el icono de la barra de herramientas

Break Layout (también disponible en el menú Layout). Ahora seleccione la caja de agrupación que

contiene los deslizadores y rompa también la disposición de estos. Debe darse cuenta de que las dos

disposiciones son independientes entre sí. La disposición del widget principal es una disposición

vertical, que maneja m_label y la caja de agrupación, y la disposición de dicha caja, maneja las

etiquetas y los deslizadores.

Si intenta añadir un elemento dentro de otro que tiene una disposición, se le preguntará si desea

romper antes la disposición para poder añadirlo. Pero eso no debería ocurrir ahora puesto que hemos

roto las disposiciones manualmente :).

Page 25: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 25/38

Ahora que hemos roto la disposición, puede mover hacia arriba los deslizadores y las etiquetas para

dejar espacio para el nuevo deslizador que añadiremos. Añada una etiqueta de texto Alfa: y un

deslizador al que llamaremos m_alpha (que el usuario podrá utilizar para establecer el alfa u

opacidad de la mezcla de colores) en la parte de abajo de la caja de agrupación. Cambie sus

propiedades para que el rango de valores de m_alpha vaya de 0 a 100. Seleccione la caja de

agrupación ...

... y pinche en la barra de herramientas para añadir una disposición de rejilla.

Page 26: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 26/38

Ahora puede seleccionar el widget principal y añadir la disposición vertical.

Añadir el botón de selección de color

Si queremos mejor todavía más el aspecto de nuestra aplicacióm, podemos añadir un botón

KColorButton que utilizaremos como forma alternativa de selección del color mediante un diálogo

de color estándar.

Page 27: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 27/38

Selecciónelo y añádalo en la parte derecha de la caja de agrupación (pero dentro de ella). ¿Reconoceese diálogo? Sí, está preguntando si se debe romper la disposición o cancelar la operación.

Seleccionaremos romper la disposición y a continuación la volveremos a crear.

Page 28: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 28/38

Podemos añadir una disposición de rejilla a la caja de agrupación tal y como está, y el diseñador lo

colocará correctamente de forma automática, pero vamos a utilizar otra técnica con la intención de

aprender algo más. Deseleccione cualquier widget que pudiera estar seleccionado, y pulsando la tecla

?Ctrl? en el teclado, dibuje un rectángulo que cubra las etiquetas y los deslizadores (pero no la caja de

agrupación entera, ni el KColorButton), de esa forma quedarán seleccionados. Una vez que tenga los 8

elementos seleccionados, pinche en la disposición de rejilla, y el diseñador generará una disposición de

rejilla para eso elementos. Ahora esta disposición maneja a sus hijos, pero (aún) no está manejada por

nadie, así que resulta un tanto inútil.

Page 29: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 29/38

Para solucionarlo, seleccionaremos la caja de agrupación y añadiremos una disposición horizontal.

Esta nueva disposición manejará la disposición de rejilla y el widget KColorButton, colocándolos

uno junto al otro.

Note la diferencia existente entre seleccionar la caja de agrupación y añadir una disposición horizontal

y seleccionar la disposición de rejilla y el KColorButton y añadir entonces esa disposición horizontal.

En el primer caso, la disposición pertenecerá a la caja de agrupación, de forma que administrará las

políticas de tamaño y (directa o indirectamente) a todos sus hijos. En el segundo caso, añadiremos una

disposición horizontal independiente. Puede realizar pruebas de estas dos formas de actuar y utilizar la

opción Preview Form para comprobar las diferencias que se produce al redimensionar la ventana.

Bien, ahora seleccionaremos el widget principal y añadiremos una disposición vertical y, de esta

forma, hemos hecho que todos los elementos estén manejados por una disposición, que es la forma

correcta de actuación (quizá debería decir que esta debe ser la forma correcta de actuación, para

resaltar que es como hay que hacerlo para que las aplicaciones funcionen correctamente).

Esto podría ser suficiente para la mayor parte de la gente, pero no para nosotros. Queremos que elwidget KColorButton (al que llamaremos m_colorButton) aumente hasta ocupar todo el

espacio de la caja de agrupación. Para ello, le cambiaremos la política de tamaño. Seleccione

m_colorButton y en el editor de propiedades, abra la sección sizePolicy y cambie vSizeType a

Expanding.

Page 30: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 30/38

Vaya, probablemente no era esto lo que queríamos. Hemos observado anteriormente que m_label

tenía una política de tamaño de expansión (MinimumExpanding para ser precisos) mientras que la

caja de agrupación no nos importaba (únicamente tenía una política Preferred). Ahora la caja de

agrupación también se ha expandido porque la política de m_colorButton es Expanding (por lo

que trata de ocupar el mayor espacio vertical posible), y m_label también, así que el sistema de

disposición trata de darle a cada uno la mitad del espacio disponible, y eso no es lo que buscamos.

¿Hay una solución? Desde luego. En casos como este es posible darle a los elementos involucrados

distintos factores de expansión para que a uno de ellos se le asigne más espacio que al otro en caso de

que ambos quieran la mayor cantidad de espacio posible. Esto se hace gracias a la propiedadverticalStretch. Así que incrementaremos el valor de la propiedad verticalStretch de

m_label para que éste sea más grande y se solucione el problema.

Page 31: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 31/38

Bien, ahora que el aspecto vuelve a ser el correcto, podemos abrir el editor de slots y añadir dos

nuevos, uno para el deslizador alfa (llamado setAlpha(int)) y otro al que se llamará cuando el

usuario modifique el color en m_colorButton, al que llamaremos setColor(const QColor

&).

Es hora de hacer las conexiones. No voy a volver a explicar cómo se hace, puesto que es muy sencillo.

Tiene que conectar la señal valueChanged(int) de m_alpha con el slot setAlpha(int) del

widget principal. No olvide conectar también la señal changed(const QColor &) de

m_colorButton con el slot setColor(const QColor &) del widget principal.

Page 32: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 32/38

Bueno, de momento ya es suficiente, así que guardaremos el archivo .ui, cerraremos el diseñador,

compilaremos el resultado y lo llamaremos s6. Fíjese que, en este caso, no hemos hecho nada con

KDevelop, únicamente hemos modificado el interfaz de usuario con el diseñador y el hecho de

compilar sin haber cambiado nada nos da el nuevo interfaz de usuario (con el código anterior

funcionando correctamente). Añadiremos el código del nuevo interfaz en el siguiente paso.

Chapter 10. Añadir las implementaciones de los nuevos

métodos

Soporte para el deslizador alfa

En primer lugar, añadiremos un slot público a CentralView llamado setAlpha(int v). La

implementación de este método únicamente llamará a m_timer.start(200,true); para iniciar

la actualización del mapa de pixels.

Page 33: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 33/38

Entonces cambiaremos el método updatePixmap para que utilice el valor del deslizador alfa.

Cambiamos

KImageEffect::blend(m_color, image, 0.5 );

por

KImageEffect::blend(m_color, image, m_alpha->value()/100.0 );

De forma que el valor resultante esté en el intervalo [0,1] (ya que en el diseñador hemos establecido en

100 en valor máximo de m_alpha).

Soporte para el botón de color

Vamos a añadir un nuevo método a CentralView llamado setColor.

void CentralView::setColor(const QColor &color)

{m_red->setValue(color.red());

m_green->setValue(color.green());

m_blue->setValue(color.blue());

}

Con esto es suficiente para establecer el color, ya que fija el valor de los tres componentes, emitiendo

las tres respectivas señales y llamando a setRed, setGreen y setBlue, y, además, no parpadeará

puesto que se llama al temporizador cada vez que cambia un valor (gracias a las señales que emiten los

deslizadores cada vez que cambia su valor) y, por lo tanto, updatePixmap recibirá una única

llamada.

Con este cambio tenemos una aplicación completamente operativa, a la que llamaremos s7.

Page 34: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 34/38

Chapter 11. Algunos cambios aquí y allá

Corrección del botón de color.

Como habrá notado, cuando el usuario cambia el color en el botón de color, los deslizadores cambian

sus valores, pero esto no ocurre en la situación inversa. Vamos a arreglarlo.

Page 35: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 35/38

Añadiremos m_colorButton->setColor(m_color); a CentralView::updatePixmap

y así haremos que m_colorButton actualice su valor al mismo tiempo que se actualiza el mapa de

pixels.

Quizá quiera actualizar m_colorButton cada vez que cambie uno de los deslizadores, pero si lohace, podría tener problemas y posiblemente tendría que utilizar QObject::blockSignals para

bloquear las señales de los deslizadores o de m_colorButton, así que lo actualizaremos en

updatePixmap para estar seguros del correcto funcionamiento.

Corrección de mapa de pixels inicial

En primer lugar, vamos a eliminar el logotipo de Qt que utiliza m_label de forma predeterminada.

Para hacerlo, abra centralviewbase.ui en el diseñador, seleccione la etiqueta y elimine el

contenido de la propiedad pixmap pinchando en la pequeña flecha roja (aparece al seleccionar la

propiedad).

En cualquier caso, queremos que haya algo dibujado al comenzar. Así que añadiremos una llamada a

updatePixmap(); en el constructor de CentralView.

Aun así, m_pixmap está vacío al iniciar TheTinter, y seguimos queriendo que aparezca algo. Vamos

a modificar la función updatePixmap para:

void CentralView::updatePixmap()

{

m_colorButton->setColor(m_color);

QPixmap pixmap;

if (!m_pixmap.isNull())

{

QImage image= m_pixmap.convertToImage();

KImageEffect::blend(m_color, image, m_alpha->value()/100.0 );

pixmap.convertFromImage(image);}

else

{

pixmap = QPixmap(128,128);

pixmap.fill(m_color);

}

m_label->setPixmap(pixmap);

}

De esta forma, en primer lugar comprobamos si m_pixmap es válido (no es nulo) y, en ese caso,

continuamos con el funcionamiento normal. En caso de que m_pixmap no haya sido inicializado,

haremos lo que se vio en los primeros pasos del tutorial y pintaremos un color.

Page 36: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 36/38

Chapter 12. Añadir más características

Posibilidad de guardar el resultado

Ahora queremos guardar la imagen teñida en un archivo. ¿Qué podemos hacer? En primer lugar

añadiremos un método de acceso a CentralView que devuelva el mapa de pixels teñido (el mapa de

pixels que se encuentra en m_label):

QPixmap *tintedPixmap() const { return m_label->pixmap(); };

En TheTinterView, añadiremos un nuevo método junto a openURL(const KURL &url),

¿adivina el nombre? Correcto, saveURL(const KURL &url) :) Este método hace:

void TheTinterView::saveURL(const KURL &url)

{

QString tmpFile;

KTempFile *temp=0;if (url.isLocalFile())

tmpFile=url.path();

else

{

temp=new KTempFile;

tmpFile=temp->name();

}

m_view->tintedPixmap()->save( tmpFile, "PNG");

if (temp)

{

KIO::NetAccess::upload(tmpFile, url, this);

temp->unlink();delete temp;

}

}

En caso de que la URL sea un archivo local, lo utilizaremos como archivo en el que guardar el mapa

de pixels teñido en formato PNG. Si no es un archivo local, crearemos un archivo temporal y

guardaremos ahí la imagen en formato PNG y, a continuación, cargaremos el archivo temporal en la

URL especificada por el usuario, eliminaremos el archivo temporal y destruiremos el objeto que

habíamos creado para ello.

Añadir soporte para arratrar y soltar

Aquí no hay mucho que hacer, ya que KDevelop añadió automáticamente desde el principio el código

necesario para aceptar operaciones de arrastrar y soltar con URIs (equivalentes, de momento, a URLs),

y como hemos utilizado KIO para cargar nuestras imágenes, ya es posible arrastrar una imagen desde

Konqueror a TheTinter y será descargada.

Para desarrollar algo sobre arrastrar y soltar, añadiremos soporte para imágenes. La diferencia con las

URIs es que los eventos de arrastrar y soltar de una imagen contienen la información de la propia

imagen, mientras que en el caso de las URLs, estas únicamente contienen la dirección de la imagen.

Page 37: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 37/38

El código que utilizaremos es:

void TheTinter::dragEnterEvent(QDragEnterEvent *event)

{

// accept uri drops only

event->accept(QUriDrag::canDecode(event) || QImageDrag::canDecode(event));}

Esto será llamado cada vez que recibamos un evento de arrastrar y soltar en nuestra aplicación. Le dice

al subsistema de arrastrar y soltar si se debe aceptar o rechazar la operación.

void TheTinter::dropEvent(QDropEvent *event)

{

// esta es una implementación muy simple de un evento de soltar. únicamente

// aceptaremos una URL. el código de arrastrar y soltar de Qt puede hacer

// *mucho* más, así que, por favor, consulte la documentación

QStrList uri;

// comprobar si se puede decodificar la URI. si no, ignorarlaif (QUriDrag::decode(event, uri))

{

// correcto, tenemos una URI. la procesamos

QString url, target;

url = uri.first();

// cargamos el archivo

load(KURL(url));

return;

}

QPixmap pixmap;

if (QImageDrag::decode(event, pixmap))

{m_view->openPixmap(pixmap);

}

}

Este código se ejecutará cada vez que el usuario suelte sobre nuestra ventana cualquier cosa que esté

arrastrando. En primero lugar tratamos de comprobar si el evento es un evento URI. Si la primera parte

tiene éxito, extraemos la primera URL de la (posible) lista de URIs que contiene el evento, y

ejecutamos esa URL.

Si no se trataba de un evento URI, tratamos de decodificarlo como un evento de imagen (utilizando

QImageDrag::decode). Si es correcto, abrimos esa imagen. Hay que tener en cuenta que

TheTinterView::openPixmaptodavía no existe, así que añadimos ese método y loimplementamos de esta forma:

void TheTinterView::openPixmap(const QPixmap& pixmap)

{

m_view->setPixmap( pixmap );

}

Y esto es s9, nuestra aplicación final. Espero que haya disfrutado del tutorial y haya aprendido con él.

También deseo poder ver publicadas muy pronto sus aplicaciones de KDE :).

Un saludo,

Page 38: El tutorial del desarrollo visual

8/6/2019 El tutorial del desarrollo visual

http://slidepdf.com/reader/full/el-tutorial-del-desarrollo-visual 38/38

Antonio Larrosa Jiménez <[email protected]

Appendix A. Créditos y licencia

El tutorial de desarrollo visual en KDE y TheTinter tienen Copyright (c) 2003 Antonio Larrosa

Jiménez <[email protected]

This documentation is licensed under the terms of the GNU Free Documentation License.

TheTinter está publicado bajo los términos de la Licencia pública general GNU.

Me gustaría agradecer a las siguientes personas su ayuda en la creación de este tutorial:

A Lauri Watts por explicar el docbook y crear un marco de trabajo excepcional para la

documentación de KDE (y por responder a mis preguntas sobre docbook hasta altas horas en el

IRC :) ).

A Anne-Marie Mahfouf por explicarme algunas etiquetas del docbook y por escribir otro

excelente tutorial sobre KDevelop y el diseñador, que podrá encontrar aquí. 

A Harald Fernengel y Roberto Raggi del equipo de KDevelop por solucionar rápidamente

algunos problemas que he encontrado en Gideon al hacer este tutorial.

A Miguel Revilla, del equipo de traducción de KDE, por traducir este tutorial en menos un día

para que me diera tiempo a usar la versión en español en Imaginática.