Wt toolkit használata
Egy webalkalmazás elkészítéséhez általában ismerni kell egyebek mellett a leíró nyelveket (X/HTML, CSS, esetleg SVG, MathML), kliensoldali programozási nyelvet (JavaScript), a HTML5 böngésző szolgáltatásainak eléréséhez szükséges API-kat, az oldalak letöltésére használt protokollt (HTTP), módszereket (Ajax, Comet), valamint legalább egy kiszolgálóoldali programozási környezetet.
Ezek a technológiák gyorsan fejlődnek, változnak és velük együtt változnak webböngészők is. A webalkalmazások fejlesztéséhez számos alkalmazásfejlesztő keretrendszer van, melyek megpróbálják a technológiai részleteket különböző mértékben eltakarni.
Egy ilyen keretrendszer a Wt toolkit, ami a hagyományos grafikus rendszerek programozásánál használatos fogalmak (objektum, esemény, üzenet stb.) szintjére emeli a webalkalmazás fejlesztését. A Wt absztrakciós mechanizmusai teljesen eltakarják a webes technológiák sokszínűségét. Így nem kell külön foglalkozni munkamenet (session) kezeléssel, felhasználói azonosítással, perzisztenciával, HTML lapok szerkesztésével, az adott böngésző lehetőségeinek lekérdezésével, csupán az alkalmazás logikájának megvalósításával.
A laborgyakorlat a Wt lehetőségeiből mutat be néhány részletet egy egyszerű, teljes egészében C++ nyelven készített webalkalmazás fejlesztésén keresztül.
Az elkészítendő alkalmazással ládákat tudunk létrehozni és egymásra pakolni. Minden ládának van tömege és teherbírása. Ha a teherbírásnál nagyobb terhet teszünk egy ládára, akkor az összetörik, a törmelék pedig nyomtalanul megsemmisül. A grafikus felületen be tudjuk állítani a létrehozandó láda tömegét és teherbírását. Ha olyan tömegű ládat akarunk létrehozni, amit már a meglevő ládáink nem bírnak el, akkor a gyenge ládák pirosra színeződnek, mielőtt a létrehozás gombot megnyomnánk. Csupán a lehetőségek bemutatása végett a gyenge (piros) ládák és az erős (barna) ládák arányát egy tortadiagramon is megjelenítjük. Amikor egy láda összetörik, az hangjelzéssel jár.
Reményeink szerint a labor végére mindenki képes lesz egy ilyen webes alkalmazást létrehozni. A mintaalkalmazás a BME-ről IPv6 fölött is elérhető.
A feladatokat az IIT és az IK közös cloud rendszerében futtatott virtuális gépen tudja végrehajtani, de ha akar, dolgozhat a saját környezetében is. Az ehhez szükséges szoftverek a Wt toolkit, a cmake, a make, valamint a doxygen.
Feladatok
- Nyissa meg a cloud.bme.hu oldalt! Itt válassza KIFU-NIIF, vagy a VIK nevű adatközpontot, majd lépjen be a rendszerbe EduID-azonosítójával (az eduID ikonra kattintson)! Indítson el egy virtuális gépet a "C++ labor" sablonnal, és lépjen be a gépre! Az indítás részleteit itt találja (1–6. feladatok).
- Töltse le az előkészített laboranyagot a virtuális gép login katalógusába:
cd git clone https://git.ik.bme.hu/Prog2/labor_peldak/lab_wt.git
A parancs hatására a login (home) katalógusban keletkezik egy lab_Wt alkatalógus, melybe bemásolódnak az előkészített fájlok:
CMakeLists.txt a cmake (makefájlt generáló program) vezérlő fájl Doxyfile Doxygen programot vezérlő fájl img img alkatalógus az alkalmazáshoz tartozó képekkel ladaapp a webalkalmazásunkat indító script ladaapp.xml szövegkonstansok a webalkalmazás nyelvi testreszabásához ladaapp.cpp a webalkalmazás C++ forrásprogramja ladak.h, ladak.cpp a webalkalmazás Lada és LadaOszlop osztálya ladawidget.h, ladawidget.cpp a webalkalmazás LadaWidget osztálya tortadiagram.h, tortadiagram.cpp a webalkalmazás Tortadiagram osztálya - Generálja a fordításához szükséges make fájlokat, majd fordítsa le az alkalmazást:
cd lab_wt cmake . # a pontot ne felejtse le! make
- Ha mindent jól csinált, akkor hiba nélkül lefordult az alkalmazás:
Scanning dependencies of target ladaapp.wt [ 33%] Building CXX object CMakeFiles/ladaapp.wt.dir/ladaapp.cpp.o [ 66%] Building CXX object CMakeFiles/ladaapp.wt.dir/ladawidget.cpp.o [100%] Building CXX object CMakeFiles/ladaapp.wt.dir/ladak.cpp.o Linking CXX executable ladaapp.wt [100%] Built target ladaapp.wt
Az alkalmazás felhasználói felülete 3 grafikus elemet tartalmaz:
- Tömeg (beviteli mező)
- Új láda hozzáadása (nyomógomb)
- Ládaoszlop (sematikus kép)
Ha a tömegbeviteli mezőbe olyan értéket akarunk bevinni, amilyen tömegű ládát az oszlop tetejére rakva egy vagy több láda megsemmisülne, akkor azok a ládák pirossal jelennek meg. Ha ennek ellenére megnyomjuk a hozzáad gombot, akkor a művelet végrehajtódik.
- Indítsa el az alkalmazást: ./ladaapp
A webalkalmazás ekkor a virtuális gép 8080-as portján webszerverként fogadja a kéréseket. Ahhoz, hogy a virtuális gép 8080-as portját a külső hálózat felől is elérjük, vagy SSH tunnelt kell építeni, vagy ki kell nyitni a megfelelő portot a tűzfalon (lásd labor a felhőben). Mivel ez utóbbi egyszerűbb, ezt javasoljuk:- A virtuális gép vezérlőpaneljén (válassza ki az adott virtuális gépet) kattintson a Hálózat fülre!
- Hozzon létre új tűzfalszabályt a 8080-as TCP-porthoz!
Most már a külső hálózatból is elérhető az alkalmazás pl. a Hálózat fülön megjelenő új linkre kattintva. (IPv6 protokollal a http://gépnév:8080/, egyébként http://vm.niif.cloud.bme.hu:(kapott-portszám)/, míg tunnel esetén http://localhost:(helyi-port)/ címen.)
Az IPv6 az internet protokoll „új” (1998 decemberi) változata, amelynek fő előnye a nagy címtartomány. IPv4-en nem tudunk minden hallgatónak saját publikus IP címet adni (egy átlagos tanszék egyébként pazarlónak tűnően nagy tartománya is csak 255 címből áll), azonban IPv6-on ez nem okoz gondot. Ezért IPv6-on a gépek saját néven, saját címmel érhetőek el, míg IPv4 esetén a port forwarding módszert vagyunk kénytelenek használni. Ebben az esetben egyetlen publikus IPv4 cím különböző portjaira érkező kapcsolatok különböző gépekre továbbítódnak. Az IPv6 szolgáltatás a magyarországi lakossági szolgáltatóknál alig fordul elő, de az egyetem központi infrastruktúrája (Wifi, HSZK) évek óta támogatja, ezért a HSZK-ban IPv6 fölött is kipróbálhatja az alkalmazását. Ehhez a virtuális gép vezérlőpaneljéről olvassa le a gép IPv6 címét és írja be a böngésző URL sávjába a 8080-as porttal kiegészítve (cloud-????.vm.niif.cloud.bme.hu:8080)! - Generálja le a dokumentációt a make doc paranccsal, hogy könnyebben át tudja tekinteni a program működését!
Amikor fut a ladaapp webalkalmazás, akkor elérhetővé válik a generált dokumentáció is az alkalmazásba beépített webszerveren keresztül.
IPv6 esetén: http://gépnév:8080/doc/html/index.html
IPv4 esetén: http://vm.niif.cloud.bme.hu:(8080-as tűzfalszabálynál kapott port)/doc/html/index.html.Érdemes a működő programból másolatot készíteni (mkdir mentes; cp ladaapp ladaapp.wt mentes; ln -s ../doc mentes/
), hogy a dokumentáció akkor is böngészhető legyen, amikor éppen nem fordul, vagy nem futtatható a módosított program. Ilyenkor a dokumentáció nézegetéséhez az elmentett változat amentes/ladaapp
paranccsal indítható el.
Ha a dokumentációt inkább egy Apache webszerverrel szeretné elérhetővé tenni, akkor telepítsen egy Apache szervert (lásd labor a felhőben)! Majd linkelje be a dokumentum katalógusára ~/public_html katalógust(rm ~/public_html; ln -s ~/lab_Wt/doc/html ~/public_html
). Ne felejtse el a az Apache szerver számára a 80-as portot kinyitni! - Elsőként ladaapp.cpp fájlt elemezze, melyhez segítséget nyújt a 12. heti előadás is! Ebben fájlban található a LadaApplication osztály deklarációja és definíciója, az osztályt példányosító
createApplication
függvény, valamint amain()
. A LadaApplication osztály konstruktora létrehozza a felhasználói felületen megjelenő elemeket és összeköti az eseménykezelő függvényeket a felület eseményeivel.
Néhány fontosabb elméleti részlet:- Már a tervezésénél fontos odafigyelni az alkalmazások nyelvi lokalizációjára. Ezt különféle módon támogatják a fejlesztőeszközök. A Wt toolkit ezt a Wt::WMessageResourceBundle osztályal támogatja, amely képes a stringek rugalmas cseréjére egy külső fájl alapján. Ennek betöltését végzi a
messageResourceBundle().use("ladaapp")
utasítás. -
A legtöbb grafikus rendszer működése objektumorientált elveken alapszik. Ezekben gyakran használt fogalom a widget (window gadget – ablakherkentyű) ami valamilyen felhasználói felületen megjelenő objektum (pl. nyomógomb, csúszka, táblázat, ablak, lista), önálló működéssel és adatokkal.
ALadaApplication
osztály konstruktora először létrehoz egy táblázatot, amelyben elhelyezzük az alkalmazás
többi widgetjét. - A táblázat első oszlopának első cellájába a kezelő panelek kerülnek. A második oszlop első cellájába pedig a ládaoszlop megjelenítését és kezelését végző
LadaWidget
. - Ahogyan korábban már említettük, a widgetek objektumok, melyek eseményeket kapnak más objektumoktól, illetve a felhasználótól, és azokra valahogyan reagálnak. A gombok, beviteli mezők a felhasználói eseményekre reagálva eseményeket küldhetnek egy másik objektumnak. Ennek megvalósítására előadáson a callback függvényeket láttunk. A Wt signal-slot mechanizmust használ az események és az azokat lekezelő függvények összerendelésére. (lásd
button->clicked().connect(this, &LadaApplication::hozzaad);
).
Ötlet: Elemezze a tömeg beviteli mezőjének kialakítását! Az új beviteli mezőhöz nem kell új eseménykezelő, mivel a bevitt adatot elegendő a nyomógomb megnyomásakor kiolvasni. - Már a tervezésénél fontos odafigyelni az alkalmazások nyelvi lokalizációjára. Ezt különféle módon támogatják a fejlesztőeszközök. A Wt toolkit ezt a Wt::WMessageResourceBundle osztályal támogatja, amely képes a stringek rugalmas cseréjére egy külső fájl alapján. Ennek betöltését végzi a
-
Bővítse a felhasználói felületet egy új beviteli mezővel, melyben megadható a hozzáadott láda maximális terhelhetősége (alapértelmezésben 10). Például így:
- Az új mező feliratához vegyen fel megfelelő mezőt a ladaapp.xml fájlban!
- Bővítse az alkalmazást nyelvválasztási lehetőséggel! Ez célszerűen egy Wt::WComboBox hozzáadását és a hozzátartozó eseménykezelő megírását jelenti a
LadaApplication
osztályban.
Ne felejtse el használni aWt/WComboBox
fejlécállományt és létrehozni aWComboBox* combo
privát adatot aLadaApplication
osztályban! Amennyiben sikerült a bővítés, hozza létre az új nyelvhez a megfelelő xml állományt (pl: ladaapp_en.xml)! AWt::WMessageResourceBundle
objektum asetLocale
függvény paramétereként megadott stringet próbálja aláhúzással a korábban megadott fájlnévhez illeszteni és azt használja a stringek cseréjéhez. Ha nincs ilyen, akkor az eredetileg megadottat használja. - A
LadaWidget
osztály külön kigyűjti, hogy hány „gyenge” és hány „erős” láda van a ládaoszlopban. Jelezzük ki ezeket egy tortadiagramon!
A Wt támogatja az MVC (Model–View–Controller) tervezési mintát. A tortadiagram megjelenítéséhez ezt fogjuk kihasználni. A laborhoz előkészített állományok között szerepel egy tortadiagram.h és egy tortadiagram.cpp állomány, melyeknek eddig nem volt szerepük. AWt::Chart::WPieChart
osztályból származó Tortadiagram osztály egy olyan megjelenítő (view) osztály, ami aWt::WStandardItemModel
modell osztály adatait tudja megjeleníteni. A modellben az adatok összetartozó név-érték párok, melyet a Wt-ben megvalósított megjelenítők táblázatosan, oszlop, illetve tortadiagram formájában képesek megjeleníteni.
Így a feladat megoldásához rá kell vennünk aLadaWidget
osztályt, hogy viselkedjenWt::WStandardItemModel
-ként.- Származtassa a
LadaWidget
osztályt aWt::WStandardItemModel
-ből is. Ezzel olyan modellé válik, amit a Tortadiagram meg tud jeleníteni. (Ne felejtse el használni a Wt/WStandardItemModel fejlécállományt aladawidget.h
állományban!) - Egészítse ki a
LadaWidget
osztályt konstruktorát úgy, hogy felépüljön a modell a megjelenítendő adatokkal! - A ládaoszlop kirajzolásakor frissítse a fenti adatokat is! Ezt például a
void LadaWidget::rajzol
függvény végére betett két utasítással teheti meg:WStandardItemModel::setData(0, 1, eros); WStandardItemModel::setData(1, 1, gyenge);
- Módosítsa a
ladaapp.cpp
állományt úgy, hogy hozzon létre egy Tortadiagram-ot az alkalmazás fő ablakán levő táblázat 3. oszlopában! (new Tortadiagram(ladak, layout->elementAt(0,2))
) - Bővítse az xml állományokat az új szövegekkel! Fordítson (make), és próbálja ki az alkalmazást!
- Származtassa a
Jó munkát!
Szeberényi Imre