Basic Programming/hu: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Add "cleanup" tag)
(Convert ExpressionEngine links)
Line 8: Line 8:
Ü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.
Ü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":http://doc.qt.nokia.com/gettingstartedqt.html oldalon.
Az útmutató angol nyelvű változata elérhető az [http://doc.qt.nokia.com/gettingstartedqt.html http://doc.qt.nokia.com/gettingstartedqt.html] oldalon.


== Hello Jegyzettömb ==
== Hello Jegyzettömb ==
Line 30: Line 30:
}</code>
}</code>


Vizsgáljuk meg a kódot sorról sorra. Az első két sorban a "QApplication":http://doc.qt.nokia.com/qapplication.html és a "QTextEdit":http://doc.qt.nokia.com/qtextedit.html 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.
Vizsgáljuk meg a kódot sorról sorra. Az első két sorban a [http://doc.qt.nokia.com/qapplication.html QApplication] és a [http://doc.qt.nokia.com/qtextedit.html QTextEdit] 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":http://doc.qt.nokia.com/4.7/qapplication.html 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":http://doc.trolltech.com/4.7/qapplication.html#QApplication.
A 6. sorban létrehozunk egy [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] 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 [http://doc.trolltech.com/4.7/qapplication.html#QApplication van néhány beépített parancssori argumentuma].


A 8. sorban létrehozunk egy "QTextEdit":http://doc.qt.nokia.com/qtextedit.html 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 8. sorban létrehozunk egy [http://doc.qt.nokia.com/qtextedit.html QTextEdit] 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":http://doc.qt.nokia.com/4.7/qmainwindow.html, 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 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 [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow], 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":http://doc.qt.nokia.com/4.7/qapplication.html 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.
A 11. sorban meghívjuk a [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] 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:
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:
Line 53: Line 53:
h3. További olvasnivalók:
h3. További olvasnivalók:
|''. Miről |''. Hol |
|''. Miről |''. Hol |
| Widgetek és ablakok geometriája | "Window and Dialog Widgets":http://doc.qt.nokia.com/4.7/application-windows.html |
| Widgetek és ablakok geometriája | [http://doc.qt.nokia.com/4.7/application-windows.html Window and Dialog Widgets] |
| Események és a Qt eseménykezelője | "The Event System":http://doc.qt.nokia.com/4.7/eventsandfilters.html |
| Események és a Qt eseménykezelője | [http://doc.qt.nokia.com/4.7/eventsandfilters.html The Event System] |


h2. Kilépés gomb hozzáadása
h2. 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":http://doc.qt.nokia.com/4.7/qpushbutton.html a szövegdoboz alá. Ez arra fog szolgálni, hogy ha a felhasználó rákattint, a program lépjen ki.  
Egy igazi alkalmazásban általában egynél több widgetre van szükséged. Helyezzünk egy [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButtont] a szövegdoboz alá. Ez arra fog szolgálni, hogy ha a felhasználó rákattint, a program lépjen ki.  


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|Eingabefeld mit Beenden Knopf]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|Eingabefeld mit Beenden Knopf]]
Line 89: Line 89:
</code>
</code>


Az első sorban beincludoljuk a "QtGui":http://doc.qt.nokia.com/4.7/qtgui.html headert, ami magában foglalja a Qt összes grafikus osztályát.
Az első sorban beincludoljuk a [http://doc.qt.nokia.com/4.7/qtgui.html QtGui] 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 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()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit a widgetünk egy beépített slotja, amelyet meghívva az alkalmazás kilép. A gombunk "clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked szignálja pedig a gomb megnyomásakor emittálódik. A szignál-slot hozzárendelést a statikus "QObject::connect()":http://doc.qt.nokia.com/4.7/qobject.html# 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 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 [http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit quit()] a widgetünk egy beépített slotja, amelyet meghívva az alkalmazás kilép. A gombunk [http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked clicked()] szignálja pedig a gomb megnyomásakor emittálódik. A szignál-slot hozzárendelést a statikus [http://doc.qt.nokia.com/4.7/qobject.html# QObject::connect()] 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":http://doc.qt.nokia.com/4.7/qvboxlayout.html 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":http://doc.qt.nokia.com/4.7/qvboxlayout.html például a gyermekeket egy függőleges oszlopba rendezi.  
A 12. sorban egy [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout-ot] 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 [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] 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.
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.
Line 101: Line 101:
h3. További olvasnivalók:
h3. További olvasnivalók:
|''. Miről |''. Hol |
|''. Miről |''. Hol |
| Szignálok és Szlotok | "Signals &amp; Slots":http://doc.qt.nokia.com/4.7/signalsandslots.html |
| Szignálok és Szlotok | [http://doc.qt.nokia.com/4.7/signalsandslots.html Signals &amp; Slots] |
| Layoutok | "Layout Management":http://doc.qt.nokia.com/4.7/layout.html, "Widgets and Layouts":http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, "Layout Examples":http://doc.qt.nokia.com/4.7/examples-layouts.html |
| Layoutok | [http://doc.qt.nokia.com/4.7/layout.html Layout Management], [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html Widgets and Layouts], [http://doc.qt.nokia.com/4.7/examples-layouts.html Layout Examples] |
| A QT beépített widgetkészlete | "Qt Widget Gallery":http://doc.qt.nokia.com/4.7/gallery.html, "Widget Examples":http://doc.qt.nokia.com/4.7/examples-widgets.html |
| A QT beépített widgetkészlete | [http://doc.qt.nokia.com/4.7/gallery.html Qt Widget Gallery], [http://doc.qt.nokia.com/4.7/examples-widgets.html Widget Examples] |


h2. Származtatás a QWidget osztályból
h2. 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":http://doc.qt.nokia.com/4.7/qwidget.html 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.
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 [http://doc.qt.nokia.com/4.7/qwidget.html QWidget] 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:
Íme a kód:
Line 128: Line 128:
</code>
</code>


A Q_OBJECT makrónak kell az osztálydeklaráció elején lennie. Ez a makró az osztályunkat "QObjectként":http://doc.qt.nokia.com/4.7/qobject.html deklarálja (természetesen a használatához a "QObjecttől":http://doc.qt.nokia.com/4.7/qobject.html kell származtatnunk). Ez a példánkban is így van, hiszen a QWidget osztály a QObjectből van származtatva. A "QObject":http://doc.qt.nokia.com/4.7/qobject.html 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 Q_OBJECT makrónak kell az osztálydeklaráció elején lennie. Ez a makró az osztályunkat [http://doc.qt.nokia.com/4.7/qobject.html QObjectként] deklarálja (természetesen a használatához a [http://doc.qt.nokia.com/4.7/qobject.html QObjecttől] kell származtatnunk). Ez a példánkban is így van, hiszen a QWidget osztály a QObjectből van származtatva. A [http://doc.qt.nokia.com/4.7/qobject.html QObject] 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 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.  
Line 154: Line 154:
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.
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()":http://doc.qt.nokia.com/4.7/qobject.html#tr 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":http://doc.qt.nokia.com/4.7/linguist-manual.html dokumentációjánál találsz.
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 [http://doc.qt.nokia.com/4.7/qobject.html#tr tr()] 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 [http://doc.qt.nokia.com/4.7/linguist-manual.html Qt Linguist] dokumentációjánál találsz.


=== További olvasnivalók:
=== További olvasnivalók:
|''. Miről |''. Hol |
|''. Miről |''. Hol |
| tr() és a többnyelvűsítés | "Qt Linguist Manual":http://doc.qt.nokia.com/4.7/linguist-manual.html, "Writing Source Code for Translation":http://doc.qt.nokia.com/4.7/i18n-source-translation.html, "Hello tr()":http://doc.qt.nokia.com/4.7/linguist-hellotr.html Example, "Internationalization with Qt":http://doc.qt.nokia.com/4.7/internationalization.html |
| tr() és a többnyelvűsítés | [http://doc.qt.nokia.com/4.7/linguist-manual.html Qt Linguist Manual], [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Writing Source Code for Translation], [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Hello tr()] Example, [http://doc.qt.nokia.com/4.7/internationalization.html Internationalization with Qt] |
| "QObject":http://doc.qt.nokia.com/4.7/qobject.html és a Qt objektummodell-rendszere | "Object Model":http://doc.qt.nokia.com/4.7/object.html |
| [http://doc.qt.nokia.com/4.7/qobject.html QObject] és a Qt objektummodell-rendszere | [http://doc.qt.nokia.com/4.7/object.html Object Model] |
| qmake a Qt build rendszere | "qmake Manual":http://doc.qt.nokia.com/4.7/qmake-manual.html | ===
| qmake a Qt build rendszere | [http://doc.qt.nokia.com/4.7/qmake-manual.html qmake Manual] | ===


Az elkövetkezőkben írunk egy saját .pro fájlt, ahelyett, hogy a qmake-el generáltatnánk le.
Az elkövetkezőkben írunk egy saját .pro fájlt, ahelyett, hogy a qmake-el generáltatnánk le.
Line 175: Line 175:


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.
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":http://doc.qt.nokia.com/4.7/qmainwindow.html van egy középső területe, ahol elhelyezhetünk bármilyen widgetet. Esetünkben is ide fog kerülni a szövegdobozunk.
A [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindownak] van egy középső területe, ahol elhelyezhetünk bármilyen widgetet. Esetünkben is ide fog kerülni a szövegdobozunk.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|QMainWindow]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|QMainWindow]]
Line 209: Line 209:
Az elkövetkezendőkben implementálni fogunk két slotot, mely a dokumentum megnyitására és mentésére fog szolgálni.  
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":http://doc.qt.nokia.com/4.7/qaction.html 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":http://doc.qt.nokia.com/4.7/qmenu.html és a "QToolBar":http://doc.qt.nokia.com/4.7/qtoolbar.html is létrehozhat menüket, eszköztárelemeket ugyanannak a "QAction":http://doc.qt.nokia.com/4.7/qaction.html -nek a hatására.
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 [http://doc.qt.nokia.com/4.7/qaction.html QAction] osztályt, amelyet átadhatunk több widgetnek is, majd hozzákötjük a megfelelő szlothoz a szignálját. Például a [http://doc.qt.nokia.com/4.7/qmenu.html QMenu] és a [http://doc.qt.nokia.com/4.7/qtoolbar.html QToolBar] is létrehozhat menüket, eszköztárelemeket ugyanannak a [http://doc.qt.nokia.com/4.7/qaction.html QAction] -nek a hatására.


Ahogyan már említettük a grafikus elemeket a Notepad osztály konstruktorában inicializáljuk.  
Ahogyan már említettük a grafikus elemeket a Notepad osztály konstruktorában inicializáljuk.  
Line 237: Line 237:
</code>
</code>


A "QAction-ök":http://doc.qt.nokia.com/4.7/qaction.html 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.  
A [http://doc.qt.nokia.com/4.7/qaction.html QAction-ök] 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.  


h3. További olvasnivalók:
h3. További olvasnivalók:
|''. Miről |''. Hol |
|''. Miről |''. Hol |
| Főablak és egyéb ablakok | "Application Main Window":http://doc.qt.nokia.com/4.7/mainwindow.html, "Main Window Examples":http://doc.qt.nokia.com/4.7/examples-mainwindow.html |
| Főablak és egyéb ablakok | [http://doc.qt.nokia.com/4.7/mainwindow.html Application Main Window], [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Main Window Examples] |
| MDI alkalmazások | "QMdiArea":http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example":http://doc.qt.nokia.com/4.7/mainwindows-mdi.html |
| MDI alkalmazások | [http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea], [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html MDI Example] |


A következő kódrészletben implementálni fogjuk a mentés és megnyitás kezelésére szolgáló szlotokat.  
A következő kódrészletben implementálni fogjuk a mentés és megnyitás kezelésére szolgáló szlotokat.  
Line 265: Line 265:
</code>
</code>


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":http://doc.qt.nokia.com/4.7/qfiledialog.html , amely egy dialógus megjelenítésére szolgál, amelyből a felhasználó kitallózhatja a kívánt fájlt.
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 [http://doc.qt.nokia.com/4.7/qfiledialog.html QFileDialog] , amely egy dialógus megjelenítésére szolgál, amelyből a felhasználó kitallózhatja a kívánt fájlt.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|A képen ezt a dialógust láthatjuk, ahogyan az KUbuntun megjelenik.]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|A képen ezt a dialógust láthatjuk, ahogyan az KUbuntun megjelenik.]]


A "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName) 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.
A [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName getOpenFileName()]) 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()":http://doc.qt.nokia.com/4.7/qiodevice.html#open 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":http://doc.qt.nokia.com/4.7/qmessagebox.html-ban jelenítjük meg a hibaüzenetet. A részletekért lásd a "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html osztály súgóját.
Ha megvan az érvényes fájlnév, akkor megnyitjuk a fájlt a QFile [http://doc.qt.nokia.com/4.7/qiodevice.html#open open()] 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 [http://doc.qt.nokia.com/4.7/qmessagebox.html-ban QMessageBox] jelenítjük meg a hibaüzenetet. A részletekért lásd a [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] osztály súgóját.


Az adatok beolvasása triviális a "QFile":http://doc.qt.nokia.com/4.7/qfile.html "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll metódusának köszönhetően. Ez a függvény egy a fájlban lévő adatokat tartlmazó "QByteArray":http://doc.qt.nokia.com/4.7/qbytearray.htm -jel tér vissza. A QByteArray "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData metódusa segítségével az adatokat const char* formában is elérhetjük, amit már át tudunk adni a "QString":http://doc.qt.nokia.com/4.7/qstring.html konstruktorának. Így a fájl tartalma megjeleníthető a szövegdobozban. Végül a "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close metódussal bezárjuk a fájlt, így adva vissza a fájlleírót az operációs rendszernek.  
Az adatok beolvasása triviális a [http://doc.qt.nokia.com/4.7/qfile.html QFile] [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll readAll()] metódusának köszönhetően. Ez a függvény egy a fájlban lévő adatokat tartlmazó [http://doc.qt.nokia.com/4.7/qbytearray.htm QByteArray] -jel tér vissza. A QByteArray [http://doc.qt.nokia.com/4.7/qbytearray.html#constData constData()] metódusa segítségével az adatokat const char* formában is elérhetjük, amit már át tudunk adni a [http://doc.qt.nokia.com/4.7/qstring.html QString] konstruktorának. Így a fájl tartalma megjeleníthető a szövegdobozban. Végül a [http://doc.qt.nokia.com/4.7/qiodevice.html#close close()] 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:
Most, hogy letudtuk a megnyitás szlotot lássuk a mentést:
Line 294: Line 294:
</code>
</code>


Miután megszerkesztettük a szövegdobozunk tartalmát, azt a "QTextStream":http://doc.qt.nokia.com/4.7/qtextstream.html objektumon keresztül írjuk vissza a fájlunkba. Ez az osztály mintegy ráépül a "QFile":http://doc.qt.nokia.com/4.7/qfile.html objektumunkra, lehetővé téve, hogy a neki küldött szövegeket direktben kiírassuk a fájlunkba.
Miután megszerkesztettük a szövegdobozunk tartalmát, azt a [http://doc.qt.nokia.com/4.7/qtextstream.html QTextStream] objektumon keresztül írjuk vissza a fájlunkba. Ez az osztály mintegy ráépül a [http://doc.qt.nokia.com/4.7/qfile.html QFile] objektumunkra, lehetővé téve, hogy a neki küldött szövegeket direktben kiírassuk a fájlunkba.


=== További olvasnivalók:
=== További olvasnivalók:
|''. Miről |''. Hol | ===
|''. Miről |''. Hol | ===

Revision as of 15:39, 4 March 2015

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

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 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.

p=. Notepad

Íme a kód:

#include <QApplication>
#include <QTextEdit>

int main(int argv, char **args)
{
 QApplication app(argv, args);

QTextEdit textEdit;
 textEdit.show();

return app.exec();
}

Vizsgáljuk meg a kódot sorról sorra. Az első két sorban a QApplication és a QTextEdit 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 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.

A 8. sorban létrehozunk egy QTextEdit 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, 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 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:

 qmake -project
 qmake
 make

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.

h3. További olvasnivalók: |. Miről |. Hol | | Widgetek és ablakok geometriája | Window and Dialog Widgets | | Események és a Qt eseménykezelője | The Event System |

h2. 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 a szövegdoboz alá. Ez arra fog szolgálni, hogy ha a felhasználó rákattint, a program lépjen ki.

p=. Eingabefeld mit Beenden Knopf

Nézzük a kódot:

#include <QtGui>

int main(int argv, char **args)
{
 QApplication app(argv, args);

 QTextEdit textEdit;
 QPushButton quitButton("Quit");

 QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));

 QVBoxLayout layout;
 layout.addWidget(&amp;textEdit);
 layout.addWidget(&amp;quitButton);

 QWidget window;
 window.setLayout(&amp;layout);

 window.show();

 return app.exec();
}

Az első sorban beincludoljuk a QtGui 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() a widgetünk egy beépített slotja, amelyet meghívva az alkalmazás kilép. A gombunk clicked() szignálja pedig a gomb megnyomásakor emittálódik. A szignál-slot hozzárendelést a statikus QObject::connect() 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 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 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.

h3. További olvasnivalók: |. Miről |. Hol | | Szignálok és Szlotok | Signals & Slots | | Layoutok | Layout Management, Widgets and Layouts, Layout Examples | | A QT beépített widgetkészlete | Qt Widget Gallery, Widget Examples |

h2. 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 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:

 class Notepad : public QWidget
 {
 Q_OBJECT

 public:
 Notepad();

 private slots:
 void quit();

 private:
 QTextEdit *textEdit;
 QPushButton *quitButton;
 };

A Q_OBJECT makrónak kell az osztálydeklaráció elején lennie. Ez a makró az osztályunkat QObjectként deklarálja (természetesen a használatához a QObjecttől kell származtatnunk). Ez a példánkban is így van, hiszen a QWidget osztály a QObjectből van származtatva. A QObject 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.

 Notepad::Notepad()
 {
 textEdit = new QTextEdit;
 quitButton = new QPushButton(tr("Quit"));

 connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));

 QVBoxLayout *layout = new QVBoxLayout;
 layout->addWidget(textEdit);
 layout->addWidget(quitButton);

setLayout(layout);

setWindowTitle(tr("Notepad"));
 }

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() 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 dokumentációjánál találsz.

=== További olvasnivalók: |. Miről |. Hol | | tr() és a többnyelvűsítés | Qt Linguist Manual, Writing Source Code for Translation, Hello tr() Example, Internationalization with Qt | | QObject és a Qt objektummodell-rendszere | Object Model | | qmake a Qt build rendszere | qmake Manual | ===

Az elkövetkezőkben írunk egy saját .pro fájlt, ahelyett, hogy a qmake-el generáltatnánk le.

 HEADERS = notepad.h
 SOURCES = notepad.cpp  main.cpp

A következő parancsokkal tudod lefordítani a példát:

 qmake
 make

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 van egy középső területe, ahol elhelyezhetünk bármilyen widgetet. Esetünkben is ide fog kerülni a szövegdobozunk.

p=. QMainWindow

Tekintsük át a Notepad osztály definícióját!

 #include <QtGui>

class Notepad : public QMainWindow
 {
 Q_OBJECT

public:
 Notepad();

private slots:
 void open();
 void save();
 void quit();

private:
 QTextEdit *textEdit;

QAction *openAction;
 QAction *saveAction;
 QAction *exitAction;

QMenu '''fileMenu;
 };

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 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 és a QToolBar is létrehozhat menüket, eszköztárelemeket ugyanannak a QAction -nek a hatására.

Ahogyan már említettük a grafikus elemeket a Notepad osztály konstruktorában inicializáljuk.

 Notepad::Notepad()
 {
 saveAction = new QAction(tr("&amp;Open"), this);
 saveAction = new QAction(tr("&amp;Save"), this);
 exitAction = new QAction(tr("E&amp;amp;xit"), this);

 connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
 connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
 connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));

 fileMenu = menuBar()->addMenu(tr("&amp;File"));
 fileMenu->addAction(openAction);
 fileMenu->addAction(saveAction);
 fileMenu->addSeparator();
 fileMenu->addAction(exitAction);

 textEdit = new QTextEdit;
 setCentralWidget(textEdit);

 setWindowTitle(tr("Notepad"));
 }

A QAction-ök 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.

h3. További olvasnivalók: |. Miről |. Hol | | Főablak és egyéb ablakok | Application Main Window, Main Window Examples | | MDI alkalmazások | QMdiArea, MDI Example |

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:

 QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp'''.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::ReadOnly)) {
 QMessageBox::critical(this, tr("Error"),
 tr("Could not open file"));
 return;
 }
 QString contents = file.readAll().constData();
 textEdit->setPlainText(contents);
 file.close();
 }

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 , amely egy dialógus megjelenítésére szolgál, amelyből a felhasználó kitallózhatja a kívánt fájlt.

p=. A képen ezt a dialógust láthatjuk, ahogyan az KUbuntun megjelenik.

A getOpenFileName()) 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() 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 jelenítjük meg a hibaüzenetet. A részletekért lásd a QMessageBox osztály súgóját.

Az adatok beolvasása triviális a QFile readAll() metódusának köszönhetően. Ez a függvény egy a fájlban lévő adatokat tartlmazó QByteArray -jel tér vissza. A QByteArray constData() metódusa segítségével az adatokat const char* formában is elérhetjük, amit már át tudunk adni a QString konstruktorának. Így a fájl tartalma megjeleníthető a szövegdobozban. Végül a close() 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:

 QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp *.h)"));

 if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::WriteOnly)) {
 // error message
 } else {
 QTextStream stream(&amp;file);
 stream << textEdit->toPlainText();
 stream.flush();
 file.close();
 }
 }

Miután megszerkesztettük a szövegdobozunk tartalmát, azt a QTextStream objektumon keresztül írjuk vissza a fájlunkba. Ez az osztály mintegy ráépül a QFile objektumunkra, lehetővé téve, hogy a neki küldött szövegeket direktben kiírassuk a fájlunkba.

=== További olvasnivalók: |. Miről |. Hol | ===