Basic Programming/hu
Magyar
Bevezetés a Qt programozás alapjaiba
Üdvözöllek a Qt keresztplatformos fejlesztői rendszer világában. Ebben a leírásban egy egyszerű jegyzettömb alkalmazás elkészítése során bemutatjuk a Qt programozás alapfogásait. Az útmutató tanulmányozása során nyugodtan nézz bele az API dokumentációba, amennyiben valamivel kapcsolatban több információra van szükséged.
Az útmutató angol nyelvű változata elérhető az http://doc.qt.nokia.com/gettingstartedqt.html [doc.qt.nokia.com] oldalon.
Hello Jegyzettömb
Példánkban egy egyszerű szövegdobozt hozunk létre egy ablakkeretben. Ez lesz a legegyszerűbb felhasználói felülettel rendelkező Qt segítségével írt program.
Íme a kód:
Vizsgáljuk meg a kódot sorról sorra. Az első két sorban a QApplication [doc.qt.nokia.com] és a QTextEdit [doc.qt.nokia.com] osztály használatához szükséges headerfájlokat includoljuk be a programunkba. A Qt összes osztályának megvan a nevével megegyező headerje.
A 6. sorban létrehozunk egy QApplication [doc.qt.nokia.com] objektumot. Ez az objektum kezeli az alkalmazás összes erőforrását. Egy ilyen objektum létrehozása szükséges minden grafikus Qt alkalmazáshoz. Argumentumként át kell adni az argv és args paramétereket, mivel a Qt-ban írt alkalmazásoknak van néhány beépített parancssori argumentuma [doc.trolltech.com].
A 8. sorban létrehozunk egy QTextEdit [doc.qt.nokia.com] objektumot. Ez a szövegdoboz egy megjeleníthető grafikus elem. A Qt-ban az ilyeneket widgeteknek hívjuk. További widgetek például: gördítősávok, címkék, rádiógombok. Minden widget lehet egyfajta konténer további widgetek számára, mint például egy ablak, vagy egy dialógus.
A 9. sorban megjelenítjük a szövegdobozt a saját ablakkeretében. Mint már említettem, a widgetek konténerként is funkcionálnak mint például a QMainWindow [doc.qt.nokia.com], amelynek van menüsora, státuszsora, és még néhány egyéb beépített widgete. Továbbá lehetőség van egyetlen widget megjelenítésére is főablakba helyezés nélkül, ez esetben maga a widget kap egy ablakkeretet. A widgetek alapból nem láthatóak, a show() metódus meghívása teszi őket azzá.
A 11. sorban meghívjuk a QApplication [doc.qt.nokia.com] eseménykezelő rutinját. Ha egy Qt alkalmazás futása közben esemény történik, akkor az kiküldődik a megfelelő widgethez. Például az egérkattintás és a billentyűleütések esetében a szövegdobozunk fogja megkapni ezeket az eseményeket. Az ilyen és ehhez hasonló feladatokat intézi ez a metódus.
Az alakalmazás fordításához és futtatásához nyiss meg egy parancssort, lépj be abba a mappában, ahol a .cpp fájlod található, és futtasd le a következő parancsokat:
Ezen műveletek után egy futtatható binárisnak kell megjelennie a part1 mappában. (Megjegyzés a Windowst és VisualStudiot használóknak: a make nmaket kell futtatniuk, továbbá a bináris a part1/debug vagy part1/release mappában fog létrejönni.)
A qmake a Qt build eszköze ami argumentum nélkül egy projekt fájlt keres, amit fel tud dolgozni. A -project argumentummal létrehoz automatikusan egy .pro fájlt a mappában található fájlokat hozzáadva. A qmaket futtatva létrejön a Makefile, amit a make programod fog feldolgozni. A .pro fájlok írásáról később még lesz szó. Amennyiben Windows alatt valamit hiányolna a fordítás során, akkor keresd ki a start menüből a Qt Command prompt-ot, és abból futtasd a parancsokat.
További olvasnivalók: {| class="infotable line" ! Miről ! Hol |- | Widgetek és ablakok geometriája | Window and Dialog Widgets [doc.qt.nokia.com] |- | Események és a Qt eseménykezelője | The Event System [doc.qt.nokia.com] |}
Kilépés gomb hozzáadása
Egy igazi alkalmazásban általában egynél több widgetre van szükséged. Helyezzünk egy QPushButtont [doc.qt.nokia.com] a szövegdoboz alá. Ez arra fog szolgálni, hogy ha a felhasználó rákattint, a program lépjen ki.
Nézzük a kódot:
Az első sorban beincludoljuk a QtGui [doc.qt.nokia.com] headert, ami magában foglalja a Qt összes grafikus osztályát.
A tizedik sorban a Qt szignál slot mechanizmusa segítségével lekezeljük a Kilépés gomb megnyomását.
A szlot függvény a futás során hívódik meg a neve segítségével. A szignálok olyan függvények, amelyek a megfelelő esemény bekövetkezésekor automatikusan meghívják a hozzájuk csatlakoztatott slotokat. Esetünkben a quit() [doc.qt.nokia.com] a widgetünk egy beépített slotja, amelyet meghívva az alkalmazás kilép. A gombunk clicked() [doc.qt.nokia.com] szignálja pedig a gomb megnyomásakor emittálódik. A szignál-slot hozzárendelést a statikus QObject::connect() [doc.qt.nokia.com]# függvénnyel hozhatjuk létre. Az argumentumként használt SIGNAL és SLOT makrókban kell megadnunk a megfelelő függvényneveket, azok argumentumainak típusával egyetemben. A connect() függvénynek át kell adni a küldő és fogadó objektumokra mutató mutatókat is.
A 12. sorban egy QVBoxLayout-ot [doc.qt.nokia.com] hozunk létre. Ahogy már említettük a widgetek (szülő widget) tartalmazhatnak további widgeteket (gyermek widgetek). Lehetőségünk van a gyermek widgeteknek pontos méretet, pozíciót megadni, de egyszerűbb, ha ehelyett layoutokat használunk, így a azok fogják kezelni a gyermekwidgetek elrendezését. A QVBoxLayout [doc.qt.nokia.com] például a gyermekeket egy függőleges oszlopba rendezi.
A 13. és 14. sorban hozzáadjuk a szövegdobozunkat és a nyomógombunkat a layouthoz, majd a 17. sorban érvénybe léptetjük az elrendezést.
További olvasnivalók: {| class="infotable line" ! Miről ! Hol |- | Szignálok és Szlotok | Signals & Slots [doc.qt.nokia.com] |- | Layoutok | Layout Management [doc.qt.nokia.com], Widgets and Layouts [doc.qt.nokia.com], Layout Examples [doc.qt.nokia.com] |- | A QT beépített widgetkészlete | Qt Widget Gallery [doc.qt.nokia.com], Widget Examples [doc.qt.nokia.com] |}
Származtatás a QWidget osztályból
Miután a felhasználó a kilépés gombra kattint, sok esetben érdemes egy megerősítést kérő ablakot megjeleníteni, hogy valóban ki akar-e lépni. Példánkban a QWidget [doc.qt.nokia.com] osztályból származtatjuk a programfelület legfelsőbbb osztályát, és létrehozunk egy slotot, amihez hozzákötjük a Kilépés gomb kattintás szignálját.
Íme a kód:
A Q_OBJECT makrónak kell az osztálydeklaráció elején lennie. Ez a makró az osztályunkat QObjectként [doc.qt.nokia.com] deklarálja (természetesen a használatához a QObjecttől [doc.qt.nokia.com] kell származtatnunk). Ez a példánkban is így van, hiszen a QWidget osztály a QObjectből van származtatva. A QObject [doc.qt.nokia.com] különféle funkciókkal bővíti ki a C++ osztályok tulajdonságait. Például az osztály és szlotok neve lekérdezhetővé válik futásidőben. Továbbá lehetőség van a szlotok argumentumainak típusát lekérdezni, illetve név alapján meghívni azokat.
A 9. sorban deklaráljuk a quit() szlotot a slots makró segítségével. A slotunkat ezután hozzáköthetjük bármilyen szignálhoz, amelynek nincs argumentuma.
A következőekben létrehozunk egy Notepad osztályt, amelynek a konstruktorában hozzuk létre a felületet, és kötjük össze a slotokat a szignálokkal. Ez megoldás elegánsabb, mint ha ezt a main() függvényben tennénk meg.
Amint láthatod mutatókat használunka textEdit és a quitButton elérésére. Az ilyen grafikus elemeket mindig a heapen példányosítjuk, és sohasem másoljuk őket.
Az ablak címét a setWindowTitle metódus segítségével állítjuk be. Amint láthatod a felhasználó számára látható szöveget a tr() [doc.qt.nokia.com] függvényen keresztül adjuk át a függvénynek. Ez a függvény a többnyelvű alkalmazások írásánál nyújt segítséget. Most nem megyünk bele a részletekbe, további információt a Qt Linguist [doc.qt.nokia.com] dokumentációjánál találsz.
További olvasnivalók: {| class="infotable line" ! Miről ! Hol |- | tr() és a többnyelvűsítés | Qt Linguist Manual [doc.qt.nokia.com], Writing Source Code for Translation [doc.qt.nokia.com], Hello tr() [doc.qt.nokia.com] Example, Internationalization with Qt [doc.qt.nokia.com] |- | QObject [doc.qt.nokia.com] és a Qt objektummodell-rendszere | Object Model [doc.qt.nokia.com] |- | qmake a Qt build rendszere | qmake Manual [doc.qt.nokia.com] |}
Az elkövetkezőkben írunk egy saját .pro fájlt, ahelyett, hogy a qmake-el generáltatnánk le.
A következő parancsokkal tudod lefordítani a példát:
A QMainWindow használata
Sok alkalmazás írásakor kézenfekvő lehet a használata, ugyanis ez az osztály egy előre megadott layout-ot tartalmaz, amelyre elhelyezhetjük saját menü sorunkat, eszköztárainkat, a dokkolható widgetek számára rögzítési területet, illetve az állapotsort is.
A QMainWindownak [doc.qt.nokia.com] van egy középső területe, ahol elhelyezhetünk bármilyen widgetet. Esetünkben is ide fog kerülni a szövegdobozunk.
Tekintsük át a Notepad osztály definícióját!
Az elkövetkezendőkben implementálni fogunk két slotot, mely a dokumentum megnyitására és mentésére fog szolgálni.
A fő ablakokban gyakran megesik az, hogy egy szlotot több widget is meghív. Esetünkben a menü egyes elemei és az eszköztár gombjai is ezt teszik. Az ilyen esetek leegyszerűsítésére hozták létre a QAction [doc.qt.nokia.com] osztályt, amelyet átadhatunk több widgetnek is, majd hozzákötjük a megfelelő szlothoz a szignálját. Például a QMenu [doc.qt.nokia.com] és a QToolBar [doc.qt.nokia.com] is létrehozhat menüket, eszköztárelemeket ugyanannak a QAction [doc.qt.nokia.com] -nek a hatására.
Ahogyan már említettük a grafikus elemeket a Notepad osztály konstruktorában inicializáljuk.
A QAction-ök [doc.qt.nokia.com] konstruktorának egy szöveget adunk meg argumentumként. Ez a szöveg fog megjelenni azokon a widgeteken, amelyekhez hozzárendeljük őket (esetünkben a menüelemeken). Ha ugyanazt a funkciót el szeretnénk érni az eszköztárunkról is, akkor az akcióhoz ikont is kell rendelnünk. Tehát ha egy menüre rákattintunk az triggerelni fogja az akciónkat, amely ezáltal a emittálja a triggered() szignálját, amely meghívja a hozzákötött szlotokat.
További olvasnivalók: {| class="infotable line" ! Miről ! Hol |- | Főablak és egyéb ablakok | Application Main Window [doc.qt.nokia.com], Main Window Examples [doc.qt.nokia.com] |- | MDI alkalmazások | QMdiArea [doc.qt.nokia.com], MDI Example [doc.qt.nokia.com] |}
A következő kódrészletben implementálni fogjuk a mentés és megnyitás kezelésére szolgáló szlotokat.
Kezdjük az open() szlottal:
Első lépésként bekérjük a felhasználótól a fájl nevét. A Qt-ban direkt erre a feladatra van egy osztály a QFileDialog [doc.qt.nokia.com] , amely egy dialógus megjelenítésére szolgál, amelyből a felhasználó kitallózhatja a kívánt fájlt.
A képen ezt a dialógust láthatjuk, ahogyan az KUbuntun megjelenik.
A getOpenFileName() [doc.qt.nokia.com]) statikus metódus egy dialógust jelenít meg (az alkalmazás többi ablaka nem használható ameddig jelen van), és addig nem tér vissza amíg a felhasználó ki nem választott egy fájlt. A visszatérési értékben megkapjuk a fájl elérési útját, vagy egy üres sztringet, ha a felhasználó a mégsem gombra kattintott.
Ha megvan az érvényes fájlnév, akkor megnyitjuk a fájlt a QFile open() [doc.qt.nokia.com] metódusával, amely igazzal tér vissza, ha a megnyitás sikerült. Most nem megyünk bele a hibakezelésbe, de ha érdekel, utána nézhetsz ezeknek a További információ szekcióban. Ha a fájl nem nyitható meg, akkor egy QMessageBox [doc.qt.nokia.com] jelenítjük meg a hibaüzenetet. A részletekért lásd a QMessageBox [doc.qt.nokia.com] osztály súgóját.
Az adatok beolvasása triviális a QFile [doc.qt.nokia.com] readAll() [doc.qt.nokia.com] metódusának köszönhetően. Ez a függvény egy a fájlban lévő adatokat tartlmazó QByteArray [doc.qt.nokia.com] -jel tér vissza. A QByteArray constData() [doc.qt.nokia.com] metódusa segítségével az adatokat const char* formában is elérhetjük, amit már át tudunk adni a QString [doc.qt.nokia.com] konstruktorának. Így a fájl tartalma megjeleníthető a szövegdobozban. Végül a close() [doc.qt.nokia.com] metódussal bezárjuk a fájlt, így adva vissza a fájlleírót az operációs rendszernek.
Most, hogy letudtuk a megnyitás szlotot lássuk a mentést:
Miután megszerkesztettük a szövegdobozunk tartalmát, azt a QTextStream [doc.qt.nokia.com] objektumon keresztül írjuk vissza a fájlunkba. Ez az osztály mintegy ráépül a QFile [doc.qt.nokia.com] objektumunkra, lehetővé téve, hogy a neki küldött szövegeket direktben kiírassuk a fájlunkba.