Getting Started with Qt/it: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=Iniziare a programmare con Qt=
h1. Iniziare a programmare con Qt


Benvenuto nel mondo di Qt, lo strumento multipiattaforma per lo sviluppo di <span class="caps">GUI</span>. In questa guida, insegneremo i fondamenti delle nozioni di Qt creando una sempplice applicazione Notepad. Dopo aver letto la guida, si dovrebbe essere in grado di cercare all’interno delle nostre panoramiche e nella documentazione delle <span class="caps">API</span> per trovare le informazioni di cui si necessita per sviluppare l’applicazione a cui si sta lavorando.
Benvenuto nel mondo di Qt, lo strumento multipiattaforma per lo sviluppo di GUI. In questa guida, insegneremo i fondamenti delle nozioni di Qt creando una sempplice applicazione Notepad. Dopo aver letto la guida, si dovrebbe essere in grado di cercare all'interno delle nostre panoramiche e nella documentazione delle API per trovare le informazioni di cui si necessita per sviluppare l'applicazione a cui si sta lavorando.


==Hello Notepad==
== Hello Notepad ==


In questo primo esempio creeremo e visualizzeremo un editor di testo in una finestra sul desktop. Questo rappresenta il più semplice programma Qt dotato di interfaccia utente.
In questo primo esempio creeremo e visualizzeremo un editor di testo in una finestra sul desktop. Questo rappresenta il più semplice programma Qt dotato di interfaccia utente.


[[Image:gs1.png|gs1.png]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs1.png|gs1.png]]


Il codice è il seguente:
Il codice è il seguente:


