SlideShare ist ein Scribd-Unternehmen logo
1 von 6
Downloaden Sie, um offline zu lesen
Mini Guide Qt

                                               Qt toolkit
                                Gestione degli eventi


Premessa
Questa presentazione è rilasciata sotto Licenza
Creative Commons: Attribution-NonCommercial-NoDerivativeWorks
(http://creativecommons.org/licenses/by-nc-nd/3.0/deed.it).

Questo documento può quindi essere riprodotto senza violare nessuna legge, sia in versione elettronica, sia in
versione cartacea, purché sia riprodotto integralmente in tutte le sue parti, compresa la pagina che contiene queste
informazioni:

Versione originale scaricabile dal sito
http://www.sereno-online.com/site/

Tutti i marchi riportati in questa pubblicazione appartengono ai rispettivi proprietari.



Link Utili
Qui di seguito riporto alcuni link utili per chi usa quotidianamente l’ambiente di sviluppo Qt e vuole confrontarsi con
altri sviluppatore, utenti e semplici appassionati di questo toolkit gratuito ed open source.



Gruppo Programmatori Italiani Qt Software (GPIQt)

http://www.facebook.com/inbox/?ref=mb#/group.php?gid=81561439535



qt in Italy

http://qt-apps.org/groups/?id=17



qtitaliantranslators

http://gitorious.org/+qtitaliantranslators




Autore P. Sereno                                                                  http://www.sereno-online.com/site
Mini Guide Qt


Scopo
Questa lezione vuole essere un semplice avvicinamento al meccanismo di gestione degli eventi di Qt. L’argomento per
poter essere spiegato correttamente deve essere affiancato da esempi pratici; a questo scopo si è pensato di creare
un custom widget per intercettare gli eventi più importanti e proporre al lettore alcune soluzioni.


Event Driven
Le applicazioni GUI vengono definite applicazioni di tipo “event-driven”, ovvero pilotate dagli eventi; questa
definizione è davvero rappresentativa, in quanto in un'applicazione GUI, tutto ciò che succede è il risultato di un
evento.
Quando programmiamo con il toolkit Qt, raramente abbiamo bisogno di preoccuparci del meccanismo degli eventi,
poiché i widgets Qt che usiamo emettono autonomamente dei segnali nel momento in cui occorre qualcosa di
significativo. La gestione degli eventi diventa quindi importante nel momento in cui vogliamo scrivere dei nuovi
custom widgets o vogliamo modificare il comportamento di widgets esistenti.


Eventi di Paint
Gli eventi vengono generati da Qt in risposta a diverse situazioni: quando viene premuto un tasto sulla tastiera,
oppure un tasto del mouse, Qt si incarica di generare un evento. Un evento però può anche essere generato in seguito
al riposizionamento di una finestra sul desktop, in quanto caso ad esempio, il sistema di gestione delle finestre riceve
un evento che usa per ridisegnare ciò che prima era nascosto dalla finestra; in questo caso parleremo di evento di
Paint (disegno). Terminiamo ora la nostra breve carrellata citando l'evento di Show. Come già visto nelle lezioni
precedenti, la creazione di un widget non implica automaticamente la sua visibilità, bisogna infatti richiamare
esplicitamente il metodo di show() per disegnarlo a video. Richiamare il metodo di show() è il metodo che Qt ci offre
per informare il motore di disegno del toolkit che un widget, di cui noi abbiamo definito le proprietà grafiche, testuali,
di posizione e dimensioni, deve essere ridisegnato.


Eventi del Timer
Un altro evento, molto comune nella pratica, è il timer. Se gli eventi visti sin'ora occorrono come risultato di un'azione
eseguita dall'utente dell'applicazione, i timers permettono all'applicazione stessa di eseguire un compito ad intervallo
di tempo.


Un esempio pratico: myTimer
Gli esempi riportati ci permettono di capire la filosofia che sta dietro agli eventi, ma nulla è ancora stato detto su
come essi “vengono implementati”. Nel mondo Qt, un evento è un metodo virtuale, il che vuol dire, semplificando il
concetto, che quando deriviamo da una classe di partenza con eventi, possiamo reimplementarli (sono sempre dei
metodi!) per fornirgli le funzionalità necessarie alla nostra applicazione e poiché un esempio è ben più chiaro di mille
parole, vediamo ora un caso pratico.
Il nostro esempio dimostrerà l'uso dell'evento di timer e per far ciò creeremo un widget il cui aspetto esteriore sarà
una stringa testuale scorrevole verso sinistra; le lettere scorreranno di un pixel ogni 100 millesimi di secondo. Questo
è un ottimo esempio, fornitoci dalla letteratura ufficiale, utile per comprende il meccanismo degli eventi.
Per prima cosa dovremo creare il nostro primo “custom widget”; per far ciò deriveremo dalla classe QWidget, creata
appositamente allo scopo e successivamente reimplementeremo i metodi virtuali paintEvent(), timerEvent(),
showEvent() ed infine hideEvent().




Autore P. Sereno                                                                 http://www.sereno-online.com/site
Mini Guide Qt
La nostra nuova classe myTimer sarà quindi:

#include <QWidget>

class myTimer : public QWidget
{
public:
      myTimer(QWidget *parent = 0, const char *name = 0);
      void setText(const QString &newText);
      QString text() const { return myText; }

protected:
      void     paintEvent(QPaintEvent *event);
      void     timerEvent(QTimerEvent *event);
      void     showEvent(QShowEvent *event);
      void     hideEvent(QHideEvent *event);

private:
      QString myText;
      int myTimerId;
      int offset;
};


La classe myTimer, di tipo public QWidget presenta tre metodi pubblici: il costruttore (myTimer), il metodo che ci
permette di modificare il testo visualizzato dal widget (setText) ed infine il metodo da usare per leggere il testo
contenuto. Come si può notare, il fatto che la stringa testuale myText sia di tipo privato, ci obbliga a fornire due
metodi pubblici per la sua lettura e scrittura. Questo è il meccanismo tipico usato per nascondere all'esterno la stringa
myText e permettere la sua elaborazione solo attraverso i metodi da noi forniti; questo meccanismo è ampiamente
usato dal toolkit Qt per fornire al programmatore la possibilità di modificare e leggere le proprietà di un widget, senza
però averne accesso diretto.
I metodi privati della nostra classe, ovvero paintEvent(), timerEvent(), showEvent() e hideEvent() rappresentano
invece tutti gli eventi che andremo a gestire; quest'operazione è possibile poiché essi sono metodi virtuali definiti in
QWidget.
Troviamo infine le proprietà della nostra classe, myText, che rappresentano rispettivamente la stringa testuale del
nostro widget, il timer che useremo per gestire la temporizzazione (myTimerId) e la posizione corrente della nostra
stringa, necessaria per gestire lo spostamento verso sinistra ad ogni intervallo di tempo.
Vediamo ora l'implementazione dei metodi della classe myTimer, iniziando dal costruttore.

myTimer::myTimer(QWidget *parent, const char *name)
: QWidget(parent, name)
{
      myTimerId = 0;
      offset=0;
}

Al costruttore della nostra classe passiamo come argomenti due parametri: il primo rappresenta il padre dell'oggetto
(ogni oggetto di Qt ha un padre, nel caso di oggetti “top level”, il puntatore al padre sarà zero) e il secondo
rappresenta il nome che verrà dato all'oggetto (il nome non deve essere confuso con la stringa di testo, bensì è un
valore mnemonico utile per identificare gli oggetti durante le sessioni di debugging).
Soffermiamoci brevemente sulla funzione
QString text() const { return myText; }.
Questa funzione è molto semplice, il suo unico scopo è restituire la stringa testuale del nostro widget. Per modificare
invece tale stringa ricorreremo alla seguente implementazione di setText:

