Basic Programming/hu

From Qt Wiki
Revision as of 09:39, 24 February 2015 by Maintenance script (talk | contribs)
Jump to navigation Jump to search


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":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 &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;

int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);

QTextEdit textEdit;<br /> textEdit.show();

return app.exec&amp;amp;#40;&amp;#41;;<br />}

Vizsgáljuk meg a kódot sorról sorra. Az első két sorban a "QApplication&quot;:http://doc.qt.nokia.com/qapplication.html és a "QTextEdit&quot;: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.

A 6. sorban létrehozunk egy "QApplication&quot;: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&quot;:http://doc.trolltech.com/4.7/qapplication.html#QApplication.

A 8. sorban létrehozunk egy "QTextEdit&quot;: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 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&quot;: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 11. sorban meghívjuk a "QApplication&quot;: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.

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:

<br /> qmake -project<br /> qmake<br /> make<br />

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&quot;:http://doc.qt.nokia.com/4.7/application-windows.html |
| Események és a Qt eseménykezelője | "The Event System&quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html |
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&quot;: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.
p=. Eingabefeld mit Beenden Knopf
Nézzük a kódot:


<br />#include &lt;QtGui&amp;gt;
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
<br /> window.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />


Az első sorban beincludoljuk a "QtGui&quot;:http://doc.qt.nokia.com/4.7/qtgui.html 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()":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 12. sorban egy "QVBoxLayout-ot&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html 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&quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html |
| Layoutok | "Layout Management&quot;:http://doc.qt.nokia.com/4.7/layout.html, "Widgets and Layouts&quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, "Layout Examples&quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html |
| A QT beépített widgetkészlete | "Qt Widget Gallery&quot;:http://doc.qt.nokia.com/4.7/gallery.html, "Widget Examples&quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html |
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&quot;: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.
Íme a kód:


<br /> class Notepad : public QWidget<br /> {<br /> Q_OBJECT
<br /> public:<br /> Notepad();
<br /> private slots:<br /> void quit();
<br /> private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br /> };<br />


A Q_OBJECT makrónak kell az osztálydeklaráció elején lennie. Ez a makró az osztályunkat "QObjectként&quot;:http://doc.qt.nokia.com/4.7/qobject.html deklarálja (természetesen a használatához a "QObjecttől&quot;: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&quot;: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 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.


<br /> Notepad::Notepad()<br /> {<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<br /> connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));
<br /> QVBoxLayout *layout = new QVBoxLayout;<br /> layout</s>&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);

setLayout(layout);

setWindowTitle(tr(&quot;Notepad&amp;quot;));<br /> }<br />

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&quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html 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&quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html, "Writing Source Code for Translation&quot;: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&quot;:http://doc.qt.nokia.com/4.7/internationalization.html |
| "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html és a Qt objektummodell-rendszere | "Object Model&quot;:http://doc.qt.nokia.com/4.7/object.html |
| qmake a Qt build rendszere | "qmake Manual&quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html |

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

 HEADERS = notepad.h<br /> SOURCES = notepad.cpp  main.cpp

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

 qmake<br /> 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&quot;: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.

p=. QMainWindow

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

<br /> #include &lt;QtGui&amp;gt;

class Notepad : public QMainWindow<br /> {<br /> Q_OBJECT

public:<br /> Notepad();

private slots:<br /> void open();<br /> void save();<br /> void quit();

private:<br /> QTextEdit *textEdit;

QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;

QMenu '''fileMenu;<br /> };<br />


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&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qmenu.html és a "QToolBar&quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html is létrehozhat menüket, eszköztárelemeket ugyanannak a "QAction&quot;:http://doc.qt.nokia.com/4.7/qaction.html nek a hatására.
Ahogyan már említettük a grafikus elemeket a Notepad osztály konstruktorában inicializáljuk.


<br /> Notepad::Notepad()<br /> {<br /> saveAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()</s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu-&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);
<br /> textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br /> }<br />


A "QAction-ök&quot;: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.
h3. További olvasnivalók:
|. Miről |. Hol |
| Főablak és egyéb ablakok | "Application Main Window&quot;:http://doc.qt.nokia.com/4.7/mainwindow.html, "Main Window Examples&quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html |
| MDI alkalmazások | "QMdiArea&quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example&quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html |
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:


<br /> QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp'''.h)&quot;));

if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br /> }<br />

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&quot;: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.

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

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&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html osztály súgóját.

Az adatok beolvasása triviális a "QFile&quot;: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&quot;: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&quot;: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.
Most, hogy letudtuk a megnyitás szlotot lássuk a mentést:


<br /> QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp *.h)&quot;));
<br /> if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // error message<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit</s>&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br /> }<br />

Miután megszerkesztettük a szövegdobozunk tartalmát, azt a "QTextStream&quot;: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&quot;: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.

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