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

  1. 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).
  2. 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
  3. 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
    
  4. 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.

  5. 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)!
  6. 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 a mentes/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!
  7. 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 a main(). 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.
      A LadaApplication 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.
    • Ö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.
    • 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);).
  8. A szövegszerkesztéshez itt talál útmutatót.
  9. 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:
  10. Az új mező feliratához vegyen fel megfelelő mezőt a ladaapp.xml fájlban!
  11. 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 a Wt/WComboBox fejlécállományt és létrehozni a WComboBox* combo privát adatot a LadaApplication 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)! A Wt::WMessageResourceBundle objektum a setLocale 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.
  12. 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. A Wt::Chart::WPieChart osztályból származó Tortadiagram osztály egy olyan megjelenítő (view) osztály, ami a Wt::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 a LadaWidget osztályt, hogy viselkedjen Wt::WStandardItemModel-ként.
    • Származtassa a LadaWidget osztályt a Wt::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 a ladawidget.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!

Jó munkát!

Szeberényi Imre

Utolsó frissítés: 2020-04-28 07.17