P6: O colectie de semne de carte
P6 este doar o simpla aplicatie care
doar afiseaza o lista de semne de carte.
#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
In loc sa folosim KMainWindow, vom folosi direct QListView.
Cu QListView poti crea un widget care contine o lista de
elemente (cu diferite coloane care arata proprietatile fiecarui element).
Este posibil (si rapid) sa cream si un arbore pentru a organiza mai bine
elementele. In acest mic exemplu vom folosi doar o lista cu o singura coloana,
cu posibilitatea ordonarii elementelor (de aceea nu vom folosi QListBox).
Este o mare diferenta fata de exemplul anterior. Acum avem un fisier numit
p6Iface.h. Haideti sa vedem ce face:
class p6Iface : virtual public DCOPObject
{
K_DCOP
public:
k_dcop:
virtual void add( const QString s ) = 0;
};
In acest fisier definim interfata pe care P6 o va publica pentru ca
celelalte aplicatii sa o foloseasca. Folosind K_DCOP (care va fi
sters de preprocesor inainte de a ajunge la compilator), definim membrii
obiectului pe care celelalte aplicatii vor putea sa-l apeleze de la
distanta folosind DCOP, in cazul nostru, add.
Trebuie sa retineti faptul ca functia este definita pur virtual, deci nu
este implementata in clasa p6Iface. Artificiul este sa folosim
dcopidl, o unealta care va transforma definitiile interfetei din
fisierul .h in Interface Definition Language. Asta permite
altor aplicatii, cum ar fi dcopidl2cpp sa scrie pentru noi
scheletul implementarii care este folosit intern de DCOPObject
pentru a sti ce metode sint disponibile pentru obiect.
class MainList : public QListView, virtual public p6Iface
Uitindu-ne in p6.h, vedem ca widget-ul principal mosteneste
QListView (este normal sa afisam o lista direct pe X), dar mosteneste
si clasa p6Iface pe care am definit-o. Astfel putem inplementa
metode accesibile de la distanta in clase obisnuite
MainList::MainList() : QListView ( 0L, "Bookmarks" ),
DCOPObject ( "bookmarkList" )
Deoarece nu am implementat nici un constructor pentru p6Iface, il
vom apela pe al lui DCOPObject. Retineti ca parametrul constructorului este
numele cu care DCOP va sti de obiect, asa ca apelurile de la distanta la
una din metodele acestuia (obiectului) vor fi facute folosind
bookmarkList ca nume al obiectului.
addColumn( i18n("My Bookmarks") );
Adaugam o coloana (trebuie sa fie cel putin una ca sa putem folosi
QListView).
DCOPClient *client=kapp->dcopClient();
client->attach();
client->registerAs("p6");
Acum vom atasa aplicatia la serverul DCOP, la fel cum am facut in
P5, dar in alt mod.
Deoarece in P5 nu primim nici un apel,
am folosit doar o conexiune anonima. In acest caz, vrem ca alte
aplicatii sa se conecteze la aceasta. De aceea ar trebui sa o inregistram in
server cu un nume, dat ca parametru la registerAs.
Bineinteles ca acesta este numele cu care celelalte aplicatii il
vor folosi in apelurile DCOP.
insertItem ( new QListViewItem ( this , s ) );
In cele din urma metoda add primeste ca parametru un
sir de caractere QString, construieste un element
QListViewItem si il adauga in lista QListView.
Probabil ca va intrebati de ce nu este o metoda mai simpla de a insera un
QString intr-o lista QListView. Motivul este simplu:
un obiect QListView poate contine clase mult mai complexe decit
simple texte. De exemplu putem avea mai multe coloane, iar ca elemente ale
coloanelor putem avea obiecte QPixmaps (imagini) etc.
Scripturi
Unul din cele mai mari avantaje ale DCOP consta in faptul ca poate fi
controlat cu usurinta si din scripturi. Ca exemplu o sa implementam un script
in Python care adauga legatura in lista de semne de carte.
Pentru a-l putea folosi, va va trebui libraria xmlrpc pentru Python.
Este disponibila la http://www.pythonware.com/products/xmlrpc/index.htm.
Decomprimati-o in directorul librariilor Python (de obicei
/usr/lib/python1.5).
Veti mai avea nevoie sa executati kxmlrpcd. Acesta este un demon
xmlrpc care este utilizat ca o punte de legatura intre protocolul
XMLRPC si protocolul DCOP. (Nota traducerii: in KDE > 3.0 XMLRPC este
un serviciu al demonului KDE kded si il activati din Centrul de
Control KDE in "Componente KDE -> Managerul de servicii")
Scriptul folosit este urmatorul:
#!/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
Vreau sa multumesc lui Kurt Granroth pentru ca a pus la dispozitie sursa
acestui script deoarece cunostintele mele in Python sunt nule.
Observati ca am folosit localhost ca adresa de conectare la
server. Daca schimbam acea linie (si avem permisiunile necesare)
putem sa ne conectam la un server aflat la distanta (chiar daca difera ca
arhitectura sau ca sistem de operare) si putem controla aplicatiile de la
distanta printr-un script.
Puteti chiar comunica cu o aplicatie KDE utilizind un simplu script de
interpretor Bash!
Am terminat de examinat P6. Sa vedem ce mai avem de facut in
continuare.
|