Hogyan készülnek a csili-vili alkalmazások?

Az összes eddigi példában, amit ebben a programozásról szóló sorozatban láttunk, a programok (programrészletek) csak olyasmit tudtak megjeleníteni a külvilág számára látható módon, ami olvasható karakterekből áll. Kis szövegeket valamilyen nem-grafikus képernyőn (ablakban). Pedig azok az alkalmazások (vagyis felhasználók számára írt programok, angolul application-ök vagy röviden app-ek), amiket nap mint nap használunk, láthatóan nem puszta karaktersorozatokat jelenítenek meg a szemünk előtt, hanem szép színes képernyőket, ábrákkal, képekkel, klikkelhető elemekkel, amik sokszor még mozogni is tudnak. Például itt van egy grafikus ablak, amihez hasonlót egy beszédelemző program (a Praat nevű) jelenít meg. Van rajta menü, a folyamatos beszéd akusztikai jellemzőit kétféleképpen megjelenítő belső grafikus ábrázolás, amik a beszéd lejátszása közben mozognak is, és így tovább:


És ennek a programnak a grafikája mégcsak nem is túl igényes: mivel tudományos célra készült, nem sok gondot fordítottak az egyes rész-ablakok, gombok stb. szépségére, színezésére stb. Például a játékprogramok grafikája ennél nagyságrendekkel látványosabb szokott lenni.

Előrebocsátom, hogy nem fogom az olvasót odáig elvezetni, hogy ilyen csili-vili alkalmazásokat írjon. Ahhoz ugyanis túl sok előkészületre lenne szükség, olyan ismeretekre, amik nem magáról a programozásról szólnak, hanem arról, hogy mások által írt konkrét programokat hogyan használhatunk a sajátunkban. Grafikus alkalmazásokat ugyanis úgy készíthetnünk, hogy ahhoz a programozási nyelvhez, amit használunk, keresünk mások által már megírt grafikus programcsomagot, programkönyvtárat (angolul: package, library), és annak a szolgáltatásait vesszük igénybe. Szinte minden programozási nyelvhez tartozik ilyen programcsomag, általában több közül is választhatunk. Ezért csak annyi lehet itt a célom, hogy a legalapvetőbb fogalmakra és lehetőségekre felhívjam a figyelmet.

A grafikus alkalmazások természete

Amikor grafikus alkalmazást készítünk, akkor az egyik fontos újdonság az, hogy a virtuális világunkba belép egy új fajta lény, a valahányszor valahány pixelből (képpontból) álló képernyő vagy ablak (és ezen belül minden képpont egy-egy kis lény). Az ablakunkban mindenféle lényeinket vizuális formában tudjuk megjeleníteni: például megjelenhetnek az ablakban „megnyomható” gombok, ábrák, a kártyalapokat az igazi kártyákra emlékeztető kis képeken láthatjuk (amik esetleg elfordítva, félig takarásban stb. jelenhetnek meg), és így tovább. Mindezek a grafikai elemek maguk is sok-sok képpontból állnak, és meghatározott módon helyezkednek el az ablakon belül.

Végső soron minden alakzat attól jelenik meg az ablakban, hogy az egyes képpontok a megfelelő színben villannak fel, és a megfelelő pillanatban. És ezt a virtuális képernyőt vagy ablakot a rendszer majd egy valóságos képernyőn vagy ablakban fogja megjeleníteni (és változtatni), egészen hasonlóan ahhoz, ahogy mi megalkotjuk.

Persze általában szó sincs arról, hogy a programunkban mindig le kell írnunk, hogy melyik képpont mikor és hogyan villanjon fel. A grafikus alkalmazásokhoz használt programcsomagok egyik fő feladata, hogy viszonylag egyszerűen hozhassuk létre a grafikus lényeket és helyezhessük el őket az ablakokban. Az egyes grafikus lények létrehozásához a grafikus programcsomag külön-külön eszközöket tartalmaz (lehet velük gombokat, feliratokat, képeket, vonalakat stb. készíteni). És mindegyikhez megadják azokat a lehetőségeket, hogy hogyan nézzenek ki a részletek (színek, méretek, perspektíva, mozgás, elhelyezés). És aztán mindezekből az információkból majd a rendszer fogja kiszámolni, hogy melyik pixeleket hogyan kell felvillantani ahhoz, hogy megjelenítse ezeket a lényeket.