void myTimer::setText(const QString &newText)
{
      myText = newText;
      update();
}



Autore P. Sereno                                                                http://www.sereno-online.com/site
Mini Guide Qt
Questo metodo presenta una peculiarità. Tralasciamo la ovvia myText = newText e concentriamoci sulla update(). Essa
ci permette di lanciare l'evento di paint al nostro widget, la modifica della stringa di testo va infatti ridisegnata a video
e per far ciò occorre scatenare un evento che, una volta riconosciuto dal motore di Qt, ci permetterà il richiamo del
metodo di paintEvent illustrato qui di seguito.

void myTimer::paintEvent(QPaintEvent *)
{
QPainter painter(this);
int textWidth = fontMetrics().width(text());

         if (textWidth < 1)
               return;

         int x = -offset;
         while (x < width())
         {
               painter.drawText(x, 0, textWidth, height(), AlignLeft | AlignVCenter,
               text());
               x += textWidth;
         }
}

Tutti i widgets Qt usano paintEvent() per disegnare a video il widget stesso; perciò nel nostro esempio dovremo
uniformarci a questa filosofia e confinare tutte le operazioni di disegno in questo metodo.
La prima operazione da compiere in un metodo di paintEvent sarà quella di allocare dinamicamente un oggetto di tipo
QPainter, esso è infatti lo strumento che Qt ci mette a disposizione per disegnare l'aspetto di un widget.

