Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája

Hasonló dokumentumok
Eseményvezérelt alkalmazások fejlesztése I 5. előadás. Grafikus felületű alkalmazások architektúrája. Grafikus felületű alkalmazások architektúrája

Modell megvalósítása. Gregorics Tibor: Eseményvezérelt alkalmazások fejlesztése I.

3. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Általános szoftver architektúrák. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése I 12. előadás. Összetett szoftver architektúrák. Giachetta Roberto

Általános szoftver architektúrák

2. Beadandó feladat dokumentáció

2. Beadandó feladat dokumentáció

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Giachetta Roberto

ELTE, Informatikai Kar december 12.

1. Beadandó feladat dokumentáció

Komponens alapú szoftverfejlesztés 8. előadás. Szoftver architektúrák alapvetései. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Eseményvezérelt alkalmazások fejlesztése I 3. előadás. Dinamikus felületű alkalmazások. Giachetta Roberto

Eseményvezérelt alkalmazások fejlesztése II 5. előadás. Windows Forms alkalmazások párhuzamosítása. Cserép Máté

Szoftvertechnológia 5. előadás. Objektumorientált tervezés: architektúra. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Szoftvertechnológia 6. előadás. Objektumorientált tervezés: állapotkezelés. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Elemi alkalmazások fejlesztése III.

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET)

Johanyák Zsolt Csaba: Ugráló gomb oktatási segédlet Copyright 2008 Johanyák Zsolt Csaba

Java Programozás 4. Gy: Java GUI. Tipper, MVC kalkulátor

Szoftvertechnológia 7. előadás. Objektumorientált tervezés: végrehajtás. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET) Cserép Máté.

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása. Biztonságos adattípusok megvalósítása

Elemi alkalmazások fejlesztése III.

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása

Eseményvezérelt alkalmazások fejlesztése I 7. előadás. Összetett grafikus felületű alkalmazások. Giachetta Roberto

Java Programozás 11. Ea: MVC modell

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

Eseményvezérelt alkalmazások fejlesztése II 3. előadás. Windows Forms dinamikus felhasználói felület, elemi grafika. Cserép Máté

3. Beadandó feladat dokumentáció

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Programozási technológia II 3. előadás. Objektumorientált tervezés Giachetta Roberto

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

2. Beadandó feladat dokumentáció

Swing GUI készítése NetBeans IDE segítségével

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

bool _freehand = false; QPoint _lastpoint; // ebben a pontban volt az utolsó rajzolásnál az egérmutató

1. beadandó feladat: egyszerű grafikus felületű alkalmazás. Közös követelmények:

Eseményvezérelt alkalmazások fejlesztése II 4. előadás. Windows Forms alkalmazások architektúrája és tesztelése

Már megismert fogalmak áttekintése

Dinamikus felületű alkalmazások. Stílusok, időzítő, képek

S01-7 Komponens alapú szoftverfejlesztés 1

Grafikus felhasználói felületek. Dr. Szendrei Rudolf Informatikai Kar Eötvös Loránd Tudományegyetem. Programozási technológia I. Dr.

Eseményvezérelt alkalmazások fejlesztése II 3. előadás. Windows Forms dinamikus felhasználói felület, elemi grafika

Operációs rendszerek. Az X Window rendszer

Grafikus felhasználói felület (GUI) létrehozása A GUI jelentése Egy egyszerű GUI mintaalkalmazás létrehozása

Webes alkalmazások fejlesztése 10. előadás. Webszolgáltatások tesztelése (ASP.NET Core) Cserép Máté

A gyakorlat során az alábbi ábrán látható négy entitáshoz kapcsolódó adatbevitelt fogjuk megoldani.

Programozási technológia

Bánsághi Anna 2014 Bánsághi Anna 1 of 31

Objektumelvű programozás

Szoftvertechnológia 10. előadás. Verifikáció és validáció. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Alkalmazott Modul III 6. gyakorlat. Objektumorientált programozás: öröklődés és polimorfizmus

Mio Technology Limited C510, C710. Gyors használati utasítás a Mio Map v3 programhoz. Magyar

Bevezetés a programozásba II. 8. Előadás: Osztályok, objektumok, osztályszintű metódusok

Tervminták a valósidejű gyakorlatban