Analizziamo ora il codice riga per riga. Nelle prime due righe includiamo i file header per [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' e [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit] ''[doc.qt.nokia.com]'', le due classi che ci servono per questo esempio. Tutte le classi Qt hanno un file header avente il loro stesso nome.
<code> #include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;


La riga 6 crea un oggetto [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]''. Questo oggetto gestisce le risorse all’interno di tutta l’applicazione ed è necessario per eseguire ogni programma Qt che possiede una <span class="caps">GUI</span>. [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' richiede ''argv'' e ''args'' poiché Qt accetta alcuni argomenti a linea di comando.
int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);


La riga 8 crea un oggetto [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit] ''[doc.qt.nokia.com]''. Un editor di testo è un elemento grafico nella <span class="caps">GUI</span>. In Qt questi elementi vengono definiti widgets. Esempi di altri widgets sono barre di scorrimento, labels e radio buttons. Un widget può inoltre contenere altri widgets, ne sono un esempio la finestra di dialogo e la main window dell’applicazione.
QTextEdit textEdit;<br /> textEdit.show();


La riga 9 mostra nella sua finestra sullo schermo l’editor di testo. I widgets funzionano anche come contenitori (ad esempio un [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'' continene toolbar, menù, barre di stato ed altri widgets), ma è comunque possibile visualizzare un widget singolo nella sua finestra. I widgets sono nascosti di default: la funzione [http://doc.qt.nokia.com/4.7/qwidget.html#show show()] ''[doc.qt.nokia.com]'' ha il compito di visualizzarli sul desktop.
return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>


La riga 11 avvia il ciclo di eventi di [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]''. Quando un programma Qt è in esecuzione, sono generati degli eventi che vengono inviati ai widgets dell’applicazione. Esempi di eventi sono pressione dei tasti del mouse o della tastiera. Quando si digita del testo nel widget di editor testuale, esso riceve eventi di pressione dei tasti e risponde visualizzando il testo digitato.
Analizziamo ora il codice riga per riga. Nelle prime due righe includiamo i file header per &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html e &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html, le due classi che ci servono per questo esempio. Tutte le classi Qt hanno un file header avente il loro stesso nome.


Per eseguire l’applicazione è sufficiente aprire un prompt dei comandi ed entrare nella cartella in cui risiede il file .cpp del programma. I seguenti comandi compilano l’applicazione.
La riga 6 crea un oggetto &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Questo oggetto gestisce le risorse all'interno di tutta l'applicazione ed è necessario per eseguire ogni programma Qt che possiede una GUI. &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html richiede ''argv'' e ''args'' poiché Qt accetta alcuni argomenti a linea di comando.


Questo crea un eseguibile nella cartella ''part1'' (nota che su Windows si potrebbe dover utilizzare ''nmake'' al posto di ''make'', inoltre l’eseguibile verrà posizionato nelle cartelle ''part1/debug'' o ''part1/release''). ''qmake'' è il tool di compilazione di Qt e richiede un file di configurazione. ''qmake'' genera questo file per noi quando gli diamo come argomento “-project” . Dato un file di configurazione (con suffisso .pro), ''qmake'' crea un makefile per compilare il programma. Torneremo su come scrivere il proprio file .pro più tardi.
La riga 8 crea un oggetto &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html. Un editor di testo è un elemento grafico nella GUI. In Qt questi elementi vengono definiti widgets. Esempi di altri widgets sono barre di scorrimento, labels e radio buttons. Un widget può inoltre contenere altri widgets, ne sono un esempio la finestra di dialogo e la main window dell'applicazione.


===Per approfondire===
La riga 9 mostra nella sua finestra sullo schermo l'editor di testo. I widgets funzionano anche come contenitori (ad esempio un &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html continene toolbar, menù, barre di stato ed altri widgets), ma è comunque possibile visualizzare un widget singolo nella sua finestra. I widgets sono nascosti di default: la funzione &quot;show()&quot;:http://doc.qt.nokia.com/4.7/qwidget.html#show ha il compito di visualizzarli sul desktop.


{| class="infotable line"
La riga 11 avvia il ciclo di eventi di &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Quando un programma Qt è in esecuzione, sono generati degli eventi che vengono inviati ai widgets dell'applicazione. Esempi di eventi sono pressione dei tasti del mouse o della tastiera. Quando si digita del testo nel widget di editor testuale, esso riceve eventi di pressione dei tasti e risponde visualizzando il testo digitato.
| '''Argomento'''
| '''Collegamento'''
|-
| Widgets e geomentria delle finetre
|
[http://doc.qt.nokia.com/4.7/application-windows.html Window and Dialog Widgets] ''[doc.qt.nokia.com]''
|-
| Eventi e loro gestione
|
[http://doc.qt.nokia.com/4.7/eventsandfilters.html The Event System] ''[doc.qt.nokia.com]''
|}
 
==Aggiungere un bottone di uscita==
 
Nelle applicazioni reali solitamente si utilizzano più widgets. Introdurremo ora un [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButton] ''[doc.qt.nokia.com]'' al di sotto dell’editor di testo. Quando premuto (ad esempio con il mouse), il bottone permetterà di uscire dall’applicazione.
 
[[Image:gs2.png|gs2.png]]
 
Diamo un’occhiata al codice.<br />
 
La prima linea include QtGui, un’header che contiene tutte le classi delle <span class="caps">GUI</span> delle Qt.
 
La linea 10 utilizza il meccanismo di segnali e slot per far uscire l’applicazione quando il '''Quit button''' viene premuto. Uno slot è una funzione che può essere invocata a runtime utilizzando il suo nome (come stringa letterale). Un segnale è una funzione che quando chiamata invoca gli slots registrati ad esso.
 
[http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit quit()] ''[doc.qt.nokia.com]'' è uno slot di [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' che chiude l’applicazione quando invocato. [http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked clicked()] ''[doc.qt.nokia.com]'' è un segnale che [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButton] ''[doc.qt.nokia.com]'' emette quando viene premuto. La funzione statica [http://doc.qt.nokia.com/4.7/qobject.html#connect QObject::connect()] ''[doc.qt.nokia.com]'' si occupa di connettere lo slot ed il segnale. <span class="caps">SIGNAL</span> e <span class="caps">SLOT</span> sono due macro che richiedono i prototipi delle funzioni del segnale e dello slot al fine di connetterli. E’ inoltre necessario fornire i puntatori agli oggetti che devono inviare e ricevere il segnale.
 
La linea 12 crea un [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]''. Come menzionato precedentemente, i widgets possono contenere altri widgets. E’ possibile impostare direttamente i limiti (locazione e dimensioni) di widget figli, ma di solito è più semplice e comodo utilizzare un layout. Un layout gestisce le dimensioni dei widget figli. [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]'', per esempio, posiziona i widget figli in righe verticali.
 
Le linee 13 e 14 aggiungono al layout l’editor di testo ed il bottone, mentre la riga 17 imposta il layout sul widget.
 
===Per approfondire===
 
{| class="infotable line"
| '''Argomento'''
| '''Collegamento'''
|-
| Segnali e slots
|
[http://doc.qt.nokia.com/4.7/signalsandslots.html Signals &amp; Slots] ''[doc.qt.nokia.com]''
|-
| Layouts
|
[http://doc.qt.nokia.com/4.7/layout.html Layout Management] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html Widgets and Layouts] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/examples-layouts.html Layout Examples] ''[doc.qt.nokia.com]''
|-
| I widgets di Qt
|
[http://doc.qt.nokia.com/4.7/gallery.html Qt Widget Gallery] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/examples-widgets.html Widget Examples] ''[doc.qt.nokia.com]''
|}


==Sottoclassare QWidget==
Per eseguire l'applicazione è sufficiente aprire un prompt dei comandi ed entrare nella cartella in cui risiede il file .cpp del programma. I seguenti comandi compilano l'applicazione.


Quando gli utilizzatori vogliono uscire dall’applicazione, si potrebbe voler visualizzare una finestra di dialogo per chiedere all’utente se è effettivamente convinto di voler uscire. In questo esempio, sottoclassiamo [http://doc.qt.nokia.com/4.7/qwidget.html QWidget] ''[doc.qt.nokia.com]'' ed aggiungiamo uno slot che connettiamo al '''Quit button'''.
<code> qmake -project<br />qmake<br />make<br /></code>


[[Image:gs3.png|gs3.png]]
Questo crea un eseguibile nella cartella ''part1'' (nota che su Windows si potrebbe dover utilizzare ''nmake'' al posto di ''make'', inoltre l'eseguibile verrà posizionato nelle cartelle ''part1/debug'' o ''part1/release''). ''qmake'' è il tool di compilazione di Qt e richiede un file di configurazione. ''qmake'' genera questo file per noi quando gli diamo come argomento &quot;<s>project&amp;quot; . Dato un file di configurazione (con suffisso .pro), ''qmake'' crea un makefile per compilare il programma. Torneremo su come scrivere il proprio file .pro più tardi.
<br />h3. Per approfondire
<br />|'''Argomento'''|'''Collegamento'''|<br />|Widgets e geomentria delle finetre| &quot;Window and Dialog Widgets&amp;quot;:http://doc.qt.nokia.com/4.7/application-windows.html|<br />|Eventi e loro gestione|&quot;The Event System&amp;quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html|
<br />h2. Aggiungere un bottone di uscita
<br />Nelle applicazioni reali solitamente si utilizzano più widgets. Introdurremo ora un &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html al di sotto dell'editor di testo. Quando premuto (ad esempio con il mouse), il bottone permetterà di uscire dall'applicazione.
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|gs2.png]]
<br />Diamo un'occhiata al codice.<br /><code>#include &lt;QtGui&amp;gt;
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
<br /> window.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
<br />La prima linea include QtGui, un'header che contiene tutte le classi delle GUI delle Qt.
<br />La linea 10 utilizza il meccanismo di segnali e slot per far uscire l'applicazione quando il '''Quit button''' viene premuto. Uno slot è una funzione che può essere invocata a runtime utilizzando il suo nome (come stringa letterale). Un segnale è una funzione che quando chiamata invoca gli slots registrati ad esso.
<br />&quot;quit()&quot;:http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit è uno slot di &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html che chiude l'applicazione quando invocato. &quot;clicked()&quot;:http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked è un segnale che &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html emette quando viene premuto. La funzione statica &quot;QObject::connect()&quot;:http://doc.qt.nokia.com/4.7/qobject.html#connect si occupa di connettere lo slot ed il segnale. SIGNAL () e SLOT() sono due macro che richiedono i prototipi delle funzioni del segnale e dello slot al fine di connetterli. E' inoltre necessario fornire i puntatori agli oggetti che devono inviare e ricevere il segnale.
<br />La linea 12 crea un &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html. Come menzionato precedentemente, i widgets possono contenere altri widgets. E' possibile impostare direttamente i limiti (locazione e dimensioni) di widget figli, ma di solito è più semplice e comodo utilizzare un layout. Un layout gestisce le dimensioni dei widget figli. &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html, per esempio, posiziona i widget figli in righe verticali.
<br />Le linee 13 e 14 aggiungono al layout l'editor di testo ed il bottone, mentre la riga 17 imposta il layout sul widget.
<br />h3. Per approfondire
<br />|'''Argomento'''|'''Collegamento'''|<br />|Segnali e slots|&quot;Signals &amp; Slots&amp;quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html|<br />|Layouts|&quot;Layout Management&amp;quot;:http://doc.qt.nokia.com/4.7/layout.html , &quot;Widgets and Layouts&amp;quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html , &quot;Layout Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html|<br />|I widgets di Qt|&quot;Qt Widget Gallery&amp;quot;:http://doc.qt.nokia.com/4.7/gallery.html , &quot;Widget Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html|
<br />h2. Sottoclassare QWidget
<br />Quando gli utilizzatori vogliono uscire dall'applicazione, si potrebbe voler visualizzare una finestra di dialogo per chiedere all'utente se è effettivamente convinto di voler uscire. In questo esempio, sottoclassiamo &quot;QWidget&amp;quot;:http://doc.qt.nokia.com/4.7/qwidget.html ed aggiungiamo uno slot che connettiamo al '''Quit button'''.
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|gs3.png]]  
<br />Diamo un'occhiata al codice:
<br /><code>class Notepad : public QWidget<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};<br /></code>
<br />La macro ''Q_OBJECT'' deve essere la prima nella definizione della classe e definisce questa come un ''QObject'' (è necessario che la classe erediti da &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html). Un &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html aggiunge molte capacità ad una normale classe C++. In particolare, il nome della classe e degli slots può essere recuperato a tempo di esecuzione. E' inoltre possibile invocare direttamente uno slot o recuperare i tipi dei suoi paramentri.
<br />La linea 13 dichiara lo slot ''quit()'' . Utilizzando la macro ''slots'', ciò diventa molto semplice. Lo slot ''quit()'' può ora essere connesso ad un segnale che possiede un prototipo compatibile (in questo caso, ogni segnale che non prende parametri).
<br />Piuttosto che impostare la GUI e connettere lo slot nella funzione ''main()'', utilizziamo ora il costruttore della classe ''Notepad''.
<br /><code>Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<br /> connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));
<br /> QVBoxLayout *layout = new QVBoxLayout;<br /> layout</s>&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);


Diamo un’occhiata al codice:
setLayout(layout);


La macro ''Q_OBJECT'' deve essere la prima nella definizione della classe e definisce questa come un ''QObject'' (è necessario che la classe erediti da [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]''). Un [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'' aggiunge molte capacità ad una normale classe C++. In particolare, il nome della classe e degli slots può essere recuperato a tempo di esecuzione. E’ inoltre possibile invocare direttamente uno slot o recuperare i tipi dei suoi paramentri.
setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br /></code>


La linea 13 dichiara lo slot ''quit()'' . Utilizzando la macro ''slots'', ciò diventa molto semplice. Lo slot ''quit()'' può ora essere connesso ad un segnale che possiede un prototipo compatibile (in questo caso, ogni segnale che non prende parametri).
Come si può vedere nella definizione della classe, utilizziamo puntatori ai nostri &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html (''textEdit'' e ''quitButton''). Come regole, si dovrebbe sempre allocare i &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html nella memoria heap e mai copiarli.


Piuttosto che impostare la <span class="caps">GUI</span> e connettere lo slot nella funzione ''main()'', utilizziamo ora il costruttore della classe ''Notepad''.
Utilizziamo anche la funzione &quot;tr()&quot;:http://doc.qt.nokia.com/4.7/qobject.html#tr attorno alle stringhe da visualizzare all'utente. Questa funzione è necessaria quando si vuole distribuire l'applicazione in più di una lingua (ad esempio Inglese ed Italiano). Qui non entreremo nei detagli, ma è possibile seguire il link ''Qt Linguist'' degli approfondimenti.


Come si può vedere nella definizione della classe, utilizziamo puntatori ai nostri [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'' (''textEdit'' e ''quitButton''). Come regole, si dovrebbe sempre allocare i [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'' nella memoria heap e mai copiarli.
=== Per approfondire ===


Utilizziamo anche la funzione [http://doc.qt.nokia.com/4.7/qobject.html#tr tr()] ''[doc.qt.nokia.com]'' attorno alle stringhe da visualizzare all’utente. Questa funzione è necessaria quando si vuole distribuire l’applicazione in più di una lingua (ad esempio Inglese ed Italiano). Qui non entreremo nei detagli, ma è possibile seguire il link ''Qt Linguist'' degli approfondimenti.
{|
 
|'''Argomento'''
===Per approfondire===
|'''Collegamento'''
 
{| class="infotable line"
| '''Argomento'''
| '''Collegamento'''
|-
|-
| tr() e internazionalizzazione
|tr() e internazionalizzazione
|
|&quot;Qt Linguist Manual&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html , &quot;Writing Source Code for Translation&amp;quot;:http://doc.qt.nokia.com/4.7/i18n-source-translation.html , &quot;Hello tr() Example&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-hellotr.html , &quot;Internationalization with Qt&amp;quot;:http://doc.qt.nokia.com/4.7/internationalization.html
[http://doc.qt.nokia.com/4.7/linguist-manual.html Qt Linguist Manual] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Writing Source Code for Translation] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Hello tr() Example] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/internationalization.html Internationalization with Qt] ''[doc.qt.nokia.com]''
|-
|-
| QObjects ed il modello a oggeti di Qt (essenziale per comprendere Qt)
|QObjects ed il modello a oggeti di Qt (essenziale per comprendere Qt)
|
|&quot;Object Model&amp;quot;:http://doc.qt.nokia.com/4.7/object.html
[http://doc.qt.nokia.com/4.7/object.html Object Model] ''[doc.qt.nokia.com]''
|-
|-
| qmake ed il sistema di compilazione di Qt
|qmake ed il sistema di compilazione di Qt
|
|&quot;qmake Manual&amp;quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html
[http://doc.qt.nokia.com/4.7/qmake-manual.html qmake Manual] ''[doc.qt.nokia.com]''
|}
|}


==Creare un file .pro==
== Creare un file .pro ==
 
Per questo esempio scriveremo il nostro file ''.pro'' al posto di utilizzare l’opzione ''-project'' di ''qmake''.
 
I seguenti comandi console compilano il programma.
 
==Usare una QMainWindow==
 
Molte applicazioni trarranno beneficio dall’ultilizzo di [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'', poiché posiede il proprio layout a cui si può aggiungere una barra dei menù, dock widgets, tool bars e una barra di stato. [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'' ha un’area centrale che può essere occupata da ogni tipo di widget. Nel nostro caso posizioneremo qui il nostro editor di testo.


[[Image:gs4.png|gs4.png]]
Per questo esempio scriveremo il nostro file ''.pro'' al posto di utilizzare l'opzione _<s>project_ di ''qmake''.
<br /><code>HEADERS = notepad.h<br />SOURCES = notepad.cpp  main.cpp<br /></code>
<br />I seguenti comandi console compilano il programma.
<br /><code>qmake<br />make<br /></code>
<br />h2. Usare una QMainWindow
<br />Molte applicazioni trarranno beneficio dall'ultilizzo di &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, poiché posiede il proprio layout a cui si può aggiungere una barra dei menù, dock widgets, tool bars e una barra di stato. &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html ha un'area centrale che può essere occupata da ogni tipo di widget. Nel nostro caso posizioneremo qui il nostro editor di testo.
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|gs4.png]]  
<br />Guardiamo la nuova definizione della classe ''Notepad''.
<br /><code>#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu *fileMenu;<br />};<br /></code>
<br />Includiamo altri due slots per salvare ed aprire un documento. Li implementeremo nella prossima sezione.
<br />Solitamente in una main window lo stesso slot può essere invocato da vari widgets. Sono esempi gli elementi del menù ed i bottoni nella tool bar. Per semplificare ciò, Qt fornisce &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html, una classe che può essere data a vari widgets e connessa ad uno slot. Per esempio, &quot;QMenu&amp;quot;:http://doc.qt.nokia.com/4.7/qmenu.html e &quot;QToolBar&amp;quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html possono creare elementi del menù e tool buttons dalle stesse &quot;QActions&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html. Presto vedremo in che modo.
<br />Come prima, useremo il costruttore della classe ''Notepad'' per impostare la GUI.
<br /><code>Notepad::Notepad()<br />{<br /> saveAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()</s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu-&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);


Guardiamo la nuova definizione della classe ''Notepad''.
textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);


Includiamo altri due slots per salvare ed aprire un documento. Li implementeremo nella prossima sezione.
setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br /></code>


Solitamente in una main window lo stesso slot può essere invocato da vari widgets. Sono esempi gli elementi del menù ed i bottoni nella tool bar. Per semplificare ciò, Qt fornisce [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'', una classe che può essere data a vari widgets e connessa ad uno slot. Per esempio, [http://doc.qt.nokia.com/4.7/qmenu.html QMenu] ''[doc.qt.nokia.com]'' e [http://doc.qt.nokia.com/4.7/qtoolbar.html QToolBar] ''[doc.qt.nokia.com]'' possono creare elementi del menù e tool buttons dalle stesse [http://doc.qt.nokia.com/4.7/qaction.html QActions] ''[doc.qt.nokia.com]''. Presto vedremo in che modo.
Le &quot;QActions&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html sono create con il testo che dovrebbe apparire sui widgets a cui vengono aggiunte (nel nostro caso gli elementi del menù). Se inoltre volessimo aggiungerle ad una tool bar potremmo impostare delle &quot;icone&amp;quot;:http://doc.qt.nokia.com/4.7/qicon.html alle varie azioni.


Come prima, useremo il costruttore della classe ''Notepad'' per impostare la <span class="caps">GUI</span>.
Quando un elemento del menù è cliccato, esso attiva la &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html che si occupa di invocare il rispettivo slot.


Le [http://doc.qt.nokia.com/4.7/qaction.html QActions] ''[doc.qt.nokia.com]'' sono create con il testo che dovrebbe apparire sui widgets a cui vengono aggiunte (nel nostro caso gli elementi del menù). Se inoltre volessimo aggiungerle ad una tool bar potremmo impostare delle [http://doc.qt.nokia.com/4.7/qicon.html icone] ''[doc.qt.nokia.com]'' alle varie azioni.
=== Per approfondire ===


Quando un elemento del menù è cliccato, esso attiva la [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'' che si occupa di invocare il rispettivo slot.
{|
 
|'''Argomento'''
===Per approfondire===
|'''Collegamento'''
 
{| class="infotable line"
| '''Argomento'''
| '''Collegamento'''
|-
|-
| Main windows e classi main window
|Main windows e classi main window
|
|&quot;Application Main Window&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindow.html , &quot;Main Window Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html
[http://doc.qt.nokia.com/4.7/mainwindow.html Application Main Window] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Main Window Examples] ''[doc.qt.nokia.com]''
|-
|-
| Applicazioni <span class="caps">MDI</span>
|Applicazioni MDI
|
|&quot;QMdiArea&amp;quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html , &quot;MDI Example&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html
[http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html <span class="caps">MDI</span> Example] ''[doc.qt.nokia.com]''
|}
|}


==Salvataggio e caricamento==
== Salvataggio e caricamento ==


In questo esempio implementeremo la funzionalità degli slot di ''open()'' e ''save()'' che abbiamo aggiunto nella sezione precedente.
In questo esempio implementeremo la funzionalità degli slot di ''open()'' e ''save()'' che abbiamo aggiunto nella sezione precedente.


[[Image:gs5.png|gs5.png]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|gs5.png]]


Iniziamo con lo slot ''open()'':
Iniziamo con lo slot ''open()'':


Il primo passo è chiedere all’utente il nome del file da aprire. Qt contiene [http://doc.qt.nokia.com/4.7/qfiledialog.html QFileDialog] ''[doc.qt.nokia.com]'', una finestra di dialogo dalla quale l’utente può selezionare un file. L’immagine precedente mostra un esempio da Kubuntu. La funzione statica [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName getOpenFileName()] ''[doc.qt.nokia.com]'' visualizza una finestra di dialogo modale e non ritorna fintanto che l’utente non seleziona un file. La funzione ritorna una stringa contenente il path del file selezionato, oppure una stringa vuota nel caso l’utente annulli l’operazione.
<code>QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
 
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br />}<br /></code>
Se otteniamo il nome di un file, proviamo ad aprirlo tramite la funzione [http://doc.qt.nokia.com/4.7/qiodevice.html#open open()] ''[doc.qt.nokia.com]'', che ritorna true se il file può essere aperto. Qui non andremo nel dettaglio della gestione errori, ma è possibile seguire il link dalla sezione approondimenti. Se il file non può essere aperto, utilizziamo una [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' per visualizzare una finestra con un messaggio d’errore (vedere la descrizione della classe [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' per ulteriori dettagli).
<br />Il primo passo è chiedere all'utente il nome del file da aprire. Qt contiene &quot;QFileDialog&amp;quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html, una finestra di dialogo dalla quale l'utente può selezionare un file. L'immagine precedente mostra un esempio da Kubuntu. La funzione statica &quot;getOpenFileName()&quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName visualizza una finestra di dialogo modale e non ritorna fintanto che l'utente non seleziona un file. La funzione ritorna una stringa contenente il path del file selezionato, oppure una stringa vuota nel caso l'utente annulli l'operazione.
 
<br />Se otteniamo il nome di un file, proviamo ad aprirlo tramite la funzione &quot;open()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#open, che ritorna true se il file può essere aperto. Qui non andremo nel dettaglio della gestione errori, ma è possibile seguire il link dalla sezione approondimenti. Se il file non può essere aperto, utilizziamo una &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html per visualizzare una finestra con un messaggio d'errore (vedere la descrizione della classe &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html per ulteriori dettagli).
La lettura dei dati è banale, grazie alla funzione [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll readAll()] ''[doc.qt.nokia.com]'' che ritorna tutti i dati nel file in un [http://doc.qt.nokia.com/4.7/qbytearray.html QByteArray] ''[doc.qt.nokia.com]''. La funzione [http://doc.qt.nokia.com/4.7/qbytearray.html#constData constData()] ''[doc.qt.nokia.com]'' ritorna il contenuto dell’array sotto forma di const char*, per il quale [http://doc.qt.nokia.com/4.7/qstring.html QString] ''[doc.qt.nokia.com]'' ha un costrutture. Il contenuto ora può essere visualizzato nell’editor di testo. Possiamo ora chudere il file con [http://doc.qt.nokia.com/4.7/qiodevice.html#close close()] ''[doc.qt.nokia.com]'' per far ritornare il file descriptor al sistema operativo.
<br />La lettura dei dati è banale, grazie alla funzione &quot;readAll()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#readAll che ritorna tutti i dati nel file in un &quot;QByteArray&amp;quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. La funzione &quot;constData()&quot;:http://doc.qt.nokia.com/4.7/qbytearray.html#constData ritorna il contenuto dell'array sotto forma di const char''', per il quale &quot;QString&amp;quot;:http://doc.qt.nokia.com/4.7/qstring.html ha un costrutture. Il contenuto ora può essere visualizzato nell'editor di testo. Possiamo ora chudere il file con &quot;close()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#close per far ritornare il file descriptor al sistema operativo.


Adesso spostiamoci sullo slot ''save()''.
Adesso spostiamoci sullo slot ''save()''.


Quando scriviamo il contenuto dell’editor di testo nel file, utilizziamo una classe [http://doc.qt.nokia.com/4.7/qtextstream.html QTextStream] ''[doc.qt.nokia.com]'' che utilizza un oggetto [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]''. La text stream può scrivere stringe direttamente nel file, mentre [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'' accetta solo dati grezzi (char*) nella funzione [http://doc.qt.nokia.com/4.7/qiodevice.html#write write()] ''[doc.qt.nokia.com]'' di [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''.
<code>QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // error message<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}<br /></code>
<br />Quando scriviamo il contenuto dell'editor di testo nel file, utilizziamo una classe &quot;QTextStream&amp;quot;:http://doc.qt.nokia.com/4.7/qtextstream.html che utilizza un oggetto &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html. La text stream può scrivere stringe direttamente nel file, mentre &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html accetta solo dati grezzi (char''') nella funzione &quot;write()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#write di &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html.


===Per approfondire===
=== Per approfondire ===


{| class="infotable line"
{|
| '''Argomento'''
|'''Argomento'''
| '''Collegamento'''
|'''Collegamento'''
|-
|-
| Files e dispositivi di I/O
|Files e dispositivi di I/O
|
|&quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html , &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html
[http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'' , [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''
|}
|}

Revision as of 09:00, 24 February 2015

h1. Iniziare a programmare con Qt

Benvenuto nel mondo di Qt, lo strumento multipiattaforma per lo sviluppo di GUI. In questa guida, insegneremo i fondamenti delle nozioni di Qt creando una sempplice applicazione Notepad. Dopo aver letto la guida, si dovrebbe essere in grado di cercare all'interno delle nostre panoramiche e nella documentazione delle API per trovare le informazioni di cui si necessita per sviluppare l'applicazione a cui si sta lavorando.

Hello Notepad

In questo primo esempio creeremo e visualizzeremo un editor di testo in una finestra sul desktop. Questo rappresenta il più semplice programma Qt dotato di interfaccia utente.

p=. gs1.png

Il codice è il seguente:

 #include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;

int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);

QTextEdit textEdit;<br /> textEdit.show();

return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />

Analizziamo ora il codice riga per riga. Nelle prime due righe includiamo i file header per "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html e "QTextEdit&quot;:http://doc.qt.nokia.com/4.7/qtextedit.html, le due classi che ci servono per questo esempio. Tutte le classi Qt hanno un file header avente il loro stesso nome.

La riga 6 crea un oggetto "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Questo oggetto gestisce le risorse all'interno di tutta l'applicazione ed è necessario per eseguire ogni programma Qt che possiede una GUI. "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html richiede argv e args poiché Qt accetta alcuni argomenti a linea di comando.

La riga 8 crea un oggetto "QTextEdit&quot;:http://doc.qt.nokia.com/4.7/qtextedit.html. Un editor di testo è un elemento grafico nella GUI. In Qt questi elementi vengono definiti widgets. Esempi di altri widgets sono barre di scorrimento, labels e radio buttons. Un widget può inoltre contenere altri widgets, ne sono un esempio la finestra di dialogo e la main window dell'applicazione.

La riga 9 mostra nella sua finestra sullo schermo l'editor di testo. I widgets funzionano anche come contenitori (ad esempio un "QMainWindow&quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html continene toolbar, menù, barre di stato ed altri widgets), ma è comunque possibile visualizzare un widget singolo nella sua finestra. I widgets sono nascosti di default: la funzione "show()":http://doc.qt.nokia.com/4.7/qwidget.html#show ha il compito di visualizzarli sul desktop.

La riga 11 avvia il ciclo di eventi di "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Quando un programma Qt è in esecuzione, sono generati degli eventi che vengono inviati ai widgets dell'applicazione. Esempi di eventi sono pressione dei tasti del mouse o della tastiera. Quando si digita del testo nel widget di editor testuale, esso riceve eventi di pressione dei tasti e risponde visualizzando il testo digitato.

Per eseguire l'applicazione è sufficiente aprire un prompt dei comandi ed entrare nella cartella in cui risiede il file .cpp del programma. I seguenti comandi compilano l'applicazione.

 qmake -project<br />qmake<br />make<br />

Questo crea un eseguibile nella cartella part1 (nota che su Windows si potrebbe dover utilizzare nmake al posto di make, inoltre l'eseguibile verrà posizionato nelle cartelle part1/debug o part1/release). qmake è il tool di compilazione di Qt e richiede un file di configurazione. qmake genera questo file per noi quando gli diamo come argomento "project&quot; . Dato un file di configurazione (con suffisso .pro), qmake crea un makefile per compilare il programma. Torneremo su come scrivere il proprio file .pro più tardi.
h3. Per approfondire
|Argomento|Collegamento|
|Widgets e geomentria delle finetre| "Window and Dialog Widgets&quot;:http://doc.qt.nokia.com/4.7/application-windows.html%7C
|Eventi e loro gestione|"The Event System&quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html%7C
h2. Aggiungere un bottone di uscita
Nelle applicazioni reali solitamente si utilizzano più widgets. Introdurremo ora un "QPushButton&quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html al di sotto dell'editor di testo. Quando premuto (ad esempio con il mouse), il bottone permetterà di uscire dall'applicazione.
p=. gs2.png


Diamo un'occhiata al codice.

#include &lt;QtGui&amp;gt;
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
<br /> window.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />


La prima linea include QtGui, un'header che contiene tutte le classi delle GUI delle Qt.
La linea 10 utilizza il meccanismo di segnali e slot per far uscire l'applicazione quando il Quit button viene premuto. Uno slot è una funzione che può essere invocata a runtime utilizzando il suo nome (come stringa letterale). Un segnale è una funzione che quando chiamata invoca gli slots registrati ad esso.
"quit()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit è uno slot di "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html che chiude l'applicazione quando invocato. "clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked è un segnale che "QPushButton&quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html emette quando viene premuto. La funzione statica "QObject::connect()":http://doc.qt.nokia.com/4.7/qobject.html#connect si occupa di connettere lo slot ed il segnale. SIGNAL () e SLOT() sono due macro che richiedono i prototipi delle funzioni del segnale e dello slot al fine di connetterli. E' inoltre necessario fornire i puntatori agli oggetti che devono inviare e ricevere il segnale.
La linea 12 crea un "QVBoxLayout&quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html. Come menzionato precedentemente, i widgets possono contenere altri widgets. E' possibile impostare direttamente i limiti (locazione e dimensioni) di widget figli, ma di solito è più semplice e comodo utilizzare un layout. Un layout gestisce le dimensioni dei widget figli. "QVBoxLayout&quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html, per esempio, posiziona i widget figli in righe verticali.
Le linee 13 e 14 aggiungono al layout l'editor di testo ed il bottone, mentre la riga 17 imposta il layout sul widget.
h3. Per approfondire
|Argomento|Collegamento|
|Segnali e slots|"Signals & Slots&quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html%7C
|Layouts|"Layout Management&quot;:http://doc.qt.nokia.com/4.7/layout.html , "Widgets and Layouts&quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html , "Layout Examples&quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html%7C
|I widgets di Qt|"Qt Widget Gallery&quot;:http://doc.qt.nokia.com/4.7/gallery.html , "Widget Examples&quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html%7C
h2. Sottoclassare QWidget
Quando gli utilizzatori vogliono uscire dall'applicazione, si potrebbe voler visualizzare una finestra di dialogo per chiedere all'utente se è effettivamente convinto di voler uscire. In questo esempio, sottoclassiamo "QWidget&quot;:http://doc.qt.nokia.com/4.7/qwidget.html ed aggiungiamo uno slot che connettiamo al Quit button.
p=. gs3.png
Diamo un'occhiata al codice:


class Notepad : public QWidget<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};<br />


La macro Q_OBJECT deve essere la prima nella definizione della classe e definisce questa come un QObject (è necessario che la classe erediti da "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html). Un "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html aggiunge molte capacità ad una normale classe C++. In particolare, il nome della classe e degli slots può essere recuperato a tempo di esecuzione. E' inoltre possibile invocare direttamente uno slot o recuperare i tipi dei suoi paramentri.
La linea 13 dichiara lo slot quit() . Utilizzando la macro slots, ciò diventa molto semplice. Lo slot quit() può ora essere connesso ad un segnale che possiede un prototipo compatibile (in questo caso, ogni segnale che non prende parametri).
Piuttosto che impostare la GUI e connettere lo slot nella funzione main(), utilizziamo ora il costruttore della classe Notepad.


Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<br /> connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));
<br /> QVBoxLayout *layout = new QVBoxLayout;<br /> layout</s>&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);

setLayout(layout);

setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br />

Come si può vedere nella definizione della classe, utilizziamo puntatori ai nostri "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html (textEdit e quitButton). Come regole, si dovrebbe sempre allocare i "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html nella memoria heap e mai copiarli.

Utilizziamo anche la funzione "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr attorno alle stringhe da visualizzare all'utente. Questa funzione è necessaria quando si vuole distribuire l'applicazione in più di una lingua (ad esempio Inglese ed Italiano). Qui non entreremo nei detagli, ma è possibile seguire il link Qt Linguist degli approfondimenti.

Per approfondire

Argomento Collegamento
tr() e internazionalizzazione "Qt Linguist Manual&quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html , "Writing Source Code for Translation&quot;:http://doc.qt.nokia.com/4.7/i18n-source-translation.html , "Hello tr() Example&quot;:http://doc.qt.nokia.com/4.7/linguist-hellotr.html , "Internationalization with Qt&quot;:http://doc.qt.nokia.com/4.7/internationalization.html
QObjects ed il modello a oggeti di Qt (essenziale per comprendere Qt) "Object Model&quot;:http://doc.qt.nokia.com/4.7/object.html
qmake ed il sistema di compilazione di Qt "qmake Manual&quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html

Creare un file .pro

Per questo esempio scriveremo il nostro file .pro al posto di utilizzare l'opzione _project_ di qmake.


HEADERS = notepad.h<br />SOURCES = notepad.cpp  main.cpp<br />


I seguenti comandi console compilano il programma.


qmake<br />make<br />


h2. Usare una QMainWindow
Molte applicazioni trarranno beneficio dall'ultilizzo di "QMainWindow&quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, poiché posiede il proprio layout a cui si può aggiungere una barra dei menù, dock widgets, tool bars e una barra di stato. "QMainWindow&quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html ha un'area centrale che può essere occupata da ogni tipo di widget. Nel nostro caso posizioneremo qui il nostro editor di testo.
p=. gs4.png
Guardiamo la nuova definizione della classe Notepad.


#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu *fileMenu;<br />};<br />


Includiamo altri due slots per salvare ed aprire un documento. Li implementeremo nella prossima sezione.
Solitamente in una main window lo stesso slot può essere invocato da vari widgets. Sono esempi gli elementi del menù ed i bottoni nella tool bar. Per semplificare ciò, Qt fornisce "QAction&quot;:http://doc.qt.nokia.com/4.7/qaction.html, una classe che può essere data a vari widgets e connessa ad uno slot. Per esempio, "QMenu&quot;:http://doc.qt.nokia.com/4.7/qmenu.html e "QToolBar&quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html possono creare elementi del menù e tool buttons dalle stesse "QActions&quot;:http://doc.qt.nokia.com/4.7/qaction.html. Presto vedremo in che modo.
Come prima, useremo il costruttore della classe Notepad per impostare la GUI.


Notepad::Notepad()<br />{<br /> saveAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()</s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu-&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);

textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);

setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br />

Le "QActions&quot;:http://doc.qt.nokia.com/4.7/qaction.html sono create con il testo che dovrebbe apparire sui widgets a cui vengono aggiunte (nel nostro caso gli elementi del menù). Se inoltre volessimo aggiungerle ad una tool bar potremmo impostare delle "icone&quot;:http://doc.qt.nokia.com/4.7/qicon.html alle varie azioni.

Quando un elemento del menù è cliccato, esso attiva la "QAction&quot;:http://doc.qt.nokia.com/4.7/qaction.html che si occupa di invocare il rispettivo slot.

Per approfondire

Argomento Collegamento
Main windows e classi main window "Application Main Window&quot;:http://doc.qt.nokia.com/4.7/mainwindow.html , "Main Window Examples&quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html
Applicazioni MDI "QMdiArea&quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html , "MDI Example&quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html

Salvataggio e caricamento

In questo esempio implementeremo la funzionalità degli slot di open() e save() che abbiamo aggiunto nella sezione precedente.

p=. gs5.png

Iniziamo con lo slot open():

QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br />}<br />


Il primo passo è chiedere all'utente il nome del file da aprire. Qt contiene "QFileDialog&quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html, una finestra di dialogo dalla quale l'utente può selezionare un file. L'immagine precedente mostra un esempio da Kubuntu. La funzione statica "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName visualizza una finestra di dialogo modale e non ritorna fintanto che l'utente non seleziona un file. La funzione ritorna una stringa contenente il path del file selezionato, oppure una stringa vuota nel caso l'utente annulli l'operazione.
Se otteniamo il nome di un file, proviamo ad aprirlo tramite la funzione "open()":http://doc.qt.nokia.com/4.7/qiodevice.html#open, che ritorna true se il file può essere aperto. Qui non andremo nel dettaglio della gestione errori, ma è possibile seguire il link dalla sezione approondimenti. Se il file non può essere aperto, utilizziamo una "QMessageBox&quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html per visualizzare una finestra con un messaggio d'errore (vedere la descrizione della classe "QMessageBox&quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html per ulteriori dettagli).
La lettura dei dati è banale, grazie alla funzione "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll che ritorna tutti i dati nel file in un "QByteArray&quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. La funzione "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData ritorna il contenuto dell'array sotto forma di const char, per il quale "QString&quot;:http://doc.qt.nokia.com/4.7/qstring.html ha un costrutture. Il contenuto ora può essere visualizzato nell'editor di testo. Possiamo ora chudere il file con "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close per far ritornare il file descriptor al sistema operativo.

Adesso spostiamoci sullo slot save().

QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // error message<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}<br />


Quando scriviamo il contenuto dell'editor di testo nel file, utilizziamo una classe "QTextStream&quot;:http://doc.qt.nokia.com/4.7/qtextstream.html che utilizza un oggetto "QFile&quot;:http://doc.qt.nokia.com/4.7/qfile.html. La text stream può scrivere stringe direttamente nel file, mentre "QFile&quot;:http://doc.qt.nokia.com/4.7/qfile.html accetta solo dati grezzi (char) nella funzione "write()":http://doc.qt.nokia.com/4.7/qiodevice.html#write di "QIODevice&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html.

Per approfondire

Argomento Collegamento
Files e dispositivi di I/O "QFile&quot;:http://doc.qt.nokia.com/4.7/qfile.html , "QIODevice&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html