L'istruzione QPainter painter(this) ci permette di allocare dinamicamente un oggetto QPainter il cui padre è
il nostro stesso widget (e cioè l'argomento this passato al costruttore).
QPainter fornisce funzioni ottimizzate per disegnare linee, cerchi, archi e corde, ellissi, poligoni; oltre a ciò, consente di
scrivere stringhe testuali controllandone l'allineamento la posizione e tutti gli attributi tipici (colore, font, dimensioni).
Per le operazioni di disegno più evolute, consente inoltre di gestire sistemi e trasformazioni di coordinate.

L'istruzione int textWidth = fontMetrics().width(text()) ci permette di conoscere la dimensione
del testo contenuto nel nostro widget. Per poter comprendere questa istruzione occorre ricordare alcune cose:

fontMetrics()
è un metodo di QPainter che ci permette di conoscere le informazioni metriche associate al font correntemente usato
(quali ad esempio le dimensioni in pixel). L'oggetto restituito da questo metodo sarà di tipo QFontMetrics.
fontMetrics() .width(QString & str)

width() è un metodo proprio di QfontMetrics che ci consente di conoscere la lunghezza in pixel della stringa passata
come argomento (& str)

fontMetrics() .width(text())
la funzione text(), propria del nostro widget, restituisce la stringa contenente il testo che vogliamo visualizzare (per la
precisione myText).

In questo modo, il valore restituito da fontMetrics() .width(text()) sarà proprio la lunghezza in pixel della nostra stringa
di testo, calcolata sulla base del font preselezionato e delle sue dimensioni.

Questo valore, contenuto in textWidth, ci sarà utile per svolgere i calcoli necessari alle operazioni di disegno.
Il blocco di istruzioni seguente:

int x = -offset;
while (x < width())
{
      painter.drawText(x, 0, textWidth, height(),AlignLeft | AlignVCenter, text());
      x += textWidth;
}


Autore P. Sereno                                                                   http://www.sereno-online.com/site
Mini Guide Qt
ci permetterà di disegnare la stringa testuale ripetutamente, sino ad occupare tutta la dimensione orizzontale del
nostro widget, - ottenuta tramite la funzione width() - e, ad ogni iterazione, la posizione orizzontale da cui la stringa
verrà disegnata cambierà di valore, sulla base del calcolo x += textWidth.
L'istruzione su cui è bene soffermare l'attenzione è il richiamo del metodo painter.drawText. Come già
suggerisce il nome stesso, questo è un metodo di QPainter incaricato di disegnare una stringa di testo.

Vediamo ora più in dettaglio i parametri:
x: posizione orizzontale (all'interno del nostro widget) da cui la stringa verrà disegnata
0: posizione verticale (all'interno del nostro widget) da cui la stringa verrà disegnata
textWidth: lunghezza della stringa da disegnare
height(): altezza della stringa da disegnare
AlignLeft | AlignVCenter: queste sono costanti proprie di Qt, usate per informare drawText sul metodo di
allineamento da adottare per il disegno della stringa. Nel nostro caso AlignLeft richiede di allineare la stringa partendo
da sinistra e AlignVCenter richiede un allineamento verticale di tipo “centrato”.


Vediamo ora l'implementazione di showEvent:

void myTimer::showEvent(QShowEvent *event)
{
      myTimerId = startTimer(100);
}

Questo metodo ci permette di far la conoscenza con una funzione propria di QWidget, ovvero startTimer(), questa
funzione attiva il timer (contenuto in ogni widget Qt) e gli assegna un valore di 100 millesimi di secondo. Da questo
momento in poi, il nostro widget genererà un evento di timer ogni 100 millesimi di secondo; questo evento di timer
verrà riconosciuto dal motore di Qt che provvederà a richiamare il nostro metodo timerEvent().

void myTimer::timerEvent(QTimerEvent *event)
{
      ++offset;
      update();
}

timerEvent viene richiamata automaticamente ogni 100 millesimi di secondo, essa incrementa la variabile offset di
uno per simulare il movimento del testo e successivamente richiama update(), metodo proprio di QWidget, che si
occupa di lanciare l'evento di paint e scatenare così la chiamata alla nostra funzione di paintEvent.
Occorre infine ricordare, quando si utilizzano i timers di Qt, che è necessario prima di terminare l'applicazione,
terminarli. A questo compito provvede l'ultimo metodo che andremo ad analizzare.

void myTimer::hideEvent(QHideEvent *event)
{
killTimer(myTimerId)
}

Come si può facilmente osservare, il metodo killTimer, proprio della classe QWidget, si occupa di distruggere il timer
precedentemente attivato.




Autore P. Sereno                                                                 http://www.sereno-online.com/site
Mini Guide Qt

Considerazioni finali
Questa lezione è parte di un ciclo reso disponibile gratuitamente in Internet sul sito

http://www.sereno-online.com/site

Ricordo infine che ogni commento o richiesta di informazioni rappresenta un utile punto di partenza per nuove lezioni
o miglioramenti di quelle già scritte.



Buon divertimento!

Paolo




Autore P. Sereno                                                                 http://www.sereno-online.com/site

Weitere ähnliche Inhalte

Was ist angesagt?

Che cosa è il Qt Framework
Che cosa è il Qt FrameworkChe cosa è il Qt Framework
Che cosa è il Qt FrameworkPaolo Sereno
 
Installazione Qt/Qt Quick per target Android
Installazione Qt/Qt Quick  per target AndroidInstallazione Qt/Qt Quick  per target Android
Installazione Qt/Qt Quick per target AndroidPaolo Sereno
 
Installazione Qt 4.5.3 per Ms Windows
Installazione Qt 4.5.3 per Ms WindowsInstallazione Qt 4.5.3 per Ms Windows
Installazione Qt 4.5.3 per Ms WindowsPaolo Sereno
 
GUI in Gtk+ con Glade & Anjuta
GUI in Gtk+ con Glade & AnjutaGUI in Gtk+ con Glade & Anjuta
GUI in Gtk+ con Glade & Anjutadelfinostefano
 
Installazione Eclipse Cdt Per Qt
Installazione Eclipse Cdt Per QtInstallazione Eclipse Cdt Per Qt
Installazione Eclipse Cdt Per QtPaolo Sereno
 
Introduzione alla programmazione android - Android@tulug lezione 3
Introduzione alla programmazione android - Android@tulug lezione 3Introduzione alla programmazione android - Android@tulug lezione 3
Introduzione alla programmazione android - Android@tulug lezione 3Ivan Gualandri
 
Introduzione alla programmazione Android - Android@tulug
Introduzione alla programmazione Android - Android@tulugIntroduzione alla programmazione Android - Android@tulug
Introduzione alla programmazione Android - Android@tulugIvan Gualandri
 
C(99) gtk 03 - le immagini
C(99) gtk   03 - le immaginiC(99) gtk   03 - le immagini
C(99) gtk 03 - le immaginiMaurizio Carboni
 
C(99) gtk 01 - introduzione e finestre
C(99) gtk   01 - introduzione e finestreC(99) gtk   01 - introduzione e finestre
C(99) gtk 01 - introduzione e finestreMaurizio Carboni
 
C(99) gtk 02 - disporre gli oggetti
C(99) gtk   02 - disporre gli oggettiC(99) gtk   02 - disporre gli oggetti
C(99) gtk 02 - disporre gli oggettiMaurizio Carboni
 
C(99) gtk 04 - label,button e entry
C(99) gtk   04 - label,button e entryC(99) gtk   04 - label,button e entry
C(99) gtk 04 - label,button e entryMaurizio Carboni
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Ivan Gualandri
 
Chakra 2012.9 rec
Chakra 2012.9 recChakra 2012.9 rec
Chakra 2012.9 reckdekda
 
Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Valerio Radice
 
Qt Platform Abstraction
Qt Platform AbstractionQt Platform Abstraction
Qt Platform AbstractionQT-day
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8Valerio Radice
 
Introduzione a WebGL
Introduzione a WebGLIntroduzione a WebGL
Introduzione a WebGLnigerpunk
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!MarioTraetta
 

Was ist angesagt? (20)

Che cosa è il Qt Framework
Che cosa è il Qt FrameworkChe cosa è il Qt Framework
Che cosa è il Qt Framework
 
Installazione Qt/Qt Quick per target Android
Installazione Qt/Qt Quick  per target AndroidInstallazione Qt/Qt Quick  per target Android
Installazione Qt/Qt Quick per target Android
 
Installazione Qt 4.5.3 per Ms Windows
Installazione Qt 4.5.3 per Ms WindowsInstallazione Qt 4.5.3 per Ms Windows
Installazione Qt 4.5.3 per Ms Windows
 
GUI in Gtk+ con Glade & Anjuta
GUI in Gtk+ con Glade & AnjutaGUI in Gtk+ con Glade & Anjuta
GUI in Gtk+ con Glade & Anjuta
 
Installazione Eclipse Cdt Per Qt
Installazione Eclipse Cdt Per QtInstallazione Eclipse Cdt Per Qt
Installazione Eclipse Cdt Per Qt
 
Introduzione alla programmazione android - Android@tulug lezione 3
Introduzione alla programmazione android - Android@tulug lezione 3Introduzione alla programmazione android - Android@tulug lezione 3
Introduzione alla programmazione android - Android@tulug lezione 3
 
Introduzione alla programmazione Android - Android@tulug
Introduzione alla programmazione Android - Android@tulugIntroduzione alla programmazione Android - Android@tulug
Introduzione alla programmazione Android - Android@tulug
 
C(99) gtk 03 - le immagini
C(99) gtk   03 - le immaginiC(99) gtk   03 - le immagini
C(99) gtk 03 - le immagini
 
C(99) gtk 01 - introduzione e finestre
C(99) gtk   01 - introduzione e finestreC(99) gtk   01 - introduzione e finestre
C(99) gtk 01 - introduzione e finestre
 
C(99) gtk 02 - disporre gli oggetti
C(99) gtk   02 - disporre gli oggettiC(99) gtk   02 - disporre gli oggetti
C(99) gtk 02 - disporre gli oggetti
 
C(99) gtk 04 - label,button e entry
C(99) gtk   04 - label,button e entryC(99) gtk   04 - label,button e entry
C(99) gtk 04 - label,button e entry
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2
 
Chakra 2012.9 rec
Chakra 2012.9 recChakra 2012.9 rec
Chakra 2012.9 rec
 
Introduzione a Latex
Introduzione a LatexIntroduzione a Latex
Introduzione a Latex
 
Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)
 
Qt Platform Abstraction
Qt Platform AbstractionQt Platform Abstraction
Qt Platform Abstraction
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
 
Java OCA teoria 1
Java OCA teoria 1Java OCA teoria 1
Java OCA teoria 1
 
Introduzione a WebGL
Introduzione a WebGLIntroduzione a WebGL
Introduzione a WebGL
 
Let's give it a GO!
Let's give it a GO!Let's give it a GO!
Let's give it a GO!
 

Ähnlich wie Qt Lezione6

Sviluppare per microsoft band
Sviluppare per microsoft bandSviluppare per microsoft band
Sviluppare per microsoft bandDotNetCampus
 
SVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDSVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDDotNetCampus
 
PyPaPi Qt Java Framework
PyPaPi Qt Java FrameworkPyPaPi Qt Java Framework
PyPaPi Qt Java FrameworkTiziano Lattisi
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft BandMassimo Bonanni
 
Intercettare gli eventi di mouse e tastiera
Intercettare gli eventi di mouse e tastieraIntercettare gli eventi di mouse e tastiera
Intercettare gli eventi di mouse e tastieraFederico Paparoni
 
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)Paolo Sereno
 
ASP.NET MVC 3: se non ora, quando?
ASP.NET MVC 3: se non ora, quando?ASP.NET MVC 3: se non ora, quando?
ASP.NET MVC 3: se non ora, quando?Giorgio Di Nardo
 
Rich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsRich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsGiorgio Di Nardo
 
Niccolò Becchi: Introduzione a GWT
Niccolò Becchi: Introduzione a GWTNiccolò Becchi: Introduzione a GWT
Niccolò Becchi: Introduzione a GWTfirenze-gtug
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft BandMassimo Bonanni
 
Integrazione continua con TFS Build
Integrazione continua con TFS BuildIntegrazione continua con TFS Build
Integrazione continua con TFS BuildGian Maria Ricci
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a JavascriptRiccardo Piccioni
 
Qt Concurrent
Qt ConcurrentQt Concurrent
Qt ConcurrentQT-day
 
Push Notification, Live Tile e Background Agent
Push Notification, Live Tile e Background AgentPush Notification, Live Tile e Background Agent
Push Notification, Live Tile e Background AgentDomusDotNet
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angulardotnetcode
 

Ähnlich wie Qt Lezione6 (20)

Sviluppare per microsoft band
Sviluppare per microsoft bandSviluppare per microsoft band
Sviluppare per microsoft band
 
SVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDSVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BAND
 
PyPaPi Qt Java Framework
PyPaPi Qt Java FrameworkPyPaPi Qt Java Framework
PyPaPi Qt Java Framework
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft Band
 
Intercettare gli eventi di mouse e tastiera
Intercettare gli eventi di mouse e tastieraIntercettare gli eventi di mouse e tastiera
Intercettare gli eventi di mouse e tastiera
 
Corso java
Corso javaCorso java
Corso java
 
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)
Qt 4.5.3 con Visual C++ Express 2008 (edizione gratuita!)
 
