You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tde-i18n/tde-i18n-it/docs/tdevelop/kde_app_devel/index.docbook

906 lines
72 KiB

<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
<!ENTITY tdevelop "<application>KDevelop</application>">
<!ENTITY kappname "&tdevelop;">
<!ENTITY % addindex "INCLUDE">
<!ENTITY % Italian "INCLUDE"> <!-- change language only here -->
]>
<book lang="&language;">
<bookinfo>
<title>Manuale di programmazione di &tdevelop;</title>
<date>2002-12-05</date>
<releaseinfo>2.0</releaseinfo>
<authorgroup>
<author><firstname>Ralf</firstname> <surname>Nolden</surname> <affiliation><address><email>Ralf.Nolden@post.rwth-aachen.de</email></address></affiliation>
</author>
<author><firstname>Caleb</firstname> <surname>Tennis</surname> <affiliation><address><email>caleb@aei-tech.com</email></address></affiliation>
</author>
</authorgroup>
<copyright>
<year>1999</year>
<holder>Ralf Nolden</holder>
</copyright>
<copyright>
<year>2002</year>
<holder>Caleb Tennis</holder>
</copyright>
<!-- ROLES_OF_TRANSLATORS -->
<legalnotice>&FDLNotice;</legalnotice>
<abstract>
<para>Il manuale utente per lo sviluppo di applicazioni C++ per l'ambiente desktop KDE con l'IDE &tdevelop;</para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>KDevelop</keyword>
<keyword>IDE</keyword>
<keyword>sviluppo</keyword>
<keyword>programmazione</keyword>
</keywordset>
</bookinfo>
<chapter id="chapter1">
<title>Introduzione</title>
<para>I sistemi Unix, che da un lato stanno diventando sempre più popolari anche ai principianti per i loro vantaggi di stabilità e funzionalità dall'altro deludono perché le applicazioni non hanno un aspetto uniforme e si comportano diversamente l'una dall'altra. Con KDE gli sviluppatori hanno uno strumento quasi perfetto per creare applicazioni di prima qualità per i sistemi desktop Unix. Quindi KDE viene sempre più scelto come base per la progettazione di applicazioni e gli sviluppatori vogliono sfruttare le possibilità offerte da questo sistema. </para>
<sect1 id="c1s1">
<title>Cosa si dovrebbe già conoscere</title>
<para>Per usare al meglio questo manuale di programmazione, si presuppone la conoscenza della programmazione con il linguaggio C/C++, in caso contrario si dovrebbe familiarizzare con questo linguaggio. Le informazioni sul linguaggio C++ sono disponibili in forma stampata nella propria libreria o in formato elettronico su Internet. Non è richiesta la conoscenza di progettazione di interfacce grafiche (GUI), siccome questo manuale illustra la progettazione di applicazioni KDE, che include sia una introduzione al toolkit Qt che l'uso delle librerie KDE e la progettazione delle interfacce utente. Inoltre si dovrebbe conoscere &tdevelop; leggendo il Manuale Utente di &tdevelop;, che contiene una descrizione delle funzionalità di questo IDE. </para>
</sect1>
<sect1 id="c1s2">
<title>Informazioni sul manuale</title>
<para>Questo manuale è stato scritto per fornire agli sviluppatori una introduzione alla progettazione di applicazioni KDE utilizzando l'ambiente di sviluppo integrato KDevelop. </para>
<para>I capitoli seguenti contengono una introduzione alla creazione di progetti, forniscono una spiegazione del codice sorgente che viene generato e mostrano come arricchirlo con altri oggetti come barre degli strumenti, barre dei menu e viste. </para>
<para>Viene discusso dettagliatamente la creazione di widget personalizzati e le impostazioni dei widget predefiniti. </para>
<para>Infine vengono illustrati vari argomenti che completano la conoscenza della progettazione e aiutano a risolvere ulteriori problemi come l'aggiunta della documentazione API e la stesura dei manuali. </para>
<sect2 id="c1s2s1">
<title>Nel prossimo capitolo</title>
<para>Verranno mostrati i concetti di base per l'utilizzo delle librerie Qt e KDE, spiegando come costruire le applicazioni illustrate nel tutorial incluso con Qt usando &tdevelop;. In questo modo i principianti vedranno subito i primi risultati e impareranno l'uso delle funzionalità più importanti di &tdevelop; </para>
</sect2>
<sect2 id="c1s2s2">
<title>Nei capitoli seguenti</title>
<para>Si imparerà: <itemizedlist>
<listitem><para>a creare una applicazione con la procedura guidata per le applicazioni</para></listitem>
<listitem><para>a conoscere lo schema del progetto</para></listitem>
<listitem><para>il significato del codice già creato</para></listitem>
<listitem><para>a creare le proprie viste</para></listitem>
<listitem><para>a espandere le funzionalità delle applicazioni con finestre di dialogo, barre dei menu e barre degli strumenti</para></listitem>
<listitem><para>a rendere l'applicazione amichevole per l'utente con le funzioni di aiuto</para></listitem>
<listitem><para>a scrivere la documentazione in linea</para></listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1 id="c1s3">
<title>Ulteriori informazioni</title>
<para>Informazioni aggiuntive sulla programmazione con Qt/KDE sono disponibili attraverso diverse fonti: <itemizedlist>
<listitem><para>Programming with Qt di Matthias Kalle Dalheimer</para></listitem>
<listitem><para><ulink url="www.kdevelop.org">Il manuale utente di KDevelop, fornito con l'IDE KDevelop</ulink></para></listitem>
<listitem><para><ulink url="doc.trolltech.com">La documentazione di riferimento delle librerie Qt</ulink></para></listitem>
<listitem><para><ulink url="developer.kde.org">Il sito dello sviluppatore KDE</ulink></para></listitem>
</itemizedlist>
</para>
<para>Si può cercare aiuto sottoscrivendo varie mailing list, i cui indirizzi sono disponibili nei siti web menzionati e nei newsgroup usenet dedicati agli utenti di KDE e dei sistemi Unix, così come quelli dedicati ai linguaggi di programmazione C e C++. </para>
<para>Per avere aiuto con KDevelop inviare le richieste alla mailing list all'indirizzo <email>kdevelop@kdevelop.org</email>. Ricordarsi che il gruppo di KDevelop non effettua supporto tecnico nel caso in cui la propria applicazione non funzioni a causa di errori di implementazione o errate impostazioni del sistema operativo, ma è dedicato allo sviluppo di strumenti che permettono di programmare applicazioni. Per questo motivo viene chiesto a tutti gli utenti di usufruire della mailing list solo per problemi riguardanti l'IDE stesso, per segnalazioni di bug e suggerimenti per migliorare le funzionalità dell'ambiente di sviluppo. </para>
</sect1>
</chapter>
<chapter id="chapter2">
<title>Le librerie KDE e Qt</title>
<para>La società norvegese TrollTech (<ulink url="http://www.trolltech.com">http://www.trolltech.com</ulink>) fornisce uno strumento per la programmazione (toolkit) di GUI chiamato Qt. GUI sta per "Graphical User Interface", quindi le applicazioni Qt appaiono con pulsanti, finestre, ecc. permettendo all'utente l'inserimento e la visualizzazione dei dati inseriti. Questo strumento è necessario agli sviluppatori di applicazioni grafiche funzionanti con il sistema X-Window di Unix, in quanto X non ha una propria interfaccia utente predefinita. Anche se sono disponibili altri strumenti per la creazione di interfacce grafiche, Qt offre alcune tecniche vantaggiose per rendere semplice la loro progettazione. Inoltre Qt è disponibile anche per la piattaforma Microsoft Windows, permettendo di sviluppare applicazioni per entrambe le piattaforme. </para>
<para>Il gruppo KDE (<ulink url="http://www.kde.org">http://www.kde.org</ulink>), si formò con l'obiettivo di rendere più facile l'uso dei sistemi Unix, e decise di utilizzare gli strumenti Qt per sviluppare un gestore di finestre per X-Window e una varietà di strumenti inclusi nei pacchetti di KDE. L'ambiente desktop KDE contiene come componenti principali il gestore di finestre kwm, il gestore dei file kfm ed il pannello di esecuzione kpanel, oltre a varie applicazioni e utility. Dopo l'uscita di KDE molti sviluppatori si interessarono a questo nuovo ambiente e a quello che poteva offrire. Le librerie KDE contengono i principali metodi e classi per rendere l'aspetto di tutte le applicazioni uniforme e coerente, in modo che l'utente ne tragga vantaggio dovendosi abituare ad un solo uso delle applicazioni, senza preoccuparsi dei pulsanti o delle finestre di dialogo. I programmi KDE si integrano con il desktop e se vengono usate tutte le funzionalità delle librerie possono interagire con il gestore file con il trascinamento, utilizzare la gestione della sessione e molto altro. </para>
<para>Sia Qt che le librerie KDE sono implementate in C++, e le applicazioni che le utilizzano sono scritte principalmente in questo linguaggio. Nel prossimo capitolo verranno analizzate queste librerie per vedere cosa contengono e come vengono create le applicazioni Qt e KDE. </para>
<sect1 id="c2s1">
<title>Il toolkit Qt</title>
<para>Come detto la libreria Qt è un insieme di strumenti che offrono tutti gli elementi grafici usati per applicazioni GUI che sono necessari per la programmazione su X-Window. Oltre a questo gli strumenti offrono: <itemizedlist>
<listitem><para>Un completo insieme di classi e metodi pronti per l'uso anche per la programmazione di applicazioni non grafiche</para></listitem>
<listitem><para>Una buona soluzione per l'interazione con l'utente tramite metodi virtuali e il meccanismo dei segnali e degli slot</para></listitem>
<listitem><para>Un insieme di elementi GUI predefiniti chiamati "widget" che possono essere facilmente usati per creare elementi visibili</para></listitem>
<listitem><para>Finestre che vengono usate frequentemente nelle applicazioni come finestre di avanzamento e finestre di dialogo per i file.</para></listitem>
</itemizedlist>
</para>
<para>La conoscenza delle classi Qt è molto importante, anche se si desidera programmare solo applicazioni KDE. Per capire i concetti di base sulla costruzione e compilazione di applicazioni GUI si esaminerà prima un programma Qt di esempio, e in seguito si estenderà l'esempio ad un programma KDE. </para>
<sect2 id="c2s1s1">
<title>La prima applicazione Qt</title>
<para>Normalmente i programmi in C++ devono contenere una funzione <function>main()</function>, che è il punto di partenza della loro esecuzione. Siccome devono essere visibili graficamente in finestre e devono interagire con l'utente, per prima cosa si deve sapere come visualizzarli. Come esempio si esaminerà il primo tutorial incluso nella documentazione di riferimento in linea di Qt e verranno spiegate le fasi di esecuzione e le modalità di visualizzazione dell'applicazione: <programlisting>#include &lt;qapplication.h>
#include &lt;qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello world!", 0 );
hello.resize( 100, 30 );
a.setMainWidget( &amp;hello );
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>Questa applicazione disegna soltanto una finestra contenente un pulsante che ha come testo "Hello world!". Come per tutte le applicazioni basate su Qt è necessario creare per prima cosa una istanza della classe <classname>QApplication</classname>, rappresentata dalla variabile a. </para>
<para>Successivamente il programma crea una istanza della classe <classname>QPushButton</classname> chiamata hello, che rappresenta il pulsante. Il costruttore di hello riceve una stringa come parametro, contenente il testo visualizzato nel pulsante. </para>
<para>Poi viene chiamato il metodo <methodname>resize()</methodname> del pulsante hello. Esso cambia la grandezza predefinita del widget (che in questo caso è <classname>QPushButton</classname>) che è stato creato, impostandolo con una lunghezza di 100 pixel e una altezza di 30 pixel. Infine viene chiamato il metodo setMainWidget() dell'oggetto a e il metodo show() di hello. La QApplication viene infine eseguita con l'istruzione <methodname>a.exec()</methodname> che farà entrare l'applicazione nel ciclo degli eventi principale (main event loop) dove attenderà fino alla restituzione di un valore intero al sistema operativo e terminerà la sua esecuzione. </para>
</sect2>
<sect2 id="c2s1s2">
<title>La documentazione di riferimento per Qt</title>
<para>Adesso si effettuerà un veloce esame della documentazione di riferimento delle librerie Qt. Avviare &tdevelop; e selezionare "Qt" dall'albero nella linguetta della documentazione. Il browser della documentazione si aprirà mostrando la pagina iniziale. Questa sarà il primo posto in cui ricercare informazioni su Qt, sulle sue classi e sulle funzioni disponibili. Il programma qui sopra è il primo della sezione dei tutorial. Per avere informazioni sulle classi <classname>QApplication</classname> e <classname>QPushButton</classname> selezionare "Lista delle classi in ordine alfabetico" e cercare il loro nome. Seguire il collegamento per visualizzare la documentazione relativa alla classe. </para>
<para>In alternativa si può consultare la <ulink url="doc.trolltech.com">documentazione Qt</ulink> di Trolltech. </para>
<para>Per <classname>QApplication</classname> si potranno vedere il costruttore e tutti gli altri metodi forniti da questa classe. Se si segue il collegamento verranno mostrate ulteriori informazioni sull'uso e sul significato del metodo, che sono molto utili quando non si ricorda il corretto utilizzo o si vuole vedere un esempio. Questo vale anche per la documentazione delle librerie KDE, che utilizzano un sistema simile; perciò questo è tutto quello che si deve sapere sulla consultazione della documentazione di riferimento. </para>
<sect3 id="c2s1s2s1">
<title>Capire l'esempio</title>
<para>Iniziando con <classname>QApplication</classname> si troveranno tutti i metodi utilizzati in questo primo esempio: <itemizedlist>
<listitem><para>il costruttore <methodname>QApplication()</methodname></para></listitem>
<listitem><para>il metodo <methodname>setMainWidget()</methodname></para></listitem>
<listitem><para>il metodo <methodname>exec()</methodname></para></listitem>
</itemizedlist>
</para>
<para>Capire perché vengono usati questi metodi è molto semplice: <orderedlist>
<listitem><para>Si crea una istanza della classe <classname>QApplication</classname> con il costruttore, così si possono usare gli elementi della GUI forniti da Qt</para></listitem>
<listitem><para>Si crea un widget che sarà contenuto nella finestra del programma</para></listitem>
<listitem><para>Si imposta il widget come il widget grafico principale per a</para></listitem>
<listitem><para>Si esegue l'istanza di <classname>QApplication</classname> di nome a</para></listitem>
</orderedlist>
</para>
<para>Il secondo oggetto del nostro programma è il pulsante, una istanza della classe <classname>QPushButton</classname>. Tra i due costruttori che creano una istanza del pulsante verrà usato il secondo: esso accetta un testo, che è l'etichetta del pulsante; in questo caso è la stringa "Hello World!". Dopo si chiama il metodo <methodname>resize()</methodname> per modificare la dimensione del pulsante - il pulsante deve essere più largo per rendere la stringa completamente visibile. </para>
<para>Qual è lo scopo del metodo <methodname>show()</methodname>? Come la maggior parte dei widget, la classe <classname>QPushButton</classname> ha una singola ereditarietà e la sua classe base è <classname>QButton</classname>. Seguire il collegamento relativo alla classe <classname>QButton</classname>; verranno visualizzati molti altri widget che ereditano da <classname>QPushButton</classname>, che saranno illustrati in seguito per spiegare il meccanismo segnale/slot. Siccome il metodo <methodname>show()</methodname> non è elencato deve essere un metodo ereditato. La classe <classname>QButton</classname> eredita da <classname>TQWidget</classname>. Seguendo nuovamente il collegamento saranno mostrati un gruppo di metodi forniti da quest'ultima classe, tra cui il metodo <methodname>show()</methodname>. Ora si può capire cosa accade nell'esempio: <orderedlist>
<listitem><para>Si crea una istanza di <classname>QPushButton</classname> usando il secondo costruttore in modo da impostare il testo del pulsante</para></listitem>
<listitem><para>Si ridimensiona il widget in base al suo contenuto</para></listitem>
<listitem><para>Si imposta il widget come quello principale dell'istanza a della classe <classname>QApplication </classname></para></listitem>
<listitem><para>Si indica al widget di mostrarsi sul video chiamando <methodname>show()</methodname>, un metodo derivato dalla classe <classname>TQWidget</classname></para></listitem>
</orderedlist>
</para>
<para>Dopo aver chiamato il metodo <methodname>exec()</methodname> l'applicazione è visibile all'utente e mostra una finestra con il pulsante contente "Hello World!". Nota: I programmi GUI hanno un comportamento piuttosto diverso dalle applicazioni procedurali: l'applicazione entra nel cosiddetto "ciclo principale degli eventi" ("main event loop"), dove attende le azioni dell'utente e reagisce ad esse. Anche nelle applicazioni Qt il programma deve essere in questo ciclo per poter gestire gli eventi. La prossima sezione spiega brevemente cosa offrono le librerie Qt per la gestione degli eventi generati dell'utente. </para>
<note><para>Per gli utenti più esperti: il pulsante non ha la dichiarazione del genitore nel costruttore, quindi è un widget top-level e viene eseguito in un ciclo di eventi locale che non ha bisogno di attendere il ciclo principale degli eventi. Vedere la documentazione della classe TQWidget e la guida di riferimento della libreria KDE</para>
</note>
</sect3>
</sect2>
<sect2 id="c2s1s3">
<title>Interazione con l'utente</title>
<para>Dopo la lettura dell'ultima sezione si dovrebbe conoscere: <itemizedlist>
<listitem><para>Cosa fornisce la libreria Qt per le applicazioni GUI</para></listitem>
<listitem><para>Come viene creato un programma che utilizza Qt e </para></listitem>
<listitem><para>Dove e come trovare, tramite il browser della documentazione, le informazioni riguardanti le classi che si vogliono usare</para></listitem>
</itemizedlist>
</para>
<para>Ora passiamo a dare "vita" all'applicazione elaborando gli eventi dell'utente. Generalmente l'utente ha due modi per interagire con un programma: il mouse e la tastiera. Per entrambi l'interfaccia grafica utente deve fornire metodi per intercettare le azioni e metodi che eseguono qualcosa in risposta a queste azioni. </para>
<para>Il sistema grafico invia tutti gli eventi di interazione all'applicazione corrispondente. La classe <classname>QApplication</classname> li invia alla finestra attiva come oggetti <classname>QEvent</classname> e i widget dovranno decidere cosa farne. Un widget riceve l'evento ed elabora <methodname>TQWidget::event(QEvent*)</methodname>, il quale decide quale evento è stato eseguito e come reagire; <methodname>event()</methodname> è il gestore principale degli eventi. In seguito il metodo <methodname>event()</methodname> passa l'evento ai cosiddetti filtri di evento che determinano cosa è successo e cosa fare con l'evento. Se non esiste un filtro assegnato come responsabile per l'evento, saranno chiamati i gestori specializzati per quell'evento. Quindi possiamo decidere tra: <itemizedlist>
<listitem><para>Eventi di tastiera -- tasti Tab e Shift-Tab:</para>
<itemizedlist>
<listitem><para><methodname>virtual void focusInEvent(QFocusEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void focusOutEvent(QFocusEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Tutti gli input dagli altri tasti:</para>
<itemizedlist>
<listitem><para><methodname>virtual void keyPressEvent(QKeyEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void keyReleaseEvent(QKeyEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Movimenti del mouse:</para>
<itemizedlist>
<listitem><para><methodname>virtual void mouseMoveEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void enterEvent(QEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void leaveEvent(QEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Azioni del pulsante del mouse</para>
<itemizedlist>
<listitem><para><methodname>virtual void mousePressEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void mouseReleaseEvent(QMouseEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void mouseDoubleClickEvent(QMouseEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
<listitem><para>Eventi della finestra contenente il widget</para>
<itemizedlist>
<listitem><para><methodname>virtual void moveEvent(QMoveEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void resizeEvent(QResizeEvent *)</methodname></para></listitem>
<listitem><para><methodname>virtual void closeEvent(QCloseEvent *)</methodname></para></listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</para>
<para>Notare che tutte le funzioni degli eventi sono virtuali e protette; quindi si possono reimplementare gli eventi per i propri widget e specificare come essi debbano rispondere. <classname>TQWidget</classname> contiene inoltre qualche altro metodo virtuale che può essere utile nei programmi. </para>
</sect2>
<sect2 id="c1s2s4">
<title>Interazione degli oggetti attraverso segnali e slot</title>
<para>Si è giunti al più ovvio vantaggio degli strumenti Qt: il meccanismo dei segnali e degli slot. Questi offrono una comoda soluzione all'interazione tra oggetti, che in X-Window viene normalmente risolta con funzioni di callback. Siccome questa comunicazione richiede una programmazione rigorosa e a volte rende la creazione di interfacce grafiche molto difficile (come riportato della documentazione Qt e dimostrato in Programming with Qt di K.Dalheimer), Troll Tech ha inventato un nuovo sistema, dove gli oggetti emettono segnali che possono essere connessi ai metodi dichiarati come slot. Il programmatore C++ deve solamente conoscere alcune cose riguardo questo meccanismo: <itemizedlist>
<listitem><para>la dichiarazione di una classe che usa i segnali e gli slot deve contenere la macro TQ_OBJECT all'inizio (senza il punto e virgola) e deve ereditare dalla classe <classname>TQObject</classname> </para></listitem>
<listitem><para>un segnale può essere emesso tramite la parola chiave emit, es: emit signal(parametri); dall'interno di qualunque membro di una classe che permette l'uso di segnali e slot </para></listitem>
<listitem><para>tutti i segnali utilizzati dalle classi che non sono ereditati devono essere aggiunti alla dichiarazione di classe in una sezione dedicata ai segnali </para></listitem>
<listitem><para>tutti i metodi che possono essere connessi ad un segnale sono dichiarati in sezioni con la parola chiave aggiuntiva slot, es: public slot: all'interno della dichiarazione della classe </para></listitem>
<listitem><para>il compilatore per i meta-oggetti moc deve essere eseguito sul file di intestazione per espandere le macro e produrre l'implementazione (che non è necessario conoscere). I file di output dal moc saranno successivamente compilati anche dal compilatore C++. </para></listitem>
</itemizedlist>
</para>
<para>Un'altra strada per utilizzare i segnali senza derivare da <classname>TQObject</classname> è utilizzare la classe <classname>QSignal</classname> - vedere la documentazione di riferimento per ulteriori informazioni ed esempi di utilizzo. Nel seguito si presuppone che si stia derivando dalla classe <classname>TQObject</classname>. </para>
<para>In questo modo la classe può inviare ovunque segnali ed avere degli slot a cui collegare tali segnali. Utilizzando i segnali non ci si deve preoccupare di chi li riceverà - si deve solo emettere il segnale e connettere un qualunque slot che risponderà all'evento. Inoltre gli slot possono essere utilizzati come normali metodi durante l'implementazione. </para>
<para>Per connettere un segnale ad uno slot si devono utilizzare i metodi <methodname>connect()</methodname> messi a disposizione dalla classe <classname>TQObject</classname> o, quando disponibile, metodi speciali forniti dagli oggetti per impostare la connessione ad un determinato segnale. </para>
<sect3 id="c1s2s4s1">
<title>Semplice utilizzo</title>
<para>Per illustrare l'interazione tra gli oggetti si estenderà il primo esempio aggiungendo una semplice connessione: <programlisting>#include &lt;qapplication.h>
#include &lt;qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello world!" , 0);
hello.resize( 100, 30 );
a.setMainWidget( &amp;hello );
TQObject::connect(&amp;hello, TQ_SIGNAL( clicked() ), &amp;a, TQ_SLOT( quit() ));
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>Come si può vedere, l'unica modifica richiesta per dare maggiore interazione al pulsante consiste nell'utilizzare il metodo <methodname>connect()</methodname>: tutto quello che si deve aggiungere è <methodname>connect(&amp;hello,TQ_SIGNAL( clicked() ), &amp;a,TQ_SLOT( quit() ))</methodname>. Cosa significa? La dichiarazione del metodo <methodname>connect()</methodname> nella classe TQObject è: </para>
<para><methodname>bool connect ( const TQObject * sender, const char * signal, const TQObject * receiver, const char * member ) </methodname></para>
<para>Si deve specificare come primo parametro un puntatore ad una istanza di <classname>TQObject</classname> che trasmette il segnale, ovvero che può emettere questo segnale; poi si specifica il segnale che si vuole connettere. Gli ultimi due parametri sono l'oggetto ricevitore che fornisce uno slot, seguito dalla funzione membro che in effetti è lo slot che sarà eseguito dopo l'emissione del segnale. </para>
<para>Utilizzando i segnali e gli slot gli oggetti dei proprio programma potranno interagire tra loro facilmente senza dipendere esplicitamente dal tipo dell'oggetto ricevente. Nei capitoli seguenti verrà spiegato come utilizzare in maniera produttiva questo meccanismo. Ulteriori informazioni sui segnali e gli slot possono essere trovati nella <ulink url="developer kde.org/documentation/library/libraryref.html">Guida di riferimento della libreria KDE</ulink> e nella <ulink url="doc.trolltech.com">documentazione Qt di riferimento</ulink>. </para>
</sect3>
</sect2>
</sect1>
<sect1 id="c2s3">
<title>Cosa fornisce KDE</title>
<sect2 id="c2s3s1">
<title>Le librerie KDE 3.x</title>
<para>Le principali librerie KDE che verranno utilizzate per la creazione di applicazioni KDE sono: <itemizedlist>
<listitem><para>la libreria tdecore, contenente tutte le classi degli elementi senza rappresentazione grafica che forniscono funzionalità all'applicazione </para></listitem>
<listitem><para>la libreria tdeui, contenente gli elementi dell'interfaccia grafica come barre dei menu, barre degli strumenti, ecc. </para></listitem>
<listitem><para>la libreria tdefile, contenente le finestre di dialogo per la selezione di file </para></listitem>
</itemizedlist>
</para>
<para>Inoltre KDE offre le seguenti librerie, dedicate a soluzioni specifiche: <itemizedlist>
<listitem><para>la libreria tdefx, contenente pixmap, effetti grafici e TDEStyle, l'estensione di QStyle </para></listitem>
<listitem><para>la libreria tdehtml, contenente il componente html di KDE </para></listitem>
<listitem><para>la libreria kjs, contenente il supporto JavaScript di KDE </para></listitem>
<listitem><para>la libreria tdeio, contenente l'accesso a basso livello ai file di rete </para></listitem>
<listitem><para>la libreria tdeparts, contenente il supporto per il riutilizzo delle applicazioni estendibili ed incapsulabili </para></listitem>
</itemizedlist>
</para>
<para>Successivamente si vedrà cosa è necessario per trasformare la prima applicazione Qt in una KDE. </para>
</sect2>
<sect2 id="c2s3s2">
<title>Esempio di application KDE</title>
<para>Scrivere una applicazione KDE non è molto più difficile che scrivere una applicazione Qt. Per usare le funzionalità di KDE si devono solo usare alcune altre classi e nient'altro. Come esempio verra discussa la versione modificata del precedente esempio Qt: <programlisting>#include &lt;tdeapplication.h>
#include &lt;qpushbutton.h>
int main( int argc, char **argv )
{
TDEApplication a( argc, argv );
QPushButton hello( "Hello world!", 0 );
hello.resize( 100, 30 );
a.setTopWidget( &amp;hello );
TQObject::connect(&amp;hello, TQ_SIGNAL( clicked() ), &amp;a, TQ_SLOT( quit() ));
hello.show();
return a.exec();
}
</programlisting>
</para>
<para>Per prima cosa è stata cambiata la classe <classname>QApplication</classname> con la classe <classname>TDEApplication</classname>. Inoltre è stato cambiato il metodo <methodname>setMainWidget()</methodname> usato precedentemente con il metodo <methodname>setTopWidget</methodname>, che viene usato da <classname>TDEApplication</classname> per impostare il widget principale. Ecco qua! La prima applicazione KDE è pronta - ora si deve solo indicare al compilatore il percorso di inclusione di KDE e al linker di collegare la libreria kdecode con l'opzione -ltdecore. </para>
<para>Ora che si conosce cosa fornisce la funzione <function>main()</function>, come rendere visibile l'applicazione e come gli oggetti interagiscono con l'utente, nel prossimo capitolo verrà creata una applicazione con &tdevelop;. Potremo quindi applicare e verificare quanto detto precedentemente. </para>
<para>Prima di proseguire si dovrebbe consultare la documentazione di riferimento di Qt, in particolare le classi <classname> QApplication</classname>, <classname>TQWidget</classname> e <classname>TQObject</classname>, e la documentazione della libreria tdecore per la classe <classname>TDEApplication </classname>. Il <ulink url="developer.kde.org/documentation/library/libraryref.html">manuale di riferimento delle librerie KDE</ulink> include una descrizione completa sulle chiamate ai costruttori delle classi <classname>QApplication</classname> e <classname> TDEApplication</classname> e l'elaborazione degli argomenti a linea di comando. </para>
</sect2>
</sect1>
</chapter>
<chapter id="chapter3">
<title>Creare una nuova applicazione</title>
<sect1 id="c3s1">
<title>La procedura guidata per le applicazioni</title>
<para>La procedura guidata per le applicazioni permette di iniziare a lavorare ad un nuovo progetto con &tdevelop;. Tutti i progetti vengono prima creati dalla procedura guidata, e in seguito si possono compilare e ampliare. A seconda dei propri obiettivi si può scegliere il tipo di progetto: <itemizedlist>
<listitem><para>KDE Application Framework: include la struttura di una applicazione KDE completa </para></listitem>
<listitem><para>QMake Project: crea una di applicazione basata sul sistema di configurazione qmake di Trolltech </para></listitem>
<listitem><para>Simple hello world program: crea un programma C++ testuale senza il supporto GUI </para></listitem>
<listitem><para>Molti altri schemi di programma </para></listitem>
</itemizedlist>
</para>
<para>In questo capitolo verrà spiegato come attivare la procedura guidata per le applicazioni e come generare una applicazione KDE. Il primo passo della trattazione sarà la creazione di un semplice progetto. Per tutti gli altri tipi di progetto il metodo da usare è lo stesso, ma il numero di opzioni potrebbe essere minore. </para>
</sect1>
<sect1 id="c3s2">
<title>Avviare la procedura guidata per le applicazioni e generare il progetto</title>
<sect2 id="c3s2s1">
<title>Avviare la procedura guidata per le applicazioni</title>
<para>Per iniziare, avviare &tdevelop;. Dal menu Progetto selezionare Nuovo Progetto. Verrà avviata la procedura guidata per le applicazioni e nella prima pagina sarà visualizzato un albero di selezione contenente i tipi di progetti disponibili. Scegliere il sottoalbero C++, KDE, quindi Application Framework. </para>
<para>Per questo progetto di esempio sarà creata l'applicazione KScribble. Inserirlo come nome dell'applicazione e modificare le eventuali altre informazioni nella parte bassa dello schermo in base alle proprie preferenze. Selezionare Successivo. <screenshot><mediaobject><imageobject>
<imagedata fileref="appwizard.png" format="PNG"/>
</imageobject><textobject><phrase>Procedura guidata per le applicazioni</phrase></textobject>
</mediaobject></screenshot>
</para>
</sect2>
<sect2 id="c3s2s2">
<title>Informazioni sul controllo versione</title>
<para>Su questa schermata si può decidere se il progetto utilizzerà un sistema per il controllo delle versioni come CVS. Per questo progetto di esempio non si utilizzerà il controllo dei sorgenti, quindi assicurarsi che la selezione sia Nessuno e selezionare Successivo. </para>
</sect2>
<sect2 id="c3s2s3">
<title>Modelli dei sorgenti e delle intestazioni</title>
<para>Le due pagine successive mostrano intestazioni di esempio che saranno aggiunte all'inizio dei file di codice e di intestazione creati utilizzando &tdevelop;. Per il momento lasciare queste intestazioni come predefinite e selezionare Prossimo, quindi Fine. Se questo pulsante non è attivo significa che non sono state impostate correttamente tutte le opzioni. Usare il pulsante Precedente per tornare ai menu precedenti e correggere gli errori. </para>
</sect2>
<sect2 id="c3s2s4">
<title>Terminare</title>
<para>Dopo aver terminato, la procedura guidata per le applicazioni dovrebbe chiudersi e comparirà una finestra che visualizza alcune informazioni riguardanti le operazioni effettuate da &tdevelop;. Al termine di tutte le procedure si dovrebbe vedere il messaggio *** Success ***. Questo significa che il framework dell'applicazione è stato creato correttamente. </para>
</sect2>
</sect1>
<sect1 id="c3s3">
<title>La prima compilazione</title>
<para>Dopo la generazione del progetto, per prima cosa si osserveranno i sorgenti per avere una comprensione generale del funzionamento dell'applicazione, in modo da sapere cosa e dove effettuare delle modifiche. </para>
<para>Questo capitolo presume che si conosca la navigazione base di &tdevelop;. Se necessario consultare il manuale utente di KDevelop. </para>
<para>Il gestore Automake visualizza i file di progetto come segue: <screenshot><mediaobject><imageobject>
<imagedata fileref="kscribblefiles.png" format="PNG"/>
</imageobject><textobject><phrase>I file nel progetto</phrase></textobject>
</mediaobject></screenshot>
</para>
<para>Prima di osservare i sorgenti, compilare ed eseguire l'applicazione. Per farlo selezionare Compila Progetto dal menu Compila o premere F8. Apparirà una finestra di output dove verranno visualizzati vari messaggi durante la fase di compilazione. <programlisting>1 cd /home/caleb/kscribble &amp;&amp; WANT_AUTOCONF_2_5=1 WANT_AUTOMAKE_1_6=1 gmake k
2 gmake all-recursive
3 gmake[1]: Entering directory `/home/caleb/kscribble'
4 Making all in doc
5 gmake[2]: Entering directory `/home/caleb/kscribble/doc'
6 Making all in .
7 gmake[3]: Entering directory `/home/caleb/kscribble/doc'
8 gmake[3]: Nothing to be done for `all-am'.
9 gmake[3]: Leaving directory `/home/caleb/kscribble/doc'
10 Making all in en
11 gmake[3]: Entering directory `/home/caleb/kscribble/doc/en'
12 /usr/local/kde3/bin/meinproc --check --cache index.cache.bz2 /home/caleb/kscribble/doc/en/index.docbook
13 gmake[3]: Leaving directory `/home/caleb/kscribble/doc/en'
14 gmake[2]: Leaving directory `/home/caleb/kscribble/doc'
15 Making all in po
16 gmake[2]: Entering directory `/home/caleb/kscribble/po'
17 gmake[2]: Nothing to be done for `all'.
18 gmake[2]: Leaving directory `/home/caleb/kscribble/po'
19 Making all in src
20 gmake[2]: Entering directory `/home/caleb/kscribble/src'
21 source='main.cpp' object='main.o' libtool=no \
22 depfile='.deps/main.Po' tmpdepfile='.deps/main.TPo' \
23 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
24 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o main.o `test -f 'main.cpp' || echo '/home/caleb/kscribble/src/'`main.cpp
25 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/kscribble.h -o kscribble.moc
26 source='kscribble.cpp' object='kscribble.o' libtool=no \
27 depfile='.deps/kscribble.Po' tmpdepfile='.deps/kscribble.TPo' \
28 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
29 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribble.o `test -f 'kscribble.cpp' || echo '/home/caleb/kscribble/src/'`kscribble.cpp
30 kscribble.cpp: In member function `void KScribble::setupActions()'
31 kscribble.cpp:107: warning: unused variable `TDEAction*custom'
32 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/kscribbleview.h -o kscribbleview.moc
33 source='kscribbleview.cpp' object='kscribbleview.o' libtool=no \
34 depfile='.deps/kscribbleview.Po' tmpdepfile='.deps/kscribbleview.TPo' \
35 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
36 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi
-D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c
-o kscribbleview.o `test -f 'kscribbleview.cpp' || echo '/home/caleb/kscribble/src/'`kscribbleview.cpp
37 kscribbleview.cpp: In member function `void KScribbleView::print(QPainter*,
38 int, int)':
39 kscribbleview.cpp:79: warning: unused parameter `QPainter*p'
40 kscribbleview.cpp:79: warning: unused parameter `int height'
41 kscribbleview.cpp:79: warning: unused parameter `int width'
42 /usr/lib/qt/bin/moc /home/caleb/kscribble/src/pref.h -o pref.moc
43 source='pref.cpp' object='pref.o' libtool=no \
44 depfile='.deps/pref.Po' tmpdepfile='.deps/pref.TPo' \
45 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
46 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o pref.o `test -f 'pref.cpp' || echo '/home/caleb/kscribble/src/'`pref.cpp
47 /usr/local/kde3/bin/dcopidl /home/caleb/kscribble/src/kscribbleiface.h > kscribbleiface.kidl ||
( rm -f kscribbleiface.kidl ; /bin/false )
48 /usr/local/kde3/bin/dcopidl2cpp --c++-suffix cpp --no-signals --no-stub kscribbleiface.kidl
49 source='kscribbleiface_skel.cpp' object='kscribbleiface_skel.o' libtool=no \
50 depfile='.deps/kscribbleiface_skel.Po' tmpdepfile='.deps/kscribbleiface_skel.TPo' \
51 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
52 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribbleiface_skel.o `test -f 'kscribbleiface_skel.cpp' ||
echo '/home/caleb/kscribble/src/'`kscribbleiface_skel.cpp
53 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall
-pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500
-D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble -R
/usr/local/kde3/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib
-L/usr/local/kde3/lib main.o kscribble.o kscribbleview.o pref.o kscribbleiface_skel.o -ltdeio
54 source='kscribble_client.cpp' object='kscribble_client.o' libtool=no \
55 depfile='.deps/kscribble_client.Po' tmpdepfile='.deps/kscribble_client.TPo' \
56 depmode=gcc3 /bin/sh /home/caleb/kscribble/admin/depcomp \
57 g++ -DHAVE_CONFIG_H -I. -I/home/caleb/kscribble/src -I.. -I/usr/local/kde3/include
-I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor
-Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings
-ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new
-c -o kscribble_client.o `test -f 'kscribble_client.cpp' || echo
'/home/caleb/kscribble/src/'`kscribble_client.cpp
58 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef
-Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500
-D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble_client -R
/usr/local/kde3/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib
-L/usr/local/kde3/lib kscribble_client.o -ltdecore
59 gmake[2]: Leaving directory `/home/caleb/kscribble/src'
60 gmake[2]: Entering directory `/home/caleb/kscribble'
61 gmake[2]: Nothing to be done for `all-am'.
62 gmake[2]: Leaving directory `/home/caleb/kscribble'
63 gmake[1]: Leaving directory `/home/caleb/kscribble'
64 *** Success ***
</programlisting>
</para>
<para>Come si può notare sono stati aggiunti i numeri di riga, che non appaiono nella finestra di output, utili per descrivere quello che succede durante la compilazione. Prima di tutto si può osservare che gmake funziona ricorsivamente. Questo significa che esso parte dalla directory nella quale è stato chiamato e prosegue all'interno di tutte le sottodirectory, una per volta, quindi ritorna alla directory di partenza, la elabora e termina. </para>
<para>La prima linea interessante è la 24. Notare che g++, il compilatore C++, viene chiamato da make per compilare il primo file di codice sorgente del progetto - in questo caso main.cpp. Il compilatore g++ usa molte altre opzioni, alcune delle quali sono predefinite mentre altre possono essere configurate con &tdevelop;. </para>
<para>Prima che venga compilato il prossimo file (kscribble.cpp, linea 29), il moc (compilatore dei meta oggetti) viene chiamato per kscribble.h (linea 25). Le classi di KScribble utilizzano i segnali e gli slot, quindi il moc deve espandere la macro TQ_OBJECT. Il file risultante, kscribble.moc, verrà utilizzato da kscribble.cpp tramite la direttiva #include all'interno del file. </para>
</sect1>
<sect1 id="c3s4">
<title>Sorgenti della struttura del progetto</title>
<para>Per capire come funziona un'applicazione KDE, si esamineranno i sorgenti della struttura del progetto creati dalla procedura guidata. Come detto in precedenza è presente un insieme di file sorgente e header che costituiscono il codice sorgente iniziale dell'applicazione e la rendono pronta ad essere eseguita. Il modo più semplice per illustrare il codice consiste nel seguire l'implementazione linea per linea man mano che viene elaborata fino a quando entra nel ciclo degli eventi principale ed è pronta a ricevere l'input dell'utente. Dopo si esamineranno le funzionalità che permettono l'interazione dell'utente e altre caratteristiche. Questo probabilmente è il miglior modo per spiegare il framework e, siccome è simile a quasi tutte le applicazioni KDE, permette di capire il codice sorgente di altri progetti; inoltre si imparerà a modificare il codice per far funzionare l'applicazione nel modo in cui era stata progettata. </para>
<sect2 id="c3s4s1">
<title>La funzione main()</title>
<para>L'applicazione inizia la sua esecuzione entrando nella funzione <function>main()</function>, quindi si partirà da qui ad esaminare il codice. La funzione <function>main()</function> di KScribble è implementata in main.cpp e può essere trovata utilizzando il browser delle classi selezionando la cartella "Funzioni Globali". <programlisting>1 int main(int argc, char **argv)
2 {
3 TDEAboutData about("kscribble", I18N_NOOP("KScribble"), version, description,
4 TDEAboutData::License_GPL, "(C) 2002 Your Name", 0, 0, "you@you.com");
5 about.addAuthor( "Your Name", 0, "you@you.com" );
6 TDECmdLineArgs::init(argc, argv, &amp;about);
7 TDECmdLineArgs::addCmdLineOptions(options);
8 TDEApplication app;
9
10 // register ourselves as a dcop client
11 app.dcopClient()->registerAs(app.name(), false);
12
13 // see if we are starting with session management
14 if (app.isRestored())
15 RESTORE(KScribble)
16 else
17 {
18 // no session.. just start up normally
19 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
20 if (args->count() == 0)
21 {
22 KScribble *widget = new KScribble;
23 widget->show();
24 }
25 else
26 {
27 int i = 0;
28 for (; i &lt; args->count(); i++)
29 {
30 KScribble *widget = new KScribble;
31 widget->show();
32 widget->load(args->url(i));
33 }
34 }
35 args->clear();
36 }
37
38 return app.exec();
39 }
</programlisting>
</para>
<para>Viene per prima cosa creato il solito oggetto <classname>TDEApplication</classname>, ma sono stati aggiunti alcuni metodi che impostano le informazioni sul programma sull'autore per questa applicazione. </para>
</sect2>
<sect2>
<title>Avvio Applicazione Utente</title>
<para>... (non ancora scritto)</para>
</sect2>
<sect2>
<title>Il costruttore</title>
<para>Si esaminerà il costruttore per vedere come viene chiamata questa istanza <programlisting>1 KScribble::KScribble()
2 : TDEMainWindow( 0, "KScribble" ),
3 m_view(new KScribbleView(this)),
4 m_printer(0)
5 {
6 // accept dnd
7 setAcceptDrops(true);
8
9 // tell the TDEMainWindow that this is indeed the main widget
10 setCentralWidget(m_view);
11
12 // then, setup our actions
13 setupActions();
14
15 // and a status bar
16 statusBar()->show();
17
18 // allow the view to change the statusbar and caption
19 connect(m_view, TQ_SIGNAL(signalChangeStatusbar(const TQString&amp;)),
20 this, TQ_SLOT(changeStatusbar(const TQString&amp;)));
21 connect(m_view, TQ_SIGNAL(signalChangeCaption(const TQString&amp;)),
22 this, TQ_SLOT(changeCaption(const TQString&amp;)));
23
24 }
</programlisting>
</para>
<para>Notare che <classname>KScribble</classname> deriva da <classname>TDEMainWindow</classname> - usata frequentemente come classe base per le applicazioni KDE. Viene inizializzata una classe chiamata <classname>KScribbleView </classname> come widget centrale, viene creata una classe <classname>KStatusBar</classname> tramite il metodo <methodname>statusBar()</methodname> (linea 16) e vengono connessi alcuni segnali e slot. </para>
</sect2>
</sect1>
</chapter>
<chapter id="chapter4">
<title>Progettare la vista dell'applicazione</title>
<sect1 id="c4s1">
<title>Introduzione</title>
<para>Nello sviluppo di un'applicazione con interfaccia grafica il lavoro più oneroso consiste nel creare la cosiddetta "vista" dell'applicazione. In generale una vista è un widget che visualizza i dati di un documento e fornisce metodi per manipolare il suo contenuto. Questo può essere fatto dall'utente per mezzo degli eventi emessi tramite tastiera o il mouse; le operazioni più complesse sono spesso elaborate dalle barre degli strumenti e dalle barre dei menu, le quali interagiscono con le viste e con il documento. La barra di stato fornisce informazioni sullo stato del documento, della vista e dell'applicazione. Come esempio verrà esaminato come funziona un editor e dove si possono trovare i vari componenti. </para>
<para>In generale un editor dovrebbe fornire una interfaccia per la vista e/o cambiare i contenuti di un documento di testo per l'utente. Se si avvia Kate si vedrà l'interfaccia visuale come segue: <itemizedlist>
<listitem><para>la barra dei menu: fornisce operazioni complesse come apertura, salvataggio e chiusura dei file ed uscita dall'applicazione. </para></listitem>
<listitem><para>la barra degli strumenti: contiene icone che permettono un veloce accesso alle funzioni più importanti, </para></listitem>
<listitem><para>la barra di stato: mostra la posizione del cursore visualizzando l'attuale numero di riga e di colonna, </para></listitem>
<listitem><para>La vista al centro della finestra, che visualizza un documento e contiene un cursore connesso alla tastiera ed al mouse per operare sui dati. </para></listitem>
</itemizedlist>
</para>
<para>É semplice capire che una vista è il componente più specifico di una applicazione e la sua progettazione influenza l'usabilità dell'applicazione. Questo significa che nelle prime fasi dello sviluppo si determinano lo scopo dell'applicazione e il tipo di vista più corrispondente alle necessità dell'utente che dovrà impiegare uno sforzo minimo per gestire l'interfaccia grafica. </para>
<para>Per la modifica dei testo e la visualizzazione di file HTML, le viste sono fornite dalle librerie Qt e KDE; nella prossima sezione verranno discussi alcuni aspetti di questi widget di alto livello, tuttavia per moltissime applicazioni devono essere progettati ed implementati nuovi widget. Questo è ciò che rende un programmatore anche un progettista e dove viene richiesta la sua creatività. Prima di tutto ci si deve concentrare sulla intuitività. Ricordarsi molti utenti non accetteranno una applicazione che non sia: <itemizedlist>
<listitem><para>graficamente gradevole </para></listitem>
<listitem><para>con molte funzionalità </para></listitem>
<listitem><para>facile da gestire </para></listitem>
<listitem><para>veloce da imparare </para></listitem>
</itemizedlist>
</para>
<para>Non c'è bisogno di dire che la stabilità è l'obiettivo principale della progettazione. Nessuno può evitare gli errori, ma si può almeno effettuare una progettazione saggia e orientata agli oggetti. Il linguaggio C++ rende la programmazione un piacere se si sfruttano le sue capacità come ereditarietà, incapsulamento e riuso del codice già esistente. </para>
<para>Quando si crea un progetto KDE o Qt, si dovrà avere sempre una vista che deriva da TQWidget per ereditarietà diretta o perché il widget di libreria che si vuole usare deriva da TQWidget. Quindi la procedura guidata per l'applicazioni crea una vista che è istanza di una classe di nome NomeApplicazioneView che deriva da TQWidget. </para>
<para>Questo capitolo descrive come usare i widget delle librerie per creare viste di applicazioni KDE o Qt che sono generate con &tdevelop;, in seguito si esamineranno le librerie e i tipi di viste disponibili. </para>
</sect1>
<sect1 id="c4s2">
<title>Usare le viste delle librerie</title>
<para>Quando è stata impostata la progettazione dell'applicazione, si dovrebbe cercare del codice già esistente che può rendere lo sviluppo molto più facile. Si può controllare se esiste un widget che può essere usato come vista o almeno come parte di essa, sia usandolo direttamente che derivandolo. Le librerie KDE e Qt contengono un insieme di widget che possono essere usati a questo scopo in due modi: <orderedlist>
<listitem><para>Rimuovendo la nuova classe per la vista, creare una istanza di un widget di libreria e poi impostare quest'ultimo come vista, </para></listitem>
<listitem><para>Impostando il widget di libreria che si vuole usare come classe base della vista </para></listitem>
</orderedlist>
</para>
<para>In entrambi i casi, è importante sapere che se l'applicazione non è collegata con la libreria che contiene il widget non riuscirà ad essere compilata. Dopo aver deciso di usare un certo widget, cercare la libreria da collegare, quindi aprire "Progetto"->"Opzioni" dalla barra dei menu di &tdevelop;, andare nella linguetta "Opzioni del linker" e cercare le caselle che indicano le librerie che sono attualmente utilizzate. Se la libreria del componente visuale è già selezionata, lasciare inalterate le opzioni di progetto e iniziare a fare i cambiamenti nel progetto. In caso contrario, se le opzioni del linker permettono di aggiungere la libreria attraverso una casella di selezione, selezionala e premere "OK" per chiudere la finestra di dialogo delle opzioni. In tutti gli altri casi, aggiungere la libreria nella casella di testo in basso con l'opzione -l. Per le librerie che devono essere trovate dallo script configure prima che vengano generati i Makefile, aggiungere la macro corrispondente alla libreria al file configure.in posizionato nella cartella radice dell'applicazione e aggiungere la macro nella casella di testo. Ricordarsi di selezionare prima "Compila"->"Autoconf e automake" e "Compila"->"Configura" in modo che i Makefile contengano la corretta espansione della macro per la libreria. </para>
<para>Inoltre, se i file di inclusione per la libreria da aggiungere non sono nel percorso corrente (che può essere visualizzato tramite l'opzione -I della finestra di output di "Make"), si deve aggiungere il percorso alla finestra di dialogo delle opzioni del progetto nella pagina "Opzioni di Compilazione" con l'opzione -I o con la macro automake corrispondente nella casella di testo "Informazioni Aggiuntive". </para>
<sect2 id="c4s3s1">
<title>Viste Qt</title>
<para>Nella prima pagina della documentazione Qt in linea è presente un collegamento alle "schermate dei widget" dove si può osservare l'aspetto dei widget. Questi widget sono pronti per essere utilizzati direttamente o combinati assieme formando widget più complessi per creare viste di applicazioni o finestre di dialogo. In seguito saranno discussi alcuni di essi che sono utilizzabili per creare viste di applicazioni, ma ricordarsi che le librerie KDE contengono widget alternativi che servono agli stessi scopi; questi verranno esaminati nella prossima sezione. </para>
<para>Ecco una serie di suggerimenti per scegliere il componente Qt da usare per un particolare scopo <orderedlist>
<listitem><para>Se l'area di vista non è abbastanza grande per visualizzare tutti i dati, l'utente deve poter scorrere il documento con le barre poste a lato e in basso. Qt fornisce la classe <classname>QScrollView</classname> che offre un'area figlio scorrevole. Si può derivare il proprio widget da questa classe o utilizzare una sua istanza. </para></listitem>
<listitem><para>per creare uno ScrollView, derivare il widget per la vista da <classname>TQWidget</classname> e aggiungere una barra di scorrimento orizzontale ed una verticale <classname>QScrollBars</classname>. (Questo viene fatto dal widget TDEHTMLViews di KDE.) </para></listitem>
<listitem><para>Per l'elaborazione del testo, usare <classname>QTextEdit</classname>. Questa classe include un widget per il testo completo che dispone delle funzionalità per tagliare, copiare e incollare testo ed è gestito da barre di scorrimento. </para></listitem>
<listitem><para>Usare la classe <classname>QTable</classname> per visualizzare i dati organizzati in una tabella. Siccome questa classe è gestita da barre di scorrimento, costituisce una buona soluzione per le applicazioni di calcolo con tabelle. </para></listitem>
<listitem><para>Per visualizzare due widget diversi o due istanze contemporaneamente,utilizzare la classe <classname>QSplitter</classname>. Questa permette di affiancare le viste verticalmente o orizzontalmente. Per osservare questo elemento grafico si può prendere come esempio KMail: la vista principale è separata da un divisore verticale, e la finestra a destra è a sua volta separata orizzontalmente. </para></listitem>
<listitem><para><classname>QListView</classname> visualizza informazioni in una lista e in un albero. Questo è utile per gli alberi file o per altre informazioni organizzate in maniera gerarchica con le quali si vuole interagire. </para></listitem>
</orderedlist>
</para>
<para>Si può vedere come Qt fornisca un ampio insieme di widget pronti da usare che, nel caso corrispondano alle proprie esigenze, eviteranno la ricerca di nuove soluzioni. Quando si usano dei widget standard gli utenti sanno già come utilizzarli e possono concentrarsi solo sui dati visualizzati. </para>
</sect2>
<sect2 id="c4s3s2">
<title>Viste KDE</title>
<para>Le librerie KDE sono state inventate per sviluppare facilmente applicazioni per l'ambiente desktop KDE e hanno più funzionalità di quelle fornite da Qt.La libreria tdeui contiene: <orderedlist>
<listitem><para>TDEListView: una versione più potente di <classname>QListView</classname> </para></listitem>
<listitem><para>TDEIconView: una vista grafica di file ad icona </para></listitem>
</orderedlist>
</para>
<para>La libreria tdehtml, d'altro canto, offre un widget per la completa interpretazione del linguaggio HTML già pronto all'uso. Non si deve implementare lo scorrimento perché è già supportato. Si può integrare come un widget che visualizza un'anteprima per un editor HTML e viene usato da applicazioni come Konqueror per visualizzare i file HTML. </para>
</sect2>
</sect1>
<sect1 id="c4s4">
<title>Creare le proprie viste</title>
<para>Non ancora scritto </para>
</sect1>
</chapter>
<chapter id="chapter5">
<title>Configurare le barre dei menu e le barre degli strumenti</title>
<sect1 id="c5s1">
<title>Introduzione</title>
<para>Le barre dei menu e le barre degli strumenti sono tra le più importanti parti di un'applicazione per lavorare con un documento. Come regola generale si dovrebbero rendere disponibili tutte le funzionalità dell'applicazione attraverso la barra dei menu. </para>
<para>Inoltre, una applicazione può contenere una sola barra dei menu, ma diverse barre degli strumenti. D'altro lato, queste ultime dovrebbero visualizzare solo i comandi usati frequentemente attraverso icone o caselle di scelta multipla. </para>
</sect1>
<sect1 id="c5s2">
<title>Come funziona?</title>
<para>L'applicazione deriva dalla classe <classname>TDEMainWindow</classname>, che automaticamente crea una barra dei menu e una barra degli strumenti. Nel metodo <methodname>KScribble::setupActions()</methodname> c'è una chiamata al metodo <methodname>TDEMainWindow::createGUI()</methodname>, che carica un file di risorse, in questo caso kscribbleui.rc, per inizializzare i menu durante l'avvio. Notare che kscribbleur.rc è elencato all'interno dei file di progetto del gestore Automake. Il contenuto del file è questo: <programlisting>1 &lt;!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
2 &lt;kpartgui name="kscribble" version="1">
3 &lt;MenuBar>
4 &lt;Menu name="custom">&lt;text>C&amp;ustom&lt;/text>
5 &lt;Action name="custom_action" />
6 &lt;/Menu>
7 &lt;/MenuBar>
8 &lt;/kpartgui>
</programlisting>
</para>
<para>Spiegazione... </para>
<para>Un altro modo per modificare i contenuti dei menu e delle barre degli strumenti consiste nel manipolarli direttamente attraverso i metodi forniti dalle loro classi. Per esempio, il metodo <methodname>menuBar()</methodname> restituisce il widget <classname>KMenuBar</classname> che rappresenta la barra dei menu del programma. Consultando la documentazione della classe <classname>KMenuBar</classname> e della sua classe base <classname>QMenuBar</classname>, si troveranno molti metodi <methodname>insertItem()</methodname> che permettono di aggiungere elementi alla barra dei menu. </para>
<para>Anche i metodi <methodname>statusBar()</methodname> e <methodname>toolBar()</methodname> della classe <classname>TDEMainWindow</classname> forniranno i widget appropriati. </para>
</sect1>
<sect1 id="c5s3">
<title>Configurazione delle scorciatoie da tastiera</title>
<para>Le scorciatoie da tastiera costituiscono un tocco molto professionale che si dovrebbe sempre aggiungere alle applicazioni. Queste sono prevalentemente utilizzate da utenti esperti che vogliono lavorare velocemente con le loro applicazioni e vogliono imparare queste scorciatoie. Per questo le librerie KDE forniscono la classe <classname>TDEAction</classname>, che permette di utilizzare tasti scorciatoia e l'accesso alla configurazione generale degli acceleratori da tastiera standard. </para>
<para>Normalmente le applicazioni generate da &tdevelop; utilizzano solamente gli acceleratori predefiniti di tastiera come F1 per accedere alla documentazione di help in linea, CRTL+N per Nuovo File, ecc. </para>
<para>Se l'applicazione contiene molti tasti acceleratori, essi dovrebbero essere configurabili da un menu di opzioni, che potrebbe essere combinato con altre configurazione dell'applicazione in un QWidger o essere separato. La libreria KDE fornisce la classe <classname>KKeyChooser</classname> da usare nelle finestre di dialogo, mentre la classe <classname>KKeyDialog</classname> è una finestra di dialogo per la configurazione dei tasti pronta all'uso. </para>
</sect1>
</chapter>
<!--
<chapter id="chapter6">
<title>Other Features</title>
</chapter>
<chapter id="chapter7">
<title>Printing Support</title>
</chapter>
-->
<chapter id="chapter8">
<title>Funzioni di Aiuto</title>
<sect1 id="c8s1">
<title>Introduzione</title>
<para>Una parte molto importante del processo di sviluppo consiste nel fornire la funzionalità di aiuto all'utente quando possibile. Molti sviluppatori tendono a rimandare questo aspetto, ma si deve tener presente che un normale utente non è necessariamente un esperto di Unix. Egli potrebbe provenire dal lato oscuro del software che fornisce tutti gli aiuti necessari all'utente per lavorare con una applicazione senza neppure fargli aprire un manuale. Per questo le librerie KDE e Qt forniscono tutti gli strumenti che rendono una applicazione professionale agli occhi del normale utente attraverso funzioni di aiuto pronte da usare. Esse sono:</para>
<itemizedlist>
<listitem><para>tooltip</para></listitem>
<listitem><para>barra di stato</para></listitem>
<listitem><para>pulsante Che cos'è?</para></listitem>
</itemizedlist>
<para>Premendo il tasto standard di aiuto F1 l'applicazione dovrebbe visualizzare un manuale in formato HTML. Questo sistema di aiuto viene supportato direttamente dalla classe <classname>TDEMainWindow</classname>, benché l'autore debba scrivere il contenuto. </para>
<para>Siccome sia &tdevelop; che l'applicazione KDE generata dalla procedura guidata supportano tutti i vari tipi di aiuto, questo capitolo spiegherà come e dove aggiungere le funzionalità di aiuto. </para>
<para>Durante lo sviluppo dell'applicazione si dovrebbe mantenere una certa consistenza in quello che viene fatto, effettuando le fasi necessarie direttamente durante lo sviluppo del codice. In questo modo si evita di dover esaminare nuovamente il codice e cercare di capire cosa sta facendo l'applicazione o caso si intendeva fare in una certa parte del codice. </para>
</sect1>
<sect1 id="c8s2">
<title>ToolTip</title>
<para>I suggerimenti (tool-tip) costituiscono un sistema molto semplice per aiutare l'utente. Essi sono piccoli messaggi di aiuto che appaiono quando l'utente muove il mouse su un widget che fornisce il suggerimento e scompaiono quando il mouse si sposta. Vengono utilizzati frequentemente nelle barre degli strumenti; in questo caso dovrebbero essere resi più piccoli possibile poiché le barre possono essere configurate per visualizzare il loro contenuto in vari modi: mostrando un pulsante, un pulsante con testo a lato, un pulsante con testo in basso o solo testo. Questa possibilità dovrebbe essere configurabile dall'utente, ma non è obbligatorio. Per una descrizione completa vedere il riferimento della classe <classname>TDEToolBar</classname> che si trova nella libreria tdeui. </para>
<para>Come esempio, cercare il pulsante "Nuovo File" di una qualunque applicazione: </para>
<para>La funzione i18n("New File") fornisce un messaggio di suggerimento. Questo è racchiuso dalla macro i18n() fornita da tdeapplication.h per tradurre i suggerimento nella lingua attualmente selezionata. </para>
<para>I suggerimenti possono essere aggiunti ad ogni widget utilizzando la classe <classname>QToolTip</classname> fornita da Qt. Un esempio potrebbe essere: </para>
</sect1>
<sect1 id="c8s3">
<title>Estendere la barra di stato</title>
<para>Le applicazioni che ereditano da <classname>TDEMainWindow</classname> contengono una barra di stato, e un insieme di messaggi predefiniti per tutti gli elementi dei menu e della barra degli strumenti. Questi messaggi possono integrare o sostituire i suggerimenti e vengono visualizzati nella barra di stato quando l'utente seleziona una voce di un menu. </para>
</sect1>
<sect1 id="c8s4">
<title>Il pulsante <guibutton>Che cos'è?</guibutton></title>
<para>Il pulsante <guibutton>Che cos'è?</guibutton> visualizza una finestra quando l'utente vuole ricevere aiuto su un particolare widget o un elemento della barra degli strumenti. Esso è posizionato nella barra degli strumenti e viene attivato quando viene premuto. Il cursore del mouse diventa una freccia con un punto interrogativo, e quando viene fatto clic su un widget appare una finestra di aiuto. Come esercizio, si può provare usando il pulsante <guibutton>Che cos'è?</guibutton> in &tdevelop;. </para>
<para>Per aggiungere l'aiuto Che cos'è? su un widget, usare il metodo statico <methodname>QWhatsThis::add(TQWidget *widget, const TQString &amp;test)</methodname> </para>
</sect1>
</chapter>
<chapter id="chapter9">
<title>Documentazione</title>
<sect1 id="c9s1">
<title>Introduzione</title>
<para>Siccome i progetti sono carenti di documentazione utente, tutti i progetti di &tdevelop; contengono un manuale pre-costruito che può essere facilmente modificato; in questo modo viene raggiunto uno degli obiettivi di KDE: rendere disponibile documentazione per aiutare gli utenti che non conoscono una applicazione. Questo capitolo illustra come estendere la documentazione predefinita e come renderla disponibile all'utente. </para>
</sect1>
<sect1 id="c9s2">
<title>Documentazione utente</title>
<para>La documentazione del proprio progetto si trova nella cartella directory_del_progetto/doc/en, o in un'altra cartella se la propria lingua non è l'inglese. Il file index.docbook contiene la documentazione. Il formato di questo file è spiegato nel <ulink url="http://i18n.kde.org/doc/markup/">sito KDE per la documentazione</ulink>. </para>
</sect1>
<sect1 id="c9s3">
<title>Documentazione per il programmatore</title>
<para>Un'importante parte della documentazione include la descrizione delle interfacce delle classi, che permette anche ad altri programmatori di usare le proprie classi leggendo la documentazione in formato HTML creata con KDoc. &tdevelop; supporta KDoc e permette di creare la documentazione delle librerie KDE e anche la propria applicazione è già documentata. Successivamente verrà descritto come ottenere la documentazione API, dove &tdevelop; può essere d'aiuto e i tipi di tag speciali inclusi in KDoc. </para>
</sect1>
</chapter>
<chapter id="chapter10">
<title>Internazionalizzazione</title>
<sect1 id="c10s1">
<title>Introduzione</title>
<para>i18n è un sistema usato per creare versioni internazionali di una applicazione o un progetto. La presenza di una sola lingua è un problema che si presenta quando si scrivono applicazioni e si può osservare negli elementi dell'interfaccia grafica come etichette, menu, ecc. L'obiettivo dell'internazionalizzazione consiste nel fornire applicazioni e librerie nella lingua dell'utente. </para>
</sect1>
<!--
<sect1 id="c10s2">
<title>How KDE support Internationalization</title>
</sect1> -->
</chapter>
<!--
<chapter id="chapter11">
<title>Finding Errors</title>
</chapter>
<chapter id="chapter12">
<title>Licensing</title>
</chapter>
<chapter id="chapter13">
<title>References</title>
</chapter>
-->
<chapter id="credits">
<title>Riconoscimenti</title>
<para>(... da scriversi...) </para>
<!--CREDITS_FOR_TRANSLATORS-->
</chapter> <!-- credits -->
<appendix id="bibliography">
<title>Bibliografia</title>
<bibliography>
<biblioentry>
<title><ulink url="info://make/Top">GNU Make Manual</ulink></title>
<authorgroup>
<author><firstname>Richard M.</firstname><surname>Stallman</surname></author>
<author><firstname>Roland</firstname><surname>McGrath</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://automake/Top">GNU Automake</ulink></title>
<authorgroup>
<author><firstname>David</firstname><surname>MacKenzie</surname></author>
<author><firstname>Tom</firstname><surname>Tromey</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://autoconf/Top">GNU Autoconf</ulink></title>
<authorgroup>
<author><firstname>David</firstname><surname>MacKenzie</surname></author>
<author><firstname>Ben</firstname><surname>Elliston</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title><ulink url="info://gcc/Top">Using the GNU Compiler Collection</ulink></title>
<author><firstname>Richard M.</firstname><surname>Stallman</surname></author>
</biblioentry>
<biblioentry>
<title><ulink url="info://libtool/Top">GNU Libtool</ulink></title>
<authorgroup>
<author><firstname>Gordon</firstname><surname>Matzigkeit</surname></author>
<author><firstname>Alexandre</firstname><surname>Oliva</surname></author>
<author><firstname>Thomas</firstname><surname>Tanner</surname></author>
<author><firstname>Gary V.</firstname><surname>Vaughan</surname></author>
</authorgroup>
</biblioentry>
<biblioentry>
<title>GNU Autoconf, Automake, and Libtool</title>
<edition>1st edition</edition>
<pubdate>October 2000</pubdate>
<authorgroup>
<author><firstname>Gary V.</firstname><surname>Vaughan</surname></author>
<author><firstname>Ben</firstname><surname>Elliston</surname></author>
<author><firstname>Tom</firstname><surname>Tromey</surname></author>
<author><firstname>Ian Lance</firstname><surname>Taylor</surname></author>
</authorgroup>
<publisher><publishername>New Riders Publishing</publishername></publisher>
<isbn>ISBN 1578701902</isbn>
</biblioentry>
<biblioentry>
<title>Advanced Programming in the UNIX(R) Environment</title>
<edition>1st edition</edition>
<pubdate>June 1992</pubdate>
<author><firstname>W. Richard</firstname><surname>Stevens</surname></author>
<publisher><publishername>Addison-Wesley Pub Co</publishername></publisher>
<isbn>ISBN 0201563177</isbn>
</biblioentry>
<biblioentry>
<title>Thinking in C++, Volume 1: Introduction to Standard C++</title>
<edition>2nd Edition</edition>
<pubdate>April 15, 2000</pubdate>
<author><firstname>Bruce</firstname><surname>Eckel</surname></author>
<publisher><publishername>Prentice Hall</publishername></publisher>
<isbn>ISBN 0139798099</isbn>
</biblioentry>
<biblioentry>
<title>Open Source Development with CVS</title>
<edition>2nd Edition</edition>
<pubdate>October 12, 2001</pubdate>
<authorgroup>
<author><firstname>Karl</firstname><surname>Fogel</surname></author>
<author><firstname>Moshe</firstname><surname>Bar</surname></author>
</authorgroup>
<publisher><publishername>The Coriolis Group</publishername></publisher>
<isbn>ISBN 158880173X</isbn>
</biblioentry>
<biblioentry>
<title>Programming PHP</title>
<edition>1st edition</edition>
<pubdate>March 2002</pubdate>
<authorgroup>
<author><firstname>Rasmus</firstname><surname>Lerdorf</surname></author>
<author><firstname>Kevin</firstname><surname>Tatroe</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly &amp; Associates</publishername></publisher>
<isbn>ISBN 1565926102</isbn>
</biblioentry>
<biblioentry>
<title>Programming Python</title>
<edition>2nd Edition</edition>
<pubdate>March 2001</pubdate>
<author><firstname>Mark</firstname><surname>Lutz</surname></author>
<publisher><publishername>O'Reilly &amp; Associates</publishername></publisher>
<isbn>ISBN 0596000855</isbn>
</biblioentry>
<biblioentry>
<title>Gui Programming With Python : Using the Qt Toolkit</title>
<edition>Bk&amp;Cd-r edition</edition>
<pubdate>January 2002</pubdate>
<author><firstname>Boudewijn</firstname><surname>Rempt</surname></author>
<publisher><publishername>Opendocs Llc</publishername></publisher>
<isbn>ISBN 0970033044</isbn>
</biblioentry>
<biblioentry>
<title>Programming Perl</title>
<subtitle>The Camel book</subtitle>
<edition>3rd Edition</edition>
<pubdate>July 2000</pubdate>
<authorgroup>
<author><firstname>Larry</firstname><surname>Wall</surname></author>
<author><firstname>Tom</firstname><surname>Christiansen</surname></author>
<author><firstname>Jon</firstname><surname>Orwant</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly &amp; Associates</publishername></publisher>
<isbn>ISBN 0596000278</isbn>
</biblioentry>
<biblioentry>
<title>Learning Perl</title>
<subtitle>The Lama book</subtitle>
<edition>3rd Edition</edition>
<pubdate>July 15, 2001</pubdate>
<authorgroup>
<author><firstname>Randal L.</firstname><surname>Schwartz</surname></author>
<author><firstname>Tom</firstname><surname>Phoenix</surname></author>
</authorgroup>
<publisher><publishername>O'Reilly &amp; Associates</publishername></publisher>
<isbn>ISBN 0596001320</isbn>
</biblioentry>
</bibliography>
&underFDL;
</appendix>
</book>