1
Marco Tarini
Università dell’Insubria
Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 2011/12
Computer Graphics Lab
Notes 3: event based prog & QT
Struttura programma tradizionale
• Struttura classica dei programmi a linea di comando:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
main() {
init();
do_my_beautiful_algorithm();
exit();
}
non va bene per applicazioni interattive interattive interattive interattive !
Struttura programma nel paradigma Event Event Event Event----Based Based Based Based
• Sistema a eventi
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
main() {
init();
while (true) { get_event() ; process_event();
}
} eventi tipo:
• mouse, tastiera...
• sistema di finistre
• reshape, minimizzazione...
• generati dall'applicazione stessa
• o da thread differenti
{
ciclo degli eventi
Esempio: applicazione con lib SDL SDL SDL SDL
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
bool done= false;
while ( ! done) /* ciclo degli eventi */
{
SDL_Event event;
SDL_WaitEvent(&event);
switch(event.type) {
case SDL_VIDEOEXPOSE: /* evento "ridisegnati" */
myRendering(); /* riempi screen buffer*/
break;
case SDL_QUIT:
done= true; break ; case SDL_KEYDOWN:
if ( event.key.keysym.sym== SDLK_ESCAPE) done= true;
break;
} } SDL_Quit();
return 1;
}
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
c i c l o d e g l i e v e n t i
Programmare un Event-Based con CallBack
• CallBack CallBack CallBack CallBack:
– funzione preposta alla gestione di un evento evento evento evento – di solito,
un funtore da registrare per gestire quell’evento
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a void myRendering() // la mia callback per l’evento “disegnati”
{
...
}
void main(){
glutDisplayFunc
( myRendering); // registra la callback...
glutMainLoop();
}
es es es es:::: GLUT GLUT GLUT GLUT library library library library
Programmare un Event-Based con SIGNALS SIGNALS SIGNALS SIGNALS e SLOTS SLOTS SLOTS SLOTS
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Object2 signal1 slot1 slot2 Object4
slot1 slot2 slot3 Object1
signal1 signal2
Object3 signal1 slot1
connect(Object1, signal1, Object2, slot1) connect(Object1, signal1, Object2, slot2)
connect ( Object1, signal2, Object4, slot1 )
connect(Object3, signal1, Object4, slot3)
2
QT: slots, signals, e connect
class A: public class QObject {
Q_OBJECT
public:
A(); // costruttore
protected:
...;
public slots:
void unMetodo( ); // uno slot!
};
class B: public class QObject {
Q_OBJECT
signals:
void unTrigger( ); // un signal!
};
{
A*a= new A();
B*b= new B();
connect( b, SIGNAL( unTrigger()) , a, SLOT( unMetodo()) );
}
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
quando a “emette” quel segnale
==>
b deve eseguire quel metodo (da B: )
emit unTrigger( );QT: slots, signals, e connect
class A: public class QObject {
Q_OBJECT
public:
A(); // costruttore
protected:
...;
public slots:
void unMetodo( int); // uno slot!
};
class B: public class QObject {
Q_OBJECT
signals:
void unTrigger( int); // un signal!
};
{
A*a= new A();
B*b= new B();
connect( b, SIGNAL( unTrigger( int)) , a, SLOT( unMetodo( int)) );
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a}
quando a “emette” quel segnale
==>
b deve eseguire quel metodo (da B: )
emit unTrigger(5);QT: un hello-world
#include <QApplication>
class MiaMainWindow:public QWidget {
public:
MiaMainWindow ():QWidget(0){
setWindowTitle(“Hello World");
} };
int main(int argc, char** argv){
QApplication app(argc, argv);
MiaMainWindow win;
win.show();
return app.exec();
}
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
QT classes
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
QObject
… …
…
… QWidget
QWindow QButton … QSlider
…
signals &
slots
Stringhe in QT
#include <QString>
void Pippo(){
Persona pers;
QString a
a = QString(“La persona %1 ha %2 anni (%3 - %4 = %2)”) .arg( pers.nome ) // argomento 1 (un char*) .arg( pers.eta() ) // argomento 2 (un int) .arg( pers.annoNascita ) // argomento 3 (un int) .arg( ANNO_CORRENTE ) // argomento 4 (un unsigned int)
; }
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a