components : IContainer dx : int dy : int tmidőzítő : Timer toolstripseparator1 : ToolStripSeparator tsmikilépés : ToolStripMenuItem

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Adatkezelés speciális eszközökkel. Giachetta Roberto

Eseménykezelés. Aszinkron kommunikáció

Vizuális és eseményvezérelt programozás , II. félév BMF NIK

Webes alkalmazások fejlesztése 12. fejezet. Szolgáltatás alapú kommunikáció (WCF) Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

Bevezetés a Programozásba II 5. előadás. Objektumorientált programozás és tervezés

Webes alkalmazások fejlesztése Bevezetés. Célkitűzés, tematika, követelmények. A.NET Core keretrendszer

Eseményvezérelt alkalmazások fejlesztése I 8. előadás. Adatbázis-kezelés modell/nézet architektúrában

Programozási technológia

ESEMÉNY VEZÉRELT ALKALMAZÁSOK FEJLESZTÉSE I. Bevezetés. Készítette: Gregorics Tibor

Java programozási nyelv

Webes alkalmazások fejlesztése Bevezetés. Célkitűzés, tematika, követelmények. A.NET Core keretrendszer

Ugráló gomb oktatási segédlet Ugráló gomb

Eseményvezérelt alkalmazások fejlesztése I 6. előadás. Összetett alkalmazások megvalósítása. Giachetta Roberto

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Szoftver-technológia II. Architektúrák dokumentálása UML-lel. Irodalom. Szoftver-technológia II.

Models are not right or wrong; they are more or less useful.

Webes alkalmazások fejlesztése 7. előadás. Autentikáció és autorizáció (ASP.NET)

3D-s számítógépes geometria és alakzatrekonstrukció

Bevezetés a Programozásba II 8. előadás. Polimorfizmus Giachetta Roberto

Grafikus keretrendszer komponensalapú webalkalmazások fejlesztéséhez

Szoftverarchitektúrák 3. előadás (második fele) Fornai Viktor

Eseményvezérelt alkalmazások fejlesztése II 10. előadás. Window Runtime alapismeretek. Windows Runtime alapismeretek A Windows Runtime

Bevezetés a programozásba II 1. gyakorlat. A grafikus könyvtár használata, alakzatok rajzolása

3. Beadandó feladat dokumentáció

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Elemi Alkalmazások Fejlesztése Beadandó Feladat Juhász Ádám

Szoftvertechnológia 8. előadás. Szoftverrendszerek tervezése. Giachetta Roberto. Eötvös Loránd Tudományegyetem Informatikai Kar

A jobboldalon a pnlright egy Stacked Widget Állítsuk be az első lapot és nevezzük el pnldraw-ra:

Szoftvertechnológia 8. előadás. Szoftverrendszerek tervezése Giachetta Roberto

Java felhasználói felület

3. Osztályok II. Programozás II

Autóipari beágyazott rendszerek. Komponens és rendszer integráció

Concurrency in Swing

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Programozási technológia I. programból! A Gomb4 megoldásból induljunk ki!

Webes alkalmazások fejlesztése 4. előadás. Megjelenítés és tartalomkezelés (ASP.NET Core) Cserép Máté

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Eseményvezérelt alkalmazások fejlesztése I 10. előadás. Adatbázis-kezelés modell/nézet architektúrában. Giachetta Roberto

Alprogramok, paraméterátadás

Java Programozás 9. Gy: Java alapok. Adatkezelő 5.rész

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Eseményvezérelt alkalmazások fejlesztése I 5. előadás Grafikus felületű alkalmazások architektúrája 2016 Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto

Architekturális tervezés Szoftver architektúrának nevezzük a szoftver fejlesztése során meghozott elsődleges tervezési döntések halmazát azon döntések, amelyek megváltoztatása később jelentős újratervezését igényelné a szoftvernek kihat a rendszer felépítésére, viselkedésére, kommunikációjára, nem funkcionális jellemzőire és megvalósítására A szoftver architektúra elsődleges feladata a rendszer magas szintű felépítésének és működésének meghatározása, a komponensek és relációk kiépítése meghatározza a szolgáltatott és elvárt interfészek halmazát, a kommunikációs csatornákat és csatlakozási pontokat ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:2