A grafikus alkalmazások másik jellegzetessége, hogy általában interaktívak, vagyis a futásuk vezérlésében döntő szerepe van a felhasználónak, aki az egér, az érintőképernyő és esetleg a billentyűzet segítségével befolyásolja az események menetét. Persze a nem-grafikus programok is megtehetik, hogy a billentyűzetről várják, hogy milyen billentyűket nyom le a felhasználó, és ettől függően folytatják a futásukat, de a grafikus alkalmazásokban ez az uralkodó mozzanat. Ezt legtöbbször a szerkezetük is tükrözi: a grafikus programok általában úgy néznek ki, hogy létrehozunk egy kezdőképet (egy kezdőablakban), és aztán átadjuk a vezérlést a felhasználónak: a program várja, hogy mit tesz a felhasználó (vagyis olyan eseményekre vár, amiket a felhasználó tevékenysége indít el), és ezeknek megfelelően lép tovább.

Például ha Python nyelven írunk grafikus alkalmazást, akkor a legkézenfekvőbb lehetőségünk a Tkinter programcsomag használata, mert ezt minden Python-rendszerrel együtt kapjuk. (Vigyázat, a Python 3. verziójától kezdve ezt csupa kisbetűvel kell írni: tkinter.) Ezért valahova a programunk elejére be kell írnunk valami ilyesmit:

import Tkinter

A fő ablakunk, ahol majd minden megjelenik, az ezen a modulon belül definiált Tk nevű osztálynak lesz egy példánya:

ablak = Tkinter.Tk()

Minden további grafikus lényt, ami az alkalmazásunkban megjelenik (és amik a Tkinter modul egyéb osztályainak példányai), közvetlenül vagy közvetve ebben az ablakban helyezhetünk el, ezeknek a lényeknek a sajátosságai fogják majd meghatározni, hogy milyen interakciók esetében mik történjenek. És a programunk futása úgy kezdődik, hogy ennek az ablaknak adjuk át a vezérlést, a következőképpen:

ablak.mainloop() Webes alkalmazások

Van a grafikus alkalmazásoknak egy másik, szintén nagyon gyakran használt fajtája, aminél a főszerepet játszó grafikus felület, az ablak, amiben az információk megjelennek, nem más, mint az internetes böngészőnk ablaka, és az alkalmazást úgy indítjuk el, hogy a böngészőnket egy bizonyos webcímre irányítjuk. Ha ilyen alkalmazást akarunk írni, akkor tehát hozzá kell férnünk egy olyan szerverhez, ami webes szolgáltatást nyújt. A hozzáférés itt azt jelenti, hogy képesnek kell lennünk a szerveren foldereket és bennük file-okat létrehozni, mert a szerver címe plusz ezeknek a foldereknek és file-oknak a neve alkotja majd a webcímet, amin keresztül az alkalmazásunk majd távolról futtatható lesz, vagyis távoli kliensek böngésző-ablakaiban látható legyen az, amit megjelenít, ha a böngészőbe ezt a címet írják be.

Amikor webes kapcsolatot teremtünk egy webcímen elérhető szerverrel, akkor a mi eszközünk (a kliens) jellemzően egy HTTP nevű protokoll (szabályrendszer) szerint létesít kapcsolatot a szerverrel. (Ezt a rövidítést jól ismerhetjük, mert ezt írjuk a címek elé, amikor ezt a protokollt akarjuk használni.) A kapcsolat során a mi eszközünk a címen kívül még néhány fajta adatot küldhet a szervernek, a szerver pedig válaszképpen ún. hypertext-adatokat küld vissza (erre utal a protokoll rövidítésének az elején a HT). Ezeknek a hypertext-adatoknak a java része tipikusan egy olyan file, amit a böngészőnk értelmezni tud, és ami vezérli, hogy mi jelenjen meg a böngésző ablakában. (Ezek a file-ok ún. HTML formátumban vannak megadva, ennek az elején is a hypertext szó rövidítése a HT.)

Ha tehát webes alkalmazást akarunk írni, akkor elsősorban a HTML formátumot kell jól ismernünk, mert ilyen formában kell előállítanunk (a programunk segítségével) mindent, amit a böngésző ablakában szeretnénk megjeleníteni. Ez a formátum is lehetővé teszi olyan elemek megjelenítését, elrendezését stb., mint amiket a grafikus programcsomagokkal produkálni tudunk.

A webes alkalmazások két fő módszeren alapulnak, és mindkét módszert használhatjuk ugyanabban az alkalmazásban, egymással keverve is. Az egyik módszer a szerver-oldali alkalmazás: maga a program a szerveren fut, és szöveges adatokat állít elő (HTML formátumban), és küld el a klienshez (a kliensen futó böngészőhöz), hogy az megjelenítse. A másik módszer a kliens-oldali alkalmazás. Ez úgy működik, hogy a szerverről érkező HTML formájú adatok tartalmaznak egy programot vagy programrészleteket (akár közvetlenül tartalmazzák őket, akár hypertext-linkekkel jelzik, hogy honnan lehet őket letölteni). Ezeket a kliensen futó böngésző letölti, és maga lefuttatja, a kliens erőforrásait felhasználva. Most röviden külön kitérek mind a két módszer legtipikusabb, leggyakoribb fajtáira.

