Basic Programming/hu

From Qt Wiki
Revision as of 16:57, 3 March 2015 by AutoSpider (talk | contribs) (Add "cleanup" tag)
Jump to navigation Jump to search
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":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":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.

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

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":http://doc.qt.nokia.com/4.7/application-windows.html | | Események és a Qt eseménykezelője | "The Event System":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":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:

#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":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":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 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":http://doc.qt.nokia.com/4.7/signalsandslots.html | | 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 | | 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 |

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.

Í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":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 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()":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.

=== További olvasnivalók: |. 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 | | "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 | | qmake a Qt build rendszere | "qmake Manual":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
 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":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!

 #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":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.

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":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":http://doc.qt.nokia.com/4.7/mainwindow.html, "Main Window Examples":http://doc.qt.nokia.com/4.7/examples-mainwindow.html | | 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 |

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

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.

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

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