Architekturális tervezés A szoftver architektúráját különböző szempontok szerint közelíthetjük meg, pl.: a szoftver által nyújtott szolgáltatások (funkciók) szerint a felhasználó és a futtató platform közötti tevékenységi szint szerint az adatátadás, kommunikáció módja szerint Az architektúra létrehozása során mintákra hagyatkozunk, a szoftver teljes architektúráját definiáló mintákat nevezzük architekturális mintáknak (architectural pattern), az architektúra alkalmazásának módját, az egyes komponensek összekapcsolását segítik elő a tervminták (design pattern) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:3

A monolitikus architektúra Minden szoftver rendelkezik architektúrával A legegyszerűbb felépítést az monolitikus architektúra (monolithic architecture) adja nem különböztetjük meg az egyes feladatköröket (pl. megjelenítés, adatkezelés), hanem egységesen kezeljük őket alkalmazás felhasználó megjelenítés tevékenységek adatkezelés ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:4

Feladat: Készítsünk egy Tic-Tac-Toe programot, amelyben két játékos küzdhet egymás ellen. a programban lehetőséget adunk új játék kezdésére, valamint lépésre (felváltva) a programban X és 0 jelekkel ábrázoljuk a két játékost a program automatikusan jelez, ha vége a játéknak (előugró üzenetben), majd új játékot kezd lehetőséget adunk, hogy a felhasználó bármikor új játékot indítson az alkalmazás felületét gombok segítségével valósítjuk meg (9 játékgomb, valamint új játék kezdése) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:5

Tervezés (felhasználói esetek): Felhasználó Új játék Lépés Kilépés «include» ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:6

Tervezés (architektúra): az alkalmazást egy osztályban (TicTacToeWidget) valósítjuk meg, amely tartalmazza a grafikus felületet és a játék viselkedését a felületet a konstruktor és a generatetable segédművelet állítja elő, elrendezések segítségével a felületen elhelyezzük az új játék gombját (_newgamebutton), valamint a játéktábla gombjait (_gametablebuttons), továbbá egy karakterrel eltároljuk az aktuális játékos jelét (_currentplayersymbol) a játékot az eseménykezelők vezérlik ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:7