Szerver-oldali alkalmazások

A szerver-oldali alkalmazások a szerver erőforrásait használják, erre a kliens-oldaliak képtelenek. Ezért ilyet szoktak használni akkor, ha a szerveren lakó erőforrásokra (például adatbázisokra) van szüksége a programunknak. Persze ehhez a szerver üzemeltetőjének az engedélye kell. Elvileg bármilyen programozási nyelvet használhatunk arra, hogy a szerveren fusson, csak úgy kell megírnunk, hogy HTML formátumú adatokat produkáljon. A probléma csak az, hogy a szerverek üzemeltetői biztonsági okokból erősen korlátozni szokták, hogy milyen nyelvet használhatunk. Még így is elég nagy a felelősségük, hogy a programunkban ne legyen biztonsági rés, ami támadhatóvá teszi a szerverüket.

A gyakorlatban a legtöbb üzemeltető csak a PHP nevű programozási nyelv használatát engedélyezi. A PHP ún. szkriptnyelv, ami azt jelenti, hogy a programok futtatásához nem szükséges őket előre feldolgozni (lefordítani). A szerver-oldali programok szempontjából ez azért jó, mert a legtöbb üzemeltető nem is engedélyezi, hogy interaktív módon beléphessünk a szerverére, és ott például programokat fordítgassunk. Elég a PHP-programot (szkriptet) feltölteni a szerverre a megfelelő helyre, és máris futtatható bárhonnan. (Ráadásul általában arra is van mód, hogy egy HTML formátumú file-ba beágyazzunk PHP-programrészleteket, és így a kliensnek elküldött adatok részben statikusak, állandóak, részben pedig dinamikusak, vagyis a PHP-utasítások hozzák őket létre.) Mint általában a szkriptek használatának, a PHP-programozásnak is megvan viszont az a nehézsége, hogy a hibakeresés nehéz, hiszen nincs mód arra, hogy már a program előzetes feldolgozása, lefordítása során hibákat találjunk. Márpedig aki programoz, az hibákat is követ el, ha másért nem, hát az elütések miatt.

A szerver-oldali alkalmazások esetében magát a programot nem kell nyilvánosságra hozni, ahhoz a böngészőkön keresztül nem is lehet távolról hozzáférni. Ha ugyanis valaki a HTTP protokoll segítségével kéri a szervertől valamelyik programfile tartalmát, akkor a szerver nem a programot fogja neki elküldeni, hanem azt a HTML formátumú file-t, amit a program létrehoz.

Kliens-oldali alkalmazások

A kliens-oldali alkalmazások fajtái is nagyon korlátozottak, hiszen csak olyan nyelven írhatjuk őket, amit a böngészők megértenek. A gyakorlatban ez csak két nyelvet jelent: a JavaScript nevű nyelvet, és a CSS nevűt.

A JavaScript nyelv segítségével bármit megtehetünk, amihez csak a kliens erőforrásai szükségesek. A HTML-file-ba beágyazott programunknak automatikusan a rendelkezésére állnak a szükséges információk például magáról a böngészőablakról (a window változó értéke), a HTML-file tartalma (a document változó értéke) és még sok másról, ezeket manipulálhatjuk vele, reagálhatunk a felhasználó mindenféle tevékenységéről (egér, billentyűzet stb.), és így tovább.

A CSS nyelv viszont nem nevezhető a szokásos értelemben vett programozási nyelvnek, mert nem „utasításokat” tartalmaz. Arra jó, hogy a HTML-file tartalmához fűzzünk formázási szabályokat, de ezek a szabályok olyan rugalmasak, hogy akár a felhasználó tevékenységére (pl. a kurzor helyzetére) is hivatkozhatnak, sőt animációt is előírhatnak (elemek mozgását, átalakulását stb.). Így aztán a HTML-file-ba ágyazott CSS-szabályokkal is igen sok megjelenítési hatást el lehet érni. Ráadásul a JavaScript programok is hozzá tudnak férni ezekhez a szabályokhoz (például új szabályokat tudunk velük bevezetni), illetve amikor JavaScript programokkal módosítjuk a HTML-file tartalmát, akkor a CSS-szabályoknak megadott módon változik a megjelenítés is.

A szerző nyelvész, az MTA Nyelvtudományi Intézetének főmunkatársa. További írásai a Qubiten itt olvashatók