ASP.NET MVC 3: se non ora, quando?
ASP.NET MVC 3: se non ora, quando?ASP.NET MVC 3: se non ora, quando?
ASP.NET MVC 3: se non ora, quando?
 
Yagwto
YagwtoYagwto
Yagwto
 
Rich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.jsRich client application: MVC4 + MVVM = Knockout.js
Rich client application: MVC4 + MVVM = Knockout.js
 
Design Pattern
Design PatternDesign Pattern
Design Pattern
 
Niccolò Becchi: Introduzione a GWT
Niccolò Becchi: Introduzione a GWTNiccolò Becchi: Introduzione a GWT
Niccolò Becchi: Introduzione a GWT
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft Band
 
Integrazione continua con TFS Build
Integrazione continua con TFS BuildIntegrazione continua con TFS Build
Integrazione continua con TFS Build
 
corso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascriptcorso web developer - Introduzione a Javascript
corso web developer - Introduzione a Javascript
 
Qt Concurrent
Qt ConcurrentQt Concurrent
Qt Concurrent
 
Push Notification, Live Tile e Background Agent
Push Notification, Live Tile e Background AgentPush Notification, Live Tile e Background Agent
Push Notification, Live Tile e Background Agent
 
Corso Javascript
Corso JavascriptCorso Javascript
Corso Javascript
 