Tervezés (architektúra): TicTacToeWidget QWidget - _currentplayersymbol :QChar - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - generatetable() :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + newgamebuttonclicked() :void ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:8

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::buttonClicked() { // lekérjük az esemény küldőjét QPushButton* senderbutton = qobject_cast<qpushbutton*> (sender()); int location = _tablelayout ->indexof(senderbutton); int x = location / 3; int y = location % 3; // a gomb rácson belüli pozíciója megadja a // koordinátákat ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:9

Megvalósítás (tictactoewidget.cpp): _gametablebuttons[x][y] ->settext(_currentplayersymbol); // megjelenítés a gombon _gametablebuttons[x][y]->setenabled(false); } if (_currentplayersymbol == 'X') // váltjuk a játékost _currentplayersymbol = '0'; else _currentplayersymbol = 'X'; ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:10

A monolitikus architektúra korlátai Összetettebb alkalmazásoknál a monolitikus felépítés korlátozza a program áttekinthetőségét (nehezen azonosítható, hol tároljuk a számításhoz szükséges adatokat) tesztelését (nem ellenőrizhetjük külön-külön az egyes programfunkciókat) módosíthatóságát, bővíthetőségét (a felület kinézetét csak úgy módosíthatjuk, ha a működést is átírjuk) újrafelhasználhatóságát (a funkciók nem emelhetőek ki és vihetőek át másik alkalmazásba) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:11

A monolitikus architektúra finomítása Ezért célszerű a program felépítését felbontani a funkciók mentén: válasszuk szét a különböző tevékenységeket, emeljünk ki a tényleges tevékenységeket külön alprogramba pl.: a játékbeli lépést helyezhetjük külön alprogramba, így függetlenedik az eseménykezelőtől az adatok mentén: ne közvetlenül a felületen tárolt információkkal dolgozzuk, hanem külön adatokkal, amelyek függetlenek a megjelenítéstől pl. a játéktábla értékeit ábrázoljuk egész számokkal, ahelyett, hogy a grafikus elemek feliratát használnánk ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:12

Feladat: Módosítsuk a Tic-Tac-Toe programot úgy, hogy áttekinthetőbb és tagoltabb legyen. a játékosok reprezentálhatóak számokkal (1: X, 5: O, 0: még nincs érték) a játékban tárolt értékeket egy külön mátrixban (_gametable) tároljuk, a az aktuális játékost is számként ábrázoljuk (_currentplayer) elmentjük a lépések számát (_stepnumber), így nem kell állandóan ellenőrizni a mezőket új metódusokat veszünk fel a játék kezelésére (newgame, stepgame, isgamewon) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:13

Tervezés (architektúra): TicTacToeWidget QWidget - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - _stepnumber :int - _currentplayer :int - _gametable :int** - generatetable() :void - isgamewon() :void - newgame() :void - stepgame(int, int) :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + newgamebuttonclicked() :void ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:14

Tervezés (viselkedés): Felhasználó newgamebuttonclicked() TicTacToeWidget buttonclicked() newgame() stepgame(int, int) isgamewon() ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:15

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::buttonClicked() { QPushButton* senderbutton = qobject_cast<qpushbutton*>(sender()); int location = _tablelayout ->indexof(senderbutton); } stepgame(location / 3, location % 3); ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:16

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::stepGame(int x, int y){ _gametable[x][y] = _currentplayer; // pozíció rögzítése if (_currentplayer == 1) _gametablebuttons[x][y]->settext("x"); else _gametablebuttons[x][y]->settext("0"); _gametablebuttons[x][y]->setenabled(false); _stepnumber++; _currentplayer = _currentplayer % 2 + 1; ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:17

A modell/nézet architektúra A programszerkezet felépítése akkor ideális, ha teljesen külön programegységbe tudjuk leválasztani a felhasználói felülettel kapcsolatos részeket a ténylegesen a feladat megoldását szolgáltató funkcionalitástól Ezt a felbontást követve jutunk el a modell/nézet (MV, modelview) architektúrához, amelyben a modell tartalmazza a feladat végrehajtását szolgáló programegységeket, az állapotkezelést, valamint az adatkezelést, ezt nevezzük alkalmazáslogikának, vagy üzleti logikának a nézet tartalmazza a grafikus felhasználói felület megvalósítását, a felület elemeit és az eseménykezelőket ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:18

A modell/nézet architektúra a felhasználó a nézettel kommunikál, a modell és a nézet egymással alkalmazás felhasználó megjelenítés nézet eseménykezelés adatkezelés modell állapotkezelés ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:19

A modell/nézet architektúra A modell és a nézet kapcsolatát úgy kell megvalósítani, hogy a nézet ismerheti a modell felületét (interfészét), és hívhatja annak (publikus) műveleteit a modellnek semmilyen tudomása sem lehet a nézetről, ezért nem hívhatja annak műveleteit, de eseményeken keresztül kommunikálhat vele nézet metódushívás események modell A megvalósításban a nézet hivatkozhat a modellre (tartalmazhatja annak példányát) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:20

Feladat: Módosítsuk a Tic-Tac-Toe programot úgy, hogy kétrétegű architektúrában valósuljon meg. a játékért felelős programrészeket kiemeljük egy új osztályba, amely a modellt valósítja meg (TicTacToeModel), itt csak egész számokkal dolgozunk, függetlenül a felülettől, a játékműveletek publikusak lesznek a modellt megfelelő ellenőrzésekkel kell ellátni (mivel leválasztottuk a tevékenységeit) a nézet (TicTacToeWidget) aggregálja a modellt, és biztosítja a grafikus megjelenítést, valamint a játék műveleteinek hívását, az eredmények megjelenítését ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:21

Tervezés (architektúra): TicTacToeWidget QWidget - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - _model :TicTacToeModel - generatetable() :void - newgame() :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + newgamebuttonclicked() :void -_model TicTacToeModel - _stepnumber :int - _currentplayer :int - _gametable :int** + TicTacToeModel() + ~TicTacToeModel() + newgame() :void + stepgame(int, int) :void + stepnumber() :int + isgameover() :int + getfield(int, int) :int ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:22

Tervezés (viselkedés): TicTacToeWidget TicTacToeModel Felhasználó newgamebuttonclicked() newgame() buttonclicked() stepgame(int, int) getfield(int, int) :int isgameover() :int ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:23

Megvalósítás (tictactoemodel.cpp): void TicTacToeModel::stepGame(int x, int y) { // ellenőrzünk lépésszámot, tartományt, mezőt if (_stepnumber >= 9) return; if (x < 0 x > 2 y < 0 y > 2) return; if (_gametable[x][y]!= 0) return; } _gametable[x][y] = _currentplayer; // pozíció rögzítése _stepnumber++; _currentplayer = _currentplayer % 2 + 1; ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:24

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::buttonClicked(){ _model.stepgame(x, y); // játék léptetése if (_model.getfield(x, y) == 1) _gametablebuttons[x][y]->settext("x"); else _gametablebuttons[x][y]->settext("0"); _gametablebuttons[x][y]->setenabled(false); int won = _model.isgameover(); // játék végének ellenőrzése ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:25

Egyedi események A saját osztályainkban lehetőségünk van események és eseménykezelők létrehozására, az események kiváltására az események olyan visszatérési érték nélküli metódusok, amelyeket csak deklarálnunk kell az eseményeket egy QObject leszármazott (és Q_OBJECT makróval ellátott) osztály signals részében helyezzük el az események mindig publikusak eseményeket az <eseménynév>(<paraméterek>) utasítással válthatunk ki az osztályon belül az eseményt ugyanabban, vagy más osztályban is lekezelhetjük ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:26

Egyedi események Pl.: class SignalDemoClass : public QObject { Q_OBJECT // makróval megjelölt public: void somemethod(); signals: // saját események void demosignal(); // csak deklaráljuk }; void SignalDemoClass::someMethod() { demosignal(); // kiváltjuk az eseményt } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:27

Feladat: Módosítsuk a Tic-Tac-Toe programot úgy, hogy a modell is kommunikáljon a nézettel, események segítségével. a modellben megvalósítunk 3 eseményt amelyeket a megfelelő pontokon kiváltunk: mező megváltozása (fieldchanged) játék vége valamely játékos győzelmével (gamewon) játék vége döntetlennel (gameover) a nézetben eseménykezelőket kötünk rájuk, így egyszerűsödik a játéklépés megvalósítása, mivel a további tevékenységek (mező átírása, játék vége) az események hatására futnak le ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:28

Tervezés (architektúra): TicTacToeWidget QWidget - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - _model :TicTacToeModel - generatetable() :void - newgame() :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + model_fieldchanged(int, int, int) :void + model_gameover() :void + model_gamewon(int) :void + newgamebuttonclicked() :void -_model TicTacToeModel - _stepnumber :int - _currentplayer :int - _gametable :int** - checkgame() :void + getfield(int, int) :int + newgame() :void + stepgame(int, int) :void + stepnumber() :int + TicTacToeModel() + ~TicTacToeModel() QObject «signal» + fieldchanged(int, int, int) :void + gameover() :void + gamewon(int) :void ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:29

Tervezés (viselkedés): TicTacToeWidget TicTacToeModel Felhasználó newgamebuttonclicked() newgame() buttonclicked() stepgame(int, int) model_fieldchanged(int, int, int) fieldchanged(int, int, int) opt model_gamewon(int) gamewon(int) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:30

Megvalósítás (tictactoemodel.cpp): void TicTacToeModel::checkGame() { int won = 0; if (won > 0) // ha valaki győzött { gamewon(won); // esemény kiváltása } else if (_stepnumber == 9) // döntetlen játék { gameover(); // esemény kiváltása } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:31

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::buttonClicked() { _model.stepgame(x, y); // játék léptetése } void TicTacToeWidget::model_gameOver() { QMessageBox::information(this, trutf8("játék vége!"), trutf8("a játék döntetlen lett!")); _model.newgame(); } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:32

A modell megvalósítása Mivel modell független a nézettől, és újrahasznosítható, nem tudható előre, milyen módon, milyen körülmények között hívják meg műveleteit a hívás paramétereit, a modell állapotát ellenőrizni kell a tevékenységek végrehajtása előtt pl. lépés előtt megnézzük, hogy az végrehajtható-e A modell és a nézet közötti kommunikációban mindkét irányban törekedni kell az egyértelműségre és a lehető legkevesebb hibalehetőségre pl. korlátozott értékhalmazra használjunk felsoroló típusokat (enum) ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:33

Feladat: Módosítsuk a Tic-Tac-Toe programot úgy, hogy a modellben a játékost és a szimbólumokat enumeráció segítségével valósítjuk meg. felvesszük a játékos (Player) felsoroló típust beágyazott típusként három lehetséges értékkel (NoPlayer, PlayerX, PlayerO) a játéktábla reprezentációját, valamint a metódusok, események paramétereit is ennek megfelelően alakítjuk át (eseményeknél a teljes elérési útvonalat meg kell adnunk, azaz a külső osztályt is) a nézet az eseményparaméter függvényében switch elágazással dönt a tevékenységről ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:34

Tervezés (architektúra): -_gametable 9 «enumeration» TicTacToeModel:: Player NoPlayer PlayerX PlayerO -_currentplayer TicTacToeWidget QWidget - _tablelayout :QGridLayout* - _mainlayout :QVBoxLayout* - _newgamebutton :QPushButton* - _gametablebuttons :QVector<QVector<QPushButton*> > - _model :TicTacToeModel - generatetable() :void - newgame() :void + TicTacToeWidget(QWidget*) «slot» + buttonclicked() :void + model_fieldchanged(int, int, TicTacToeModel::Player) :void + model_gameover() :void + model_gamewon(tictactoemodel::player) :void + newgamebuttonclicked() :void -_model TicTacToeModel - _stepnumber :int - _currentplayer :Player - _gametable :Player** - checkgame() :void + getfield(int, int) :Player + newgame() :void + stepgame(int, int) :void + stepnumber() :int + TicTacToeModel() + ~TicTacToeModel() QObject «signal» + fieldchanged(int, int, Player) :void + gameover() :void + gamewon(player) :void ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:35

Megvalósítás (tictactoemodel.cpp): void TicTacToeModel::stepGame(int x, int y){ _gametable[x][y] = _currentplayer; // pozíció rögzítése fieldchanged(x, y, _currentplayer); // jelezzük egy eseménykiváltással, hogy // változott a mező _stepnumber++; _currentplayer = (Player)(_currentPlayer % 2 + 1); // egészként kezelhető az érték, de // konvertálnunk kell ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:36

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::model_fieldChanged(int x, int y, TicTacToeModel::Player player) { switch (player) { case TicTacToeModel::PlayerX: _gametablebuttons[x][y]->settext("x"); _gametablebuttons[x][y]->setenabled(false); break; } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:37

Feladat: Készítsünk új nézetet a Tic-Tac-Toe játékhoz, amelyben nem karakterekkel jelenítjük meg a játékállást, hanem alakzatokat rajzolunk. a képernyőről levesszük az összes vezérlőt, a megjelenítését rajzolás segítségével (QPainter) valósítjuk meg a játékosok ismét egér segítségével foglalhatják el a mezőket, új játékot pedig a Ctrl+N billentyűkombinációval indíthatnak ehhez felüldefiniáljuk a billentyű- és egérlenyomás eseménykezelőket (keypressevent, mousepressevent) a modellen semmit sem kell változtatnunk ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:38

Tervezés (architektúra): -_gametable 9 «enumeration» TicTacToeModel:: Player NoPlayer PlayerX PlayerO -_currentplayer TicTacToeWidget - _tablegraphics :QVector<QLineF> - _playerxgraphics :QVector<QLineF> - _playerographics :QRectF - _model :TicTacToeModel # keypressevent(qkeyevent*) :void # mousepressevent(qmouseevent*) :void # paintevent(qpaintevent*) :void + TicTacToeWidget(QWidget*) QWidget «slot» - model_fieldchanged(int, int, TicTacToeModel::Player) :void - model_gameover() :void - model_gamewon(tictactoemodel::player) :void -_model TicTacToeModel - _stepnumber :int - _currentplayer :Player - _gametable :Player** - checkgame() :void + getfield(int, int) :Player + newgame() :void + stepgame(int, int) :void + stepnumber() :int + TicTacToeModel() + ~TicTacToeModel() QObject «signal» + fieldchanged(int, int, Player) :void + gameover() :void + gamewon(player) :void ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:39

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_N && QApplication::keyboardModifiers() == Qt::ControlModifier) { // lekezeljük a Ctrl+N kombinációt _model.newgame(); update(); } } ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:40

Megvalósítás (tictactoewidget.cpp): void TicTacToeWidget::mousePressEvent(QMouseEvent *event) { // az event->pos() megadja az egérpozíciót, // ami QPoint típusú, ebből kiszámolható, // melyik mezőn vagyunk: int x = event->pos().x() * 3 / width(); int y = event->pos().y() * 3 / height(); } _model.stepgame(x, y); // játék léptetése ELTE IK, Eseményvezérelt alkalmazások fejlesztése I 5:41