KDevelop"> ]> Manuale di programmazione di &tdevelop; 2002-12-05 2.0 Ralf Nolden
Ralf.Nolden@post.rwth-aachen.de
Caleb Tennis
caleb@aei-tech.com
1999 Ralf Nolden 2002 Caleb Tennis &FDLNotice; Il manuale utente per lo sviluppo di applicazioni C++ per l'ambiente desktop KDE con l'IDE &tdevelop; KDE KDevelop IDE sviluppo programmazione
Introduzione 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. Cosa si dovrebbe già conoscere 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. Informazioni sul manuale Questo manuale è stato scritto per fornire agli sviluppatori una introduzione alla progettazione di applicazioni KDE utilizzando l'ambiente di sviluppo integrato KDevelop. 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. Viene discusso dettagliatamente la creazione di widget personalizzati e le impostazioni dei widget predefiniti. 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. Nel prossimo capitolo 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; Nei capitoli seguenti Si imparerà: a creare una applicazione con la procedura guidata per le applicazioni a conoscere lo schema del progetto il significato del codice già creato a creare le proprie viste a espandere le funzionalità delle applicazioni con finestre di dialogo, barre dei menu e barre degli strumenti a rendere l'applicazione amichevole per l'utente con le funzioni di aiuto a scrivere la documentazione in linea Ulteriori informazioni Informazioni aggiuntive sulla programmazione con Qt/KDE sono disponibili attraverso diverse fonti: Programming with Qt di Matthias Kalle Dalheimer Il manuale utente di KDevelop, fornito con l'IDE KDevelop La documentazione di riferimento delle librerie Qt Il sito dello sviluppatore KDE 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++. Per avere aiuto con KDevelop inviare le richieste alla mailing list all'indirizzo tdevelop@tdevelop.org. 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. Le librerie KDE e Qt La società norvegese TrollTech (http://www.trolltech.com) 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. Il gruppo KDE (http://www.kde.org), 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. 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. Il toolkit Qt 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: Un completo insieme di classi e metodi pronti per l'uso anche per la programmazione di applicazioni non grafiche Una buona soluzione per l'interazione con l'utente tramite metodi virtuali e il meccanismo dei segnali e degli slot Un insieme di elementi GUI predefiniti chiamati "widget" che possono essere facilmente usati per creare elementi visibili Finestre che vengono usate frequentemente nelle applicazioni come finestre di avanzamento e finestre di dialogo per i file. 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. La prima applicazione Qt Normalmente i programmi in C++ devono contenere una funzione main(), 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: #include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); QPushButton hello( "Hello world!", 0 ); hello.resize( 100, 30 ); a.setMainWidget( &hello ); hello.show(); return a.exec(); } 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 QApplication, rappresentata dalla variabile a. Successivamente il programma crea una istanza della classe QPushButton chiamata hello, che rappresenta il pulsante. Il costruttore di hello riceve una stringa come parametro, contenente il testo visualizzato nel pulsante. Poi viene chiamato il metodo resize() del pulsante hello. Esso cambia la grandezza predefinita del widget (che in questo caso è QPushButton) 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 a.exec() 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. La documentazione di riferimento per Qt 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 QApplication e QPushButton selezionare "Lista delle classi in ordine alfabetico" e cercare il loro nome. Seguire il collegamento per visualizzare la documentazione relativa alla classe. In alternativa si può consultare la documentazione Qt di Trolltech. Per QApplication 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. Capire l'esempio Iniziando con QApplication si troveranno tutti i metodi utilizzati in questo primo esempio: il costruttore QApplication() il metodo setMainWidget() il metodo exec() Capire perché vengono usati questi metodi è molto semplice: Si crea una istanza della classe QApplication con il costruttore, così si possono usare gli elementi della GUI forniti da Qt Si crea un widget che sarà contenuto nella finestra del programma Si imposta il widget come il widget grafico principale per a Si esegue l'istanza di QApplication di nome a Il secondo oggetto del nostro programma è il pulsante, una istanza della classe QPushButton. 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 resize() per modificare la dimensione del pulsante - il pulsante deve essere più largo per rendere la stringa completamente visibile. Qual è lo scopo del metodo show()? Come la maggior parte dei widget, la classe QPushButton ha una singola ereditarietà e la sua classe base è QButton. Seguire il collegamento relativo alla classe QButton; verranno visualizzati molti altri widget che ereditano da QPushButton, che saranno illustrati in seguito per spiegare il meccanismo segnale/slot. Siccome il metodo show() non è elencato deve essere un metodo ereditato. La classe QButton eredita da QWidget. Seguendo nuovamente il collegamento saranno mostrati un gruppo di metodi forniti da quest'ultima classe, tra cui il metodo show(). Ora si può capire cosa accade nell'esempio: Si crea una istanza di QPushButton usando il secondo costruttore in modo da impostare il testo del pulsante Si ridimensiona il widget in base al suo contenuto Si imposta il widget come quello principale dell'istanza a della classe QApplication Si indica al widget di mostrarsi sul video chiamando show(), un metodo derivato dalla classe QWidget Dopo aver chiamato il metodo exec() 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. 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 QWidget e la guida di riferimento della libreria KDE Interazione con l'utente Dopo la lettura dell'ultima sezione si dovrebbe conoscere: Cosa fornisce la libreria Qt per le applicazioni GUI Come viene creato un programma che utilizza Qt e Dove e come trovare, tramite il browser della documentazione, le informazioni riguardanti le classi che si vogliono usare 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. Il sistema grafico invia tutti gli eventi di interazione all'applicazione corrispondente. La classe QApplication li invia alla finestra attiva come oggetti QEvent e i widget dovranno decidere cosa farne. Un widget riceve l'evento ed elabora QWidget::event(QEvent*), il quale decide quale evento è stato eseguito e come reagire; event() è il gestore principale degli eventi. In seguito il metodo event() 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: Eventi di tastiera -- tasti Tab e Shift-Tab: virtual void focusInEvent(QFocusEvent *) virtual void focusOutEvent(QFocusEvent *) Tutti gli input dagli altri tasti: virtual void keyPressEvent(QKeyEvent *) virtual void keyReleaseEvent(QKeyEvent *) Movimenti del mouse: virtual void mouseMoveEvent(QMouseEvent *) virtual void enterEvent(QEvent *) virtual void leaveEvent(QEvent *) Azioni del pulsante del mouse virtual void mousePressEvent(QMouseEvent *) virtual void mouseReleaseEvent(QMouseEvent *) virtual void mouseDoubleClickEvent(QMouseEvent *) Eventi della finestra contenente il widget virtual void moveEvent(QMoveEvent *) virtual void resizeEvent(QResizeEvent *) virtual void closeEvent(QCloseEvent *) 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. QWidget contiene inoltre qualche altro metodo virtuale che può essere utile nei programmi. Interazione degli oggetti attraverso segnali e slot 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: la dichiarazione di una classe che usa i segnali e gli slot deve contenere la macro Q_OBJECT all'inizio (senza il punto e virgola) e deve ereditare dalla classe QObject 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 tutti i segnali utilizzati dalle classi che non sono ereditati devono essere aggiunti alla dichiarazione di classe in una sezione dedicata ai segnali 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 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++. Un'altra strada per utilizzare i segnali senza derivare da QObject è utilizzare la classe QSignal - vedere la documentazione di riferimento per ulteriori informazioni ed esempi di utilizzo. Nel seguito si presuppone che si stia derivando dalla classe QObject. 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. Per connettere un segnale ad uno slot si devono utilizzare i metodi connect() messi a disposizione dalla classe QObject o, quando disponibile, metodi speciali forniti dagli oggetti per impostare la connessione ad un determinato segnale. Semplice utilizzo Per illustrare l'interazione tra gli oggetti si estenderà il primo esempio aggiungendo una semplice connessione: #include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); QPushButton hello( "Hello world!" , 0); hello.resize( 100, 30 ); a.setMainWidget( &hello ); QObject::connect(&hello, SIGNAL( clicked() ), &a, SLOT( quit() )); hello.show(); return a.exec(); } Come si può vedere, l'unica modifica richiesta per dare maggiore interazione al pulsante consiste nell'utilizzare il metodo connect(): tutto quello che si deve aggiungere è connect(&hello,SIGNAL( clicked() ), &a,SLOT( quit() )). Cosa significa? La dichiarazione del metodo connect() nella classe QObject è: bool connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) Si deve specificare come primo parametro un puntatore ad una istanza di QObject 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. 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 Guida di riferimento della libreria KDE e nella documentazione Qt di riferimento. Cosa fornisce KDE Le librerie KDE 3.x Le principali librerie KDE che verranno utilizzate per la creazione di applicazioni KDE sono: la libreria tdecore, contenente tutte le classi degli elementi senza rappresentazione grafica che forniscono funzionalità all'applicazione la libreria tdeui, contenente gli elementi dell'interfaccia grafica come barre dei menu, barre degli strumenti, ecc. la libreria kfile, contenente le finestre di dialogo per la selezione di file Inoltre KDE offre le seguenti librerie, dedicate a soluzioni specifiche: la libreria tdefx, contenente pixmap, effetti grafici e KStyle, l'estensione di QStyle la libreria khtml, contenente il componente html di KDE la libreria kjs, contenente il supporto JavaScript di KDE la libreria kio, contenente l'accesso a basso livello ai file di rete la libreria kparts, contenente il supporto per il riutilizzo delle applicazioni estendibili ed incapsulabili Successivamente si vedrà cosa è necessario per trasformare la prima applicazione Qt in una KDE. Esempio di application KDE 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: #include <kapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { TDEApplication a( argc, argv ); QPushButton hello( "Hello world!", 0 ); hello.resize( 100, 30 ); a.setTopWidget( &hello ); QObject::connect(&hello, SIGNAL( clicked() ), &a, SLOT( quit() )); hello.show(); return a.exec(); } Per prima cosa è stata cambiata la classe QApplication con la classe TDEApplication. Inoltre è stato cambiato il metodo setMainWidget() usato precedentemente con il metodo setTopWidget, che viene usato da TDEApplication 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. Ora che si conosce cosa fornisce la funzione main(), 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. Prima di proseguire si dovrebbe consultare la documentazione di riferimento di Qt, in particolare le classi QApplication, QWidget e QObject, e la documentazione della libreria tdecore per la classe TDEApplication . Il manuale di riferimento delle librerie KDE include una descrizione completa sulle chiamate ai costruttori delle classi QApplication e TDEApplication e l'elaborazione degli argomenti a linea di comando. Creare una nuova applicazione La procedura guidata per le applicazioni 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: KDE Application Framework: include la struttura di una applicazione KDE completa QMake Project: crea una di applicazione basata sul sistema di configurazione qmake di Trolltech Simple hello world program: crea un programma C++ testuale senza il supporto GUI Molti altri schemi di programma 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. Avviare la procedura guidata per le applicazioni e generare il progetto Avviare la procedura guidata per le applicazioni 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. 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. Procedura guidata per le applicazioni Informazioni sul controllo versione 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. Modelli dei sorgenti e delle intestazioni 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. Terminare 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. La prima compilazione 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. Questo capitolo presume che si conosca la navigazione base di &tdevelop;. Se necessario consultare il manuale utente di KDevelop. Il gestore Automake visualizza i file di progetto come segue: I file nel progetto 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. 1 cd /home/caleb/kscribble && 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 -DQT_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_BSD_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 -DQT_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_BSD_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 `KAction*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 -DQT_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_BSD_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 -DQT_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_BSD_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 -DQT_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_BSD_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_BSD_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 -lkio 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 -DQT_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_BSD_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_BSD_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 *** 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. 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;. 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 Q_OBJECT. Il file risultante, kscribble.moc, verrà utilizzato da kscribble.cpp tramite la direttiva #include all'interno del file. Sorgenti della struttura del progetto 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. La funzione main() L'applicazione inizia la sua esecuzione entrando nella funzione main(), quindi si partirà da qui ad esaminare il codice. La funzione main() di KScribble è implementata in main.cpp e può essere trovata utilizzando il browser delle classi selezionando la cartella "Funzioni Globali". 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, &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 < 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 } Viene per prima cosa creato il solito oggetto TDEApplication, ma sono stati aggiunti alcuni metodi che impostano le informazioni sul programma sull'autore per questa applicazione. Avvio Applicazione Utente ... (non ancora scritto) Il costruttore Si esaminerà il costruttore per vedere come viene chiamata questa istanza 1 KScribble::KScribble() 2 : KMainWindow( 0, "KScribble" ), 3 m_view(new KScribbleView(this)), 4 m_printer(0) 5 { 6 // accept dnd 7 setAcceptDrops(true); 8 9 // tell the KMainWindow 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, SIGNAL(signalChangeStatusbar(const QString&)), 20 this, SLOT(changeStatusbar(const QString&))); 21 connect(m_view, SIGNAL(signalChangeCaption(const QString&)), 22 this, SLOT(changeCaption(const QString&))); 23 24 } Notare che KScribble deriva da KMainWindow - usata frequentemente come classe base per le applicazioni KDE. Viene inizializzata una classe chiamata KScribbleView come widget centrale, viene creata una classe KStatusBar tramite il metodo statusBar() (linea 16) e vengono connessi alcuni segnali e slot. Progettare la vista dell'applicazione Introduzione 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. 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: la barra dei menu: fornisce operazioni complesse come apertura, salvataggio e chiusura dei file ed uscita dall'applicazione. la barra degli strumenti: contiene icone che permettono un veloce accesso alle funzioni più importanti, la barra di stato: mostra la posizione del cursore visualizzando l'attuale numero di riga e di colonna, La vista al centro della finestra, che visualizza un documento e contiene un cursore connesso alla tastiera ed al mouse per operare sui dati. É 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. 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: graficamente gradevole con molte funzionalità facile da gestire veloce da imparare 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. Quando si crea un progetto KDE o Qt, si dovrà avere sempre una vista che deriva da QWidget per ereditarietà diretta o perché il widget di libreria che si vuole usare deriva da QWidget. Quindi la procedura guidata per l'applicazioni crea una vista che è istanza di una classe di nome NomeApplicazioneView che deriva da QWidget. 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. Usare le viste delle librerie 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: Rimuovendo la nuova classe per la vista, creare una istanza di un widget di libreria e poi impostare quest'ultimo come vista, Impostando il widget di libreria che si vuole usare come classe base della vista 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. 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". Viste Qt 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. Ecco una serie di suggerimenti per scegliere il componente Qt da usare per un particolare scopo 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 QScrollView che offre un'area figlio scorrevole. Si può derivare il proprio widget da questa classe o utilizzare una sua istanza. per creare uno ScrollView, derivare il widget per la vista da QWidget e aggiungere una barra di scorrimento orizzontale ed una verticale QScrollBars. (Questo viene fatto dal widget KHTMLViews di KDE.) Per l'elaborazione del testo, usare QTextEdit. 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. Usare la classe QTable 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. Per visualizzare due widget diversi o due istanze contemporaneamente,utilizzare la classe QSplitter. 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. QListView 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. 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. Viste KDE 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: KListView: una versione più potente di QListView KIconView: una vista grafica di file ad icona La libreria khtml, 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. Creare le proprie viste Non ancora scritto Configurare le barre dei menu e le barre degli strumenti Introduzione 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. 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. Come funziona? L'applicazione deriva dalla classe KMainWindow, che automaticamente crea una barra dei menu e una barra degli strumenti. Nel metodo KScribble::setupActions() c'è una chiamata al metodo KMainWindow::createGUI(), 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: 1 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> 2 <kpartgui name="kscribble" version="1"> 3 <MenuBar> 4 <Menu name="custom" ><text >C&ustom</text> 5 <Action name="custom_action" /> 6 </Menu> 7 </MenuBar> 8 </kpartgui > Spiegazione... 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 menuBar() restituisce il widget KMenuBar che rappresenta la barra dei menu del programma. Consultando la documentazione della classe KMenuBar e della sua classe base QMenuBar, si troveranno molti metodi insertItem() che permettono di aggiungere elementi alla barra dei menu. Anche i metodi statusBar() e toolBar() della classe KMainWindow forniranno i widget appropriati. Configurazione delle scorciatoie da tastiera 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 KAction, che permette di utilizzare tasti scorciatoia e l'accesso alla configurazione generale degli acceleratori da tastiera standard. 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. 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 KKeyChooser da usare nelle finestre di dialogo, mentre la classe KKeyDialog è una finestra di dialogo per la configurazione dei tasti pronta all'uso. Funzioni di Aiuto Introduzione 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: tooltip barra di stato pulsante Che cos'è? 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 KMainWindow, benché l'autore debba scrivere il contenuto. 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. 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. ToolTip 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 KToolBar che si trova nella libreria tdeui. Come esempio, cercare il pulsante "Nuovo File" di una qualunque applicazione: La funzione i18n("New File") fornisce un messaggio di suggerimento. Questo è racchiuso dalla macro i18n() fornita da kapp.h per tradurre i suggerimento nella lingua attualmente selezionata. I suggerimenti possono essere aggiunti ad ogni widget utilizzando la classe QToolTip fornita da Qt. Un esempio potrebbe essere: Estendere la barra di stato Le applicazioni che ereditano da KMainWindow 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. Il pulsante <guibutton >Che cos'è?</guibutton > Il pulsante Che cos'è? 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 Che cos'è? in &tdevelop;. Per aggiungere l'aiuto Che cos'è? su un widget, usare il metodo statico QWhatsThis::add(QWidget *widget, const QString &test) Documentazione Introduzione 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. Documentazione utente 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 sito KDE per la documentazione. Documentazione per il programmatore 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. Internazionalizzazione Introduzione 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. Riconoscimenti (... da scriversi...) Bibliografia <ulink url="info://make/Top" >GNU Make Manual</ulink > Richard M.Stallman RolandMcGrath <ulink url="info://automake/Top" >GNU Automake</ulink > DavidMacKenzie TomTromey <ulink url="info://autoconf/Top" >GNU Autoconf</ulink > DavidMacKenzie BenElliston <ulink url="info://gcc/Top" >Using the GNU Compiler Collection</ulink > Richard M.Stallman <ulink url="info://libtool/Top" >GNU Libtool</ulink > GordonMatzigkeit AlexandreOliva ThomasTanner Gary V.Vaughan GNU Autoconf, Automake, and Libtool 1st edition October 2000 Gary V.Vaughan BenElliston TomTromey Ian LanceTaylor New Riders Publishing ISBN 1578701902 Advanced Programming in the UNIX(R) Environment 1st edition June 1992 W. RichardStevens Addison-Wesley Pub Co ISBN 0201563177 Thinking in C++, Volume 1: Introduction to Standard C++ 2nd Edition April 15, 2000 BruceEckel Prentice Hall ISBN 0139798099 Open Source Development with CVS 2nd Edition October 12, 2001 KarlFogel MosheBar The Coriolis Group ISBN 158880173X Programming PHP 1st edition March 2002 RasmusLerdorf KevinTatroe O'Reilly & Associates ISBN 1565926102 Programming Python 2nd Edition March 2001 MarkLutz O'Reilly & Associates ISBN 0596000855 Gui Programming With Python : Using the Qt Toolkit Bk&Cd-r edition January 2002 BoudewijnRempt Opendocs Llc ISBN 0970033044 Programming Perl The Camel book 3rd Edition July 2000 LarryWall TomChristiansen JonOrwant O'Reilly & Associates ISBN 0596000278 Learning Perl The Lama book 3rd Edition July 15, 2001 Randal L.Schwartz TomPhoenix O'Reilly & Associates ISBN 0596001320 &underFDL;