p6

Siguiente Anterior Tabla de Contenidos

Aqui explicaremos p6, que es una aplicación muy simple que simplemente muestra una lista con bookmarks.


#include <kapp.h>
#include "p6.h"
 
int main( int argc, char **argv )
{
    KApplication a( argc, argv, "p6" );
 
    MainList *mylist=new MainList;
    mylist->resize( 300, 200 );
 
    a.setMainWidget( mylist );
    mylist->show();
 
    return a.exec();
}

main.cpp


#ifndef __P6IFACE_H__
#define __P6IFACE_H__
 
#include <dcopobject.h>
#include <qstring.h>
 
class p6Iface : virtual public DCOPObject
{
    K_DCOP
public:
 
k_dcop:
    virtual void add( const QString s ) = 0;
 
};
 
#endif

p6Iface.h


#include "p6Iface.h"
#include <qlistview.h>
 
class MainList : public QListView, virtual public p6Iface
{
 Q_OBJECT
 
public:
 
 MainList();
 
 void add ( const QString s );
 
};

p6.h


#include "p6.h"
#include <klocale.h>
#include <kapp.h>
#include <dcopclient.h>
 
MainList::MainList() : QListView ( 0L, "Bookmarks" ), 
			DCOPObject ( "bookmarkList" )
{
   addColumn( i18n("My Bookmarks") );
 
   DCOPClient *client=kapp->dcopClient();
   client->attach();
   client->registerAs("p6");
};
 
void MainList::add( const QString s )
{
   insertItem ( new QListViewItem ( this , s ) );
}; 

p6.cpp

En vez de usar un KTMainWindow y para conseguir claridad en el código fuente, usaremos directamente un widget QListView a costa del diseño del interfaz gráfico.

Con QListView se puede crear un widget con una lista de elementos (además con diferentes columnas para mostrar las diferentes propiedades de cada elemento). Es además posible, y rápido, el crear un árbol de elementos para tenerlo todo mejor organizado. En este pequeño ejemplo, lo usaremos como una vista de una lista compuesta por una sola columna y con capacidades de ordenación. ( por esto es por lo que no estamos usando un QListBox, que satisfacería nuestros propósitos con un API mas simple).

Hay una gran diferencia con los ejemplos previos, tenemos un fichero llamado p6Iface.h, veamos ahora que es y para que sirve.

class p6Iface : virtual public DCOPObject
{
    K_DCOP
public:
 
k_dcop:
    virtual void add( const QString s ) = 0;
 
};

Con este dichero definimos el interface que p6 exportará a otras aplicaciones para que lo usen. Usando la marca especial k_dcop ( que sera eliminada por el preprocesador antes de llegar al compilador ), definimos los miembros del objeto que otros podran llamar remotamente usando DCOP, en este caso add.

Hay que fijarse en que definimos esta función como pure virtual, con lo que no esta implementada en la clase p6Iface. El truco aquí es usar dcopidl, una herramienta que traduce nuestra definición parecida a un fichero .h a un lenguaje de definición de interfaces común (IDL, Interface Definition Language). Esto le permite a otras aplicaciones, como a dcopidl2cpp, el escribir por nosotros una plantilla de la implementación, que se usa internamente por DCOPObject para saber que métodos estan disponibles en este objeto.

class MainList : public QListView, virtual public p6Iface

Mirando en p6.h, podemos ver que nuestro widget principal hereda de QListView (ya que será natural el mostrar la lista en el X-Windows), pero ademas hereda de la clase p6Iface que acabamos de definir. De esta forma podemos implementar los métodos accesibles remotamente en las clases que usemos.

MainList::MainList() : QListView ( 0L, "Bookmarks" ), 
			DCOPObject ( "bookmarkList" )

Como no hemos implementado todavía el constructor de p6Iface, llamaremos aquí a DCOPObject. El parámetro del constructor es el nombre con el que DCOP conocerá a este objeto, con lo que las llamadas remotas a uno de sus métodos deberan de ser hechas usando bookmarkList como el nombre del objeto.

   addColumn( i18n("My Bookmarks") );

Añadimos una columna ( al menos debe haber una para que QListView sea útil).

   DCOPClient *client=kapp->dcopClient();
   client->attach();
   client->registerAs("p6");

Ahora esta aplicación está unida (attached) al servidor DCOP, tal como hicimos en p5, pero de una nueva forma. Como en p5 no ibamos a recivir ninguna llamada usamos una conexión anónima. En este caso queremos que otras aplicaciones se conecten a esta, con lo que debemos registrarnos con un nombre, que es lo que hace registerAs.

Obviamente, ese es el nombre que otros usaran cuando hagan una llamada a esta aplicación usando DCOP.

   insertItem ( new QListViewItem ( this , s ) );
Finalmente el método add toma el parámetro QString, construye un QListViewItem con el y añade el elemento (item) a QListView.

Quizá te preguntes porque no hay un método mas simple para insertar un QString en un QListView. La razón es simple: Un objeto QListView puede contener cosas mucho mas complicadas que cadenas, por ejemplo, se pueden tener múltiples columnas, donde algunas de ellas son objetos QPixmap (imágenes), etc.


Scripting (guiones)

Uno de los múltiples beneficios de usar DCOP es su habilidad para facilmente permitir la creación de scripts para cualquier aplicación que use este interface. Como ejemplo de esto, mostraremos un script en Python que añade un url a la lista de marcadores.

Para poder usarlo sera necesaria la librería xmlrpc para Python. Esta disponible en http://www.pythonware.com/downloads/xmlrpc-0.9.8--990621.zip, solo hace falta descomprimirla en el directorio de librerías de Python (usualmente /usr/lib/python1.5). Además hará falta ejecutar kxmlrpcd, que es un demonio de xmlrpc que funciona como puente entre el protocolo xmlrpc y el protocolo DCOP.

El script usado es el siguiente:


#!/usr/bin/python
 
from xmlrpclib import *
import os
 
rc = open(os.environ['HOME'] + '/.kxmlrpcd', 'r')
config = string.split(rc.read(), ',')
port = config[0]
auth = config[1]
 
server = Server("http://localhost:" + port +"/p6")
 
server.bookmarkList.add(auth, "http://www.kde.org")  

addurl.py

Quisiera aquí darle las gracias a Kurt Granroth por darme el código fuente de este script, ya que mi conocimiento de Python es nulo.

De cualquier forma, nos podemos fijar en que estamos usando la dirección localhost cuando nos conectamos al servidor. Simplemente cambiando esa linea (y teniendo los permisos correctos), podemos conectarnos a servidores en hosts remotos (incluso con diferentes tipos de CPU y sistemas operativos), y controlar aplicaciones remotas desde scripts.

¡ Incluso se puede hacer un script para una aplicación de KDE usando un script en bash !

Hemos terminado de examinar p6. Veamos qué podemos hacer a continuación.

Siguiente Anterior Tabla de Contenidos


© 1999 Antonio Larrosa
Traducido por Rafael Larrosa y Antonio Larrosa