Js intro
Js introJs intro
Js intro
 
Meetup ASP.NET Core Angular
Meetup ASP.NET Core AngularMeetup ASP.NET Core Angular
Meetup ASP.NET Core Angular
 

Qt Lezione6

  • 1. Mini Guide Qt Qt toolkit Gestione degli eventi Premessa Questa presentazione è rilasciata sotto Licenza Creative Commons: Attribution-NonCommercial-NoDerivativeWorks (http://creativecommons.org/licenses/by-nc-nd/3.0/deed.it). Questo documento può quindi essere riprodotto senza violare nessuna legge, sia in versione elettronica, sia in versione cartacea, purché sia riprodotto integralmente in tutte le sue parti, compresa la pagina che contiene queste informazioni: Versione originale scaricabile dal sito http://www.sereno-online.com/site/ Tutti i marchi riportati in questa pubblicazione appartengono ai rispettivi proprietari. Link Utili Qui di seguito riporto alcuni link utili per chi usa quotidianamente l’ambiente di sviluppo Qt e vuole confrontarsi con altri sviluppatore, utenti e semplici appassionati di questo toolkit gratuito ed open source. Gruppo Programmatori Italiani Qt Software (GPIQt) http://www.facebook.com/inbox/?ref=mb#/group.php?gid=81561439535 qt in Italy http://qt-apps.org/groups/?id=17 qtitaliantranslators http://gitorious.org/+qtitaliantranslators Autore P. Sereno http://www.sereno-online.com/site
  • 2. Mini Guide Qt Scopo Questa lezione vuole essere un semplice avvicinamento al meccanismo di gestione degli eventi di Qt. L’argomento per poter essere spiegato correttamente deve essere affiancato da esempi pratici; a questo scopo si è pensato di creare un custom widget per intercettare gli eventi più importanti e proporre al lettore alcune soluzioni. Event Driven Le applicazioni GUI vengono definite applicazioni di tipo “event-driven”, ovvero pilotate dagli eventi; questa definizione è davvero rappresentativa, in quanto in un'applicazione GUI, tutto ciò che succede è il risultato di un evento. Quando programmiamo con il toolkit Qt, raramente abbiamo bisogno di preoccuparci del meccanismo degli eventi, poiché i widgets Qt che usiamo emettono autonomamente dei segnali nel momento in cui occorre qualcosa di significativo. La gestione degli eventi diventa quindi importante nel momento in cui vogliamo scrivere dei nuovi custom widgets o vogliamo modificare il comportamento di widgets esistenti. Eventi di Paint Gli eventi vengono generati da Qt in risposta a diverse situazioni: quando viene premuto un tasto sulla tastiera, oppure un tasto del mouse, Qt si incarica di generare un evento. Un evento però può anche essere generato in seguito al riposizionamento di una finestra sul desktop, in quanto caso ad esempio, il sistema di gestione delle finestre riceve un evento che usa per ridisegnare ciò che prima era nascosto dalla finestra; in questo caso parleremo di evento di Paint (disegno). Terminiamo ora la nostra breve carrellata citando l'evento di Show. Come già visto nelle lezioni precedenti, la creazione di un widget non implica automaticamente la sua visibilità, bisogna infatti richiamare esplicitamente il metodo di show() per disegnarlo a video. Richiamare il metodo di show() è il metodo che Qt ci offre per informare il motore di disegno del toolkit che un widget, di cui noi abbiamo definito le proprietà grafiche, testuali, di posizione e dimensioni, deve essere ridisegnato. Eventi del Timer Un altro evento, molto comune nella pratica, è il timer. Se gli eventi visti sin'ora occorrono come risultato di un'azione eseguita dall'utente dell'applicazione, i timers permettono all'applicazione stessa di eseguire un compito ad intervallo di tempo. Un esempio pratico: myTimer Gli esempi riportati ci permettono di capire la filosofia che sta dietro agli eventi, ma nulla è ancora stato detto su come essi “vengono implementati”. Nel mondo Qt, un evento è un metodo virtuale, il che vuol dire, semplificando il concetto, che quando deriviamo da una classe di partenza con eventi, possiamo reimplementarli (sono sempre dei metodi!) per fornirgli le funzionalità necessarie alla nostra applicazione e poiché un esempio è ben più chiaro di mille parole, vediamo ora un caso pratico. Il nostro esempio dimostrerà l'uso dell'evento di timer e per far ciò creeremo un widget il cui aspetto esteriore sarà una stringa testuale scorrevole verso sinistra; le lettere scorreranno di un pixel ogni 100 millesimi di secondo. Questo è un ottimo esempio, fornitoci dalla letteratura ufficiale, utile per comprende il meccanismo degli eventi. Per prima cosa dovremo creare il nostro primo “custom widget”; per far ciò deriveremo dalla classe QWidget, creata appositamente allo scopo e successivamente reimplementeremo i metodi virtuali paintEvent(), timerEvent(), showEvent() ed infine hideEvent(). Autore P. Sereno http://www.sereno-online.com/site
  • 3. Mini Guide Qt La nostra nuova classe myTimer sarà quindi: #include <QWidget> class myTimer : public QWidget { public: myTimer(QWidget *parent = 0, const char *name = 0); void setText(const QString &newText); QString text() const { return myText; } protected: void paintEvent(QPaintEvent *event); void timerEvent(QTimerEvent *event); void showEvent(QShowEvent *event); void hideEvent(QHideEvent *event); private: QString myText; int myTimerId; int offset; }; La classe myTimer, di tipo public QWidget presenta tre metodi pubblici: il costruttore (myTimer), il metodo che ci permette di modificare il testo visualizzato dal widget (setText) ed infine il metodo da usare per leggere il testo contenuto. Come si può notare, il fatto che la stringa testuale myText sia di tipo privato, ci obbliga a fornire due metodi pubblici per la sua lettura e scrittura. Questo è il meccanismo tipico usato per nascondere all'esterno la stringa myText e permettere la sua elaborazione solo attraverso i metodi da noi forniti; questo meccanismo è ampiamente usato dal toolkit Qt per fornire al programmatore la possibilità di modificare e leggere le proprietà di un widget, senza però averne accesso diretto. I metodi privati della nostra classe, ovvero paintEvent(), timerEvent(), showEvent() e hideEvent() rappresentano invece tutti gli eventi che andremo a gestire; quest'operazione è possibile poiché essi sono metodi virtuali definiti in QWidget. Troviamo infine le proprietà della nostra classe, myText, che rappresentano rispettivamente la stringa testuale del nostro widget, il timer che useremo per gestire la temporizzazione (myTimerId) e la posizione corrente della nostra stringa, necessaria per gestire lo spostamento verso sinistra ad ogni intervallo di tempo. Vediamo ora l'implementazione dei metodi della classe myTimer, iniziando dal costruttore. myTimer::myTimer(QWidget *parent, const char *name) : QWidget(parent, name) { myTimerId = 0; offset=0; } Al costruttore della nostra classe passiamo come argomenti due parametri: il primo rappresenta il padre dell'oggetto (ogni oggetto di Qt ha un padre, nel caso di oggetti “top level”, il puntatore al padre sarà zero) e il secondo rappresenta il nome che verrà dato all'oggetto (il nome non deve essere confuso con la stringa di testo, bensì è un valore mnemonico utile per identificare gli oggetti durante le sessioni di debugging). Soffermiamoci brevemente sulla funzione QString text() const { return myText; }. Questa funzione è molto semplice, il suo unico scopo è restituire la stringa testuale del nostro widget. Per modificare invece tale stringa ricorreremo alla seguente implementazione di setText: void myTimer::setText(const QString &newText) { myText = newText; update(); } Autore P. Sereno http://www.sereno-online.com/site
  • 4. Mini Guide Qt Questo metodo presenta una peculiarità. Tralasciamo la ovvia myText = newText e concentriamoci sulla update(). Essa ci permette di lanciare l'evento di paint al nostro widget, la modifica della stringa di testo va infatti ridisegnata a video e per far ciò occorre scatenare un evento che, una volta riconosciuto dal motore di Qt, ci permetterà il richiamo del metodo di paintEvent illustrato qui di seguito. void myTimer::paintEvent(QPaintEvent *) { QPainter painter(this); int textWidth = fontMetrics().width(text()); if (textWidth < 1) return; int x = -offset; while (x < width()) { painter.drawText(x, 0, textWidth, height(), AlignLeft | AlignVCenter, text()); x += textWidth; } } Tutti i widgets Qt usano paintEvent() per disegnare a video il widget stesso; perciò nel nostro esempio dovremo uniformarci a questa filosofia e confinare tutte le operazioni di disegno in questo metodo. La prima operazione da compiere in un metodo di paintEvent sarà quella di allocare dinamicamente un oggetto di tipo QPainter, esso è infatti lo strumento che Qt ci mette a disposizione per disegnare l'aspetto di un widget. L'istruzione QPainter painter(this) ci permette di allocare dinamicamente un oggetto QPainter il cui padre è il nostro stesso widget (e cioè l'argomento this passato al costruttore). QPainter fornisce funzioni ottimizzate per disegnare linee, cerchi, archi e corde, ellissi, poligoni; oltre a ciò, consente di scrivere stringhe testuali controllandone l'allineamento la posizione e tutti gli attributi tipici (colore, font, dimensioni). Per le operazioni di disegno più evolute, consente inoltre di gestire sistemi e trasformazioni di coordinate. L'istruzione int textWidth = fontMetrics().width(text()) ci permette di conoscere la dimensione del testo contenuto nel nostro widget. Per poter comprendere questa istruzione occorre ricordare alcune cose: fontMetrics() è un metodo di QPainter che ci permette di conoscere le informazioni metriche associate al font correntemente usato (quali ad esempio le dimensioni in pixel). L'oggetto restituito da questo metodo sarà di tipo QFontMetrics. fontMetrics() .width(QString & str) width() è un metodo proprio di QfontMetrics che ci consente di conoscere la lunghezza in pixel della stringa passata come argomento (& str) fontMetrics() .width(text()) la funzione text(), propria del nostro widget, restituisce la stringa contenente il testo che vogliamo visualizzare (per la precisione myText). In questo modo, il valore restituito da fontMetrics() .width(text()) sarà proprio la lunghezza in pixel della nostra stringa di testo, calcolata sulla base del font preselezionato e delle sue dimensioni. Questo valore, contenuto in textWidth, ci sarà utile per svolgere i calcoli necessari alle operazioni di disegno. Il blocco di istruzioni seguente: int x = -offset; while (x < width()) { painter.drawText(x, 0, textWidth, height(),AlignLeft | AlignVCenter, text()); x += textWidth; } Autore P. Sereno http://www.sereno-online.com/site
  • 5. Mini Guide Qt ci permetterà di disegnare la stringa testuale ripetutamente, sino ad occupare tutta la dimensione orizzontale del nostro widget, - ottenuta tramite la funzione width() - e, ad ogni iterazione, la posizione orizzontale da cui la stringa verrà disegnata cambierà di valore, sulla base del calcolo x += textWidth. L'istruzione su cui è bene soffermare l'attenzione è il richiamo del metodo painter.drawText. Come già suggerisce il nome stesso, questo è un metodo di QPainter incaricato di disegnare una stringa di testo. Vediamo ora più in dettaglio i parametri: x: posizione orizzontale (all'interno del nostro widget) da cui la stringa verrà disegnata 0: posizione verticale (all'interno del nostro widget) da cui la stringa verrà disegnata textWidth: lunghezza della stringa da disegnare height(): altezza della stringa da disegnare AlignLeft | AlignVCenter: queste sono costanti proprie di Qt, usate per informare drawText sul metodo di allineamento da adottare per il disegno della stringa. Nel nostro caso AlignLeft richiede di allineare la stringa partendo da sinistra e AlignVCenter richiede un allineamento verticale di tipo “centrato”. Vediamo ora l'implementazione di showEvent: void myTimer::showEvent(QShowEvent *event) { myTimerId = startTimer(100); } Questo metodo ci permette di far la conoscenza con una funzione propria di QWidget, ovvero startTimer(), questa funzione attiva il timer (contenuto in ogni widget Qt) e gli assegna un valore di 100 millesimi di secondo. Da questo momento in poi, il nostro widget genererà un evento di timer ogni 100 millesimi di secondo; questo evento di timer verrà riconosciuto dal motore di Qt che provvederà a richiamare il nostro metodo timerEvent(). void myTimer::timerEvent(QTimerEvent *event) { ++offset; update(); } timerEvent viene richiamata automaticamente ogni 100 millesimi di secondo, essa incrementa la variabile offset di uno per simulare il movimento del testo e successivamente richiama update(), metodo proprio di QWidget, che si occupa di lanciare l'evento di paint e scatenare così la chiamata alla nostra funzione di paintEvent. Occorre infine ricordare, quando si utilizzano i timers di Qt, che è necessario prima di terminare l'applicazione, terminarli. A questo compito provvede l'ultimo metodo che andremo ad analizzare. void myTimer::hideEvent(QHideEvent *event) { killTimer(myTimerId) } Come si può facilmente osservare, il metodo killTimer, proprio della classe QWidget, si occupa di distruggere il timer precedentemente attivato. Autore P. Sereno http://www.sereno-online.com/site
  • 6. Mini Guide Qt Considerazioni finali Questa lezione è parte di un ciclo reso disponibile gratuitamente in Internet sul sito http://www.sereno-online.com/site Ricordo infine che ogni commento o richiesta di informazioni rappresenta un utile punto di partenza per nuove lezioni o miglioramenti di quelle già scritte. Buon divertimento! Paolo Autore P. Sereno http://www.sereno-online.com/site