Elemi alkalmazások fejlesztése III Egy ablakos alkalmazás készítése I. C++ / Qt felhasználásával készítette: Szabóné Nacsa Rozália 1
Ajánlott irodalom Qt dokumentáció online: www.trolltech.com lokális változat: Kdevelop help vagy /usr/share/doc... Nyomtatható változat: www.trolltech.com ról PDF www.trolltech.com formátumban 2
A Qt assistant elindítása Alt F2 vel behívjuk a parancsablakot, majd kiadjuk az assistant parancsot. 3
A Qt assistant nyitó ablaka 4
5
GUI alkalmazás Qt osztályokkal 6
QObject Hello Qt alkalmazás QLabel QApplication #include <qapplication.h> #include <qlabel.h> hello.cpp int main(int argc,char *argv[]) { QApplication app(argc,argv); QLabel *label = new QLabel("Hello Qt!",0); app.setmainwidget(label); label >show(); return app.exec(); } 7
Fordítás/futtatás parancs sorból Linux 1. 2. 3. 4. qmake project qmake hello.pro make./hello 8
Fordítás/futtatás parancs sorból Windows 1. 2. 3. 4. qmake project qmake hello.pro nmake hello 9
QObject QPushButton Quit alkalmazás QApplication #include <qapplication.h> #include <qpushbutton.h> quit.cpp int main(int argc, char *argv[]) { QApplication app(argc,argv); QPushButton *button = new QPushButton("Quit",0); QObject::connect(button,SIGNAL(clicked()),&app,SLOT(quit())); app.setmainwidget(button); button >show(); return app.exec(); } 10
Signal / slot mechanizmus Slotok Slotok Signálok button clicked() Signálok quit() app connect( button, SIGNAL( clicked() ), &app, SLOT( quit() ) ); A gomb clicked() szignált küld. Ezt a szignált hozzákötjük az alkalmazás quit() slotjához (speciálisan kezelt műveletéhez). 11
Fordítás/futtatás parancs sorból Linux 1. 2. 3. 4. qmake project qmake quit.pro make./quit 12
Numbers alkalmazás form.h form.cpp main.cpp Form: főablakot reprezentáló osztály 13
Form ablak látvány terve Caption QVBox QHBox QSpinBox QSlider QLineEdit 14
Form osztály definíció #ifndef FORM_H #define FORM_H #include <qwidget.h> #include <qvbox.h> form.h class QHBox; class QSpinBox; class QSlider; class QLineEdit; class Form: public QVBox { public: Form(QWidget *parent=0, const char *name=0); private: QHBox *hbox; QSpinBox *spinbox; QSlider *slider; QLineEdit *lineedit; }; #endif Caption QVBox QHBox QSpinBox QSlider QLineEdit 15
Form osztály implementáció 1 #include <qhbox.h> #include <qspinbox.h> #include <qslider.h> #include <qlineedit.h> #include "form.h"... form.cpp Caption QVBox QHBox QSpinBox QSlider QLineEdit 16
Form osztály implementáció 2... Form::Form(QWidget *parent, const char *name) :QVBox(parent,name) { setmargin(6); Caption setspacing(6); hbox = new QHBox(this); lineedit = new QLineEdit(this); hbox >setmargin(6); hbox >setspacing(6); spinbox = new QSpinBox(hbox); slider = new QSlider(Qt::Horizontal,hbox); slider >setrange(0,10); spinbox >setrange(0,10); form.cpp QVBox QHBox QSpinBox QSlider QLineEdit spinbox >setvalue(5); connect(slider,signal(valuechanged(int)),spinbox,slot(setvalue(int))); connect(spinbox,signal(valuechanged(int)),slider,slot(setvalue(int))); } 17
Signal / slot mechanizmus Slotok Signálok slider valuechanged(int) Slotok Signálok setvalue(int) spinbox connect(slider,signal(valuechanged(int)),spinbox,slot(setvalue(int))); A csúszka értékváltozás esetén valuechanged(int) szignált küld. Ezt a szignált hozzákötjük a számkijelző setvalue(int) slotjához (speciálisan kezelt műveletéhez). 18
Saját slot kezelése definíció... class Form: public QVBox { Q_OBJECT form.h A Q_OBJECT makróban vannak a moc számára a függvénydeklarációk. public: Form(QWidget *parent=0, const char *name=0); private: QHBox *hbox; QSpinBox *spinbox; QSlider *slider; QLineEdit *lineedit; QString words[11]; void initwords(); public slots: void sayasword(int i); };... moc: meta object compiler Nem szabványos C++ elem. A moc készíti el a szabványos C++ kódot. 19
Saját slot kezelése implementáció 1... Form::Form(QWidget *parent, const char *name) :QVBox(parent,name) { setmargin(6); setspacing(6); form.cpp... connect(slider,signal(valuechanged(int)),spinbox,slot(setvalue(int))); connect(spinbox,signal(valuechanged(int)),slider,slot(setvalue(int))); connect(slider,signal(valuechanged(int)),this,slot(sayasword(int))); initwords(); spinbox >setvalue(5); } Saját slot A kezdőértéket a kapcsolat kiépítése után kell beállítani 20
Saját slot kezelése implementáció 2... void Form::sayAsWord(int i) { lineedit >settext(words[i]); } form.cpp void Form::initWords() { words[0] = "null"; words[1] = "one";... words[10] = "ten"; } 21
Numbers projekt fájl TEMPLATE = app INCLUDEPATH +=. # Input HEADERS += form.h SOURCES += form.cpp main.cpp 1. 2. 3. 4. qmake project qmake numbers.pro make./numbers 22
Memória gazdálkodás (widget) Form(QVBOX) Caption gyerek lista QVBox QHBox QSpinBox QHBox(hbox) QSlider QSpinBox(spinBox) QLineEdit QSilder(slider) QLineEdit(lineEdit) Csak azokat a widget eket kell törölni, amelyeket new operátorral hozunk létre és nincs szülője. 23
Widget Layout Manager Caption Caption mainlayout QVBox QHBox QSpinBox QSlider QLineEdit toplayout QSpinBox QSlider QLineEdit 24
Memória gazdálkodás (layout) mainlayout Form Caption QSpinBox(spinBox) QSlider(slider) QSpinBox QSlider QLineEdit(lineEdit) QLineEdit QVBoxLayout(mainLayout) toplayout QVBoxLayout(topLayout) Csak azokat a widget eket kell törölni, amelyeket new operátorral hozunk létre és nincs szülője. 25
Form osztály definíció #include <qwidget.h> form.h class QSpinBox; class QSlider; class QLineEdit; class Form: public QWidget { Q_OBJECT public: Form(QWidget *parent=0, const char *name=0); private: QSpinBox *spinbox; QSlider *slider; QLineEdit *lineedit; QString words[11]; void initwords(); public slots: void sayasword(int i); }; Caption QSpinBox QSlider QLineEdit 26
Form osztály implementáció 1 #include <qlayout.h> #include <qspinbox.h> #include <qslider.h> #include <qlineedit.h> #include "form.h"... form.cpp Caption QSpinBox QSlider QLineEdit 27
Form osztály implementáció 2... Form::Form(QWidget *parent, const char *name):qwidget(parent,name) { spinbox = new QSpinBox(this); slider = new QSlider(Qt::Horizontal,this); slider >setrange(0,10); Caption spinbox >setrange(0,10); lineedit = new QLineEdit(this); QHBoxLayout *toplayout = new QHBoxLayout; toplayout >addwidget(spinbox); toplayout >addwidget(slider); QVBoxLayout *mainlayout = new QVBoxLayout(this); QSpinBox form.cpp QSlider QLineEdit mainlayout >addlayout(toplayout); mainlayout >addwidget(lineedit); mainlayout >setmargin(11); mainlayout >setspacing(6); connect(slider,signal(valuechanged(int)),spinbox,slot(setvalue(int))); connect(spinbox,signal(valuechanged(int)),slider,slot(setvalue(int))); connect(spinbox,signal(valuechanged(int)),this,slot(sayasword(int))); initwords(); spinbox >setvalue(5); } 28
Layout projekt fájl form.h TEMPLATE = app INCLUDEPATH +=. # Input HEADERS += form.h SOURCES += form.cpp main.cpp form.cpp 1. 2. 3. 4. main.cpp qmake project qmake layout.pro make./layout 29
GUI alkalmazás Qt Designerrel 30
A.ui fájl és a generált kód Qt designer form.ui UIC Írás, olvasás Olvasás Generálás #includes Eszköz (tool) Generált forráskód Felhasználó forráskódja form.h form.cpp main.cpp 31
Származtatásos modulszerkezet form.ui UIC Írás, olvasás Olvasás Generálás #includes Eszköz (tool) Generált forráskód Felhasználó forráskódja Öröklődés Qt designer formbase.h form.h formbase.cpp form.cpp main.cpp A formbase.h és a formbase.cpp minden módosításnál újra generálódik. Az alkalmazás specifikus funkciókat a származtatott osztályban adjuk meg. 32
ui.h s modulszerkezet form.ui.h Qt designer form.ui Az alkalmazásspecifius funkciókat a form.ui.h implementációs fájlban adjuk meg. Írás, olvasás Olvasás Generálás #includes Eszköz (tool) Generált forráskód Felhasználó forráskódja UIC form.h form.cpp main.cpp 33
Qt Designer indítása 34
A QtDesigner ablakai ProjectOverview Toolbox ObjectExplorer Properties Editor/ Signal Handlers 35
File/New/C++ Project 36
File/New/C++ Project 37
38
Elrendezés 39
Edit/Connections <connections> form.ui <connection> <sender>slider</sender> <signal>valuechanged(int)</signal> <receiver>spinbox</receiver> <slot>setvalue(int)</slot> </connection> <connection> <sender>spinbox</sender> <signal>valuechanged(int)</signal> <receiver>slider</receiver> <slot>setvalue(int)</slot> </connection> </connections> 40
Változó deklarálása 41
Saját slot létrehozása Edit/Slots... /New Function Edit/Connections 42
void Form::sayAsWord( int i) { lineedit >settext(words[i]); } 43
Saját függvény és konstruktor létrehozása Edit/Slots... /New Function void Form::init() { spinbox >setmaxvalue(10); slider >setmaxvalue(10); initwords(); spinbox >setvalue(5); } A Form konstruktora után automatikusan végrehajtódik az init() metódus. void Form::initWords() { words[0] = "null";... words[10] = "ten"; } 44
main függvény beillesztése Edit/Slots... /C++ Main file 45
Generált main.cpp program #include <qapplication.h> #include "form.h" int main( int argc, char ** argv ) { QApplication a( argc, argv ); Form w; w.show(); a.connect( &a, SIGNAL( lastwindowclosed() ), &a, SLOT( quit() ) ); return a.exec(); } 46
Fordítás/futtatás 1. 2. 3. qmake project qmake words.pro make 47
Words projekt fájl TEMPLATE = app INCLUDEPATH +=. # Input HEADERS += form.ui.h INTERFACES += form.ui SOURCES += main.cpp 1. 2. 3. 4. qmake project qmake o Makefile words.pro make./words 48
Gyakorló feladat Feladat: Egészítse ki a projektet úgy, hogy a szám szöveges begépelésére, ha van az adott szöveghez szám, akkor a SpinBox és a Slider automatikusan álljon be a megadott értékre. Gépelés 49
Saját slot deklarációja 50
Saját slot implementálása void Form::slotTextChanged_( const QString & s ) { bool l=false; for (int i=0; i< (int) sizeof(words)/sizeof(words[0]) &&!l;i++) { if(words[i]==s) { l=true; slider >setvalue(i); } } } 51
Saját slot összekapcsolása eseménnyel 52
Legyen Ön is milliomos példa Gomb + kép Szerkeszthető szöveg LCD kijelző Gomb csoport Gomb + szöveg Radio Button 53
Szövegdoboz elhelyezése A Qt eszköztárából válasszuk ki a TextEdit eszközt 1 2 3 Kattintsunk a szövegdoboz tervezett helyére. 54
Pixmap gomb elhelyezése PushButton 1 3 2 Kattintsunk a vezérlőelem tervezett helyére. 4 Válaszunk képet a gomb felirata helyett. 55
LCDNumber Számkijelző elhelyezése 1 2 56
Távtartó (spacer) elhelyezése Spacer Az endbutton és az LCD kijelző közé elhelyezhetünk egy távtartót. 57
Elrendezés szabályozása 2 Kattintsunk a Lay Out Vertically gombra. Jelöljük ki egyszerre mindhárom elemet. 1 58
Layout toolbar Ezzel a gombbal lehet megszüntetni a csoportot. A piros keret jelzi az elemek összetartozását 59
TextLabel Kérdés elhelyezése 60
ButtonGroup Válasz keret elhelyezése 61
Radio Button Válaszok elhelyezése 1 62
Válaszok elhelyezése 2 63
A Következő gomb elhelyezése 64
65
Grid Layout A szabályos elrendezéshez kattintson a Lay Out in a Grid gombra Ne legyen elem kiválasztva. 66
Főprogram beillesztése 67
#include <qapplication.h> #include "millmain.h" int main( int argc, char ** argv ) { QApplication a( argc, argv ); MillMain w; w.show(); a.connect( &a, SIGNAL( lastwindowclosed() ), &a, SLOT( quit() ) ); return a.exec(); } 68
Viselkedés tesztelése Ctrl T Itt léphet ki a tesztelésből. A szövegek elrendezése változik az ablak méretével. 69
Tennivalók az alkalmazásunkban Következő kérdés feladása nextquestion() Válasz ellenőrzése checkanswer() Kilépés endbutton() 70
Tennivalók az alkalmazásunkban Következő kérdés feladása nextquestion() Válasz ellenőrzése checkanswer() Kilépés endbutton() connect( nextbutton, SIGNAL( clicked() ), this, SLOT( nextquestion() ) ); connect( ansgroup, SIGNAL( clicked(int) ), this, SLOT( checkanswer(int) ) ); connect( endbutton, SIGNAL( clicked() ), this, SLOT( endgame() ) ); 71
Saját slotok beillesztése Edit/Slots void MillMain::nextQuestion( ) millmain.ui.h { qwarning( tr("millmain::nextquestion(): Not implemented yet" )); } void MillMain::checkAnswer(int ) millmain.ui.h { qwarning( tr("millmain::nextquestion(): Not implemented yet" )); } 72
Edit/Connections connect( nextbutton, SIGNAL( clicked() ), this, SLOT( nextquestion() ) ); connect( ansgroup, SIGNAL( clicked(int) ), this, SLOT( checkanswer(int) ) ); connect( endbutton, SIGNAL( clicked() ), this, SLOT( endgame() ) ); 73
millmain.ui.h Qt designer millmain.ui form.ui UIC Írás, olvasás Olvasás Generálás #includes Eszköz (tool) Generált forráskód Felhasználó forráskódja millmain.h millmain.cpp main.cpp 74
millmain.ui.h void MillMain::nextQuestion() { qwarning( tr("millmain::nextquestion(): Not implemented yet" )); } void MillMain::checkAnswer( int ) { qwarning( tr("millmain::nextquestion(): Not implemented yet" )); } void MillMain::endGame() { qwarning( tr("millmain::nextquestion(): Not implemented yet" )); } 75
Fordítás/futtatás 76
Vége, de... A munkafüzet programjai letölthetők a people.inf.elte.hu/nacsa/eaf3/projects címről. 77