Basic Programming/cs: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
[toc align_right="yes" depth="3"]
[toc align_right="yes" depth="3"]


= Začínáme programovat s Qt =
= Začínáme programovat s Qt =
Line 13: Line 13:
A toto je jeho zdrojový kód:
A toto je jeho zdrojový kód:


<code>#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;
<code>#include <QApplication>
#include <QTextEdit>


int main(int argv, char *'''args)<br />{<br /> QApplication app(argv, args);
int main(int argv, char *'''args)
<br /> QTextEdit textEdit;<br /> textEdit.show();
{
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}</code>
QApplication app(argv, args);
<br />Nyní si tento zdrojový kód řádek po řádku projdeme. V prvních dvou řádcích vkládáme hlavičkové soubory pro &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html a &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html, což jsou přávě ty třídy, které pro tento příklad potřebujeme. Názvy všech Qt hlavičkových souborů se shodují s názvy tříd které jsou v nich deklarovány.
<br />Na řádku 6 vytváříme objekt třídy &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html. Tento objekt spravuje prostředky celé aplikace a je vyžadován pro funkčnost všech Qt programů mající GUI. Jako parametry potřebuje argv a args, potože Qt samo od sebe přijímá několik argumentů příkazové řádky.
<br />Řádek 8 vytváří objekt třídy &quot;QTextEdit&amp;quot;:http://doc.qt.nokia.com/4.7/qtextedit.html. Oblast pro úpravu textu je vizuální prvek GUI. V Qt takovéto elementy nazýváme widgety. Příklady dalších widgetů jsou například posuvníky, štítky, přepínače, atp. Widget může být zároveň kontejnerem pro další widgety; příkladem budiž hlavní okno aplikace či dialog.
<br />Řádek 9 zobrazí oblast pro úpravu textu na obrazovce ve vlastním okně. Vzhledem k tomu, že widgety mohou složit i jako kontejnery (například &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, který obsahuje nástrojovou lištu, menu, stavový řádek a několik dalších widgetů), je možné zobrazit widget ve vlastním okně. Widgety jsou implicitně skryty; o zobrazení se stará právě metoda &quot;show()&quot;:http://doc.qt.nokia.com/4.7/qwidget.html#show).
<br />Řádek 11 spustí hlavní smyčku eventů aplikace. Dokud aplikace beží, jejím widgetům jsou zasílány eventy. Příkladem eventů jsou stisknutí tlačítek myši a klávesnice. Jakmile napíšete text do dříve zmíněné oblasti pro úpravu textu, ta obdrží eventy informující o stisknutí kláves a reaguje vykreslením příslušného textu.
<br />Pro spuštění aplikace, otevřete příkazovou řádku, přejděte do adresáře kde máte její zdrojový soubor a napište následující příkazy.
<br /><code>qmake -project<br />qmake<br />make</code>
<br />Ty vytvoří spustitelný soubor v daném adresáři (na systémech windows bude možná třeba použít nmake namísto make. Také spustitelné soubory se budou nacházet buďto v podadresáři release nebo debug). qmake je Qt nástroj pro sestavování projektů vyžadující konfigurační soubor. Tento konfigurační soubor za nás qmake sám vygeneruje, když ho spustíme s přepínačem -project. Z daného konfiguračního souboru (s příponou .pro) qmake vytvoří makefile, která za vás program sestaví. Na to jak si můžete vytvořit vlastní .pro soubor se podíváme později.
<br />h3. Rozšiřující informace
<br />|Téma|Odkaz|<br />|Widgety a gemoetrie okna|&quot;Window and Dialog Widgets&amp;quot;:http://doc.qt.nokia.com/4.7/application-windows.html|<br />|Eventy a jejich zpracování|&quot;The Event System&amp;quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html|
<br />h2. Přídání tlačítka 'Quit'
<br />V reálné aplikaci budete běžně potřebovat více než jen jeden widget. Nyní přidáme &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html pod oblast pro úpravu textu. Toto tlačítko bude plnit funkci vypínače aplikace (společně se zavřením okna).
<br />[[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|Ahoj Notepade]]
<br />Nyní se podívejme na zdrojový kód
<br /><code>#include &lt;QtGui&amp;gt;
<br />int main(int argv, char'''*args)<br />{<br /> QApplication app(argv, args);


QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);
QTextEdit textEdit;
textEdit.show();
 
return app.exec();
}</code>
 
Nyní si tento zdrojový kód řádek po řádku projdeme. V prvních dvou řádcích vkládáme hlavičkové soubory pro "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html a "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html, což jsou přávě ty třídy, které pro tento příklad potřebujeme. Názvy všech Qt hlavičkových souborů se shodují s názvy tříd které jsou v nich deklarovány.
 
Na řádku 6 vytváříme objekt třídy "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html. Tento objekt spravuje prostředky celé aplikace a je vyžadován pro funkčnost všech Qt programů mající GUI. Jako parametry potřebuje argv a args, potože Qt samo od sebe přijímá několik argumentů příkazové řádky.
 
Řádek 8 vytváří objekt třídy "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html. Oblast pro úpravu textu je vizuální prvek GUI. V Qt takovéto elementy nazýváme widgety. Příklady dalších widgetů jsou například posuvníky, štítky, přepínače, atp. Widget může být zároveň kontejnerem pro další widgety; příkladem budiž hlavní okno aplikace či dialog.
 
Řádek 9 zobrazí oblast pro úpravu textu na obrazovce ve vlastním okně. Vzhledem k tomu, že widgety mohou složit i jako kontejnery (například "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, který obsahuje nástrojovou lištu, menu, stavový řádek a několik dalších widgetů), je možné zobrazit widget ve vlastním okně. Widgety jsou implicitně skryty; o zobrazení se stará právě metoda "show()":http://doc.qt.nokia.com/4.7/qwidget.html#show).
 
Řádek 11 spustí hlavní smyčku eventů aplikace. Dokud aplikace beží, jejím widgetům jsou zasílány eventy. Příkladem eventů jsou stisknutí tlačítek myši a klávesnice. Jakmile napíšete text do dříve zmíněné oblasti pro úpravu textu, ta obdrží eventy informující o stisknutí kláves a reaguje vykreslením příslušného textu.
 
Pro spuštění aplikace, otevřete příkazovou řádku, přejděte do adresáře kde máte její zdrojový soubor a napište následující příkazy.
 
<code>qmake -project
qmake
make</code>
 
Ty vytvoří spustitelný soubor v daném adresáři (na systémech windows bude možná třeba použít nmake namísto make. Také spustitelné soubory se budou nacházet buďto v podadresáři release nebo debug). qmake je Qt nástroj pro sestavování projektů vyžadující konfigurační soubor. Tento konfigurační soubor za nás qmake sám vygeneruje, když ho spustíme s přepínačem -project. Z daného konfiguračního souboru (s příponou .pro) qmake vytvoří makefile, která za vás program sestaví. Na to jak si můžete vytvořit vlastní .pro soubor se podíváme později.
 
h3. Rozšiřující informace
 
|Téma|Odkaz|
|Widgety a gemoetrie okna|"Window and Dialog Widgets":http://doc.qt.nokia.com/4.7/application-windows.html|
|Eventy a jejich zpracování|"The Event System":http://doc.qt.nokia.com/4.7/eventsandfilters.html|
 
h2. Přídání tlačítka 'Quit'
 
V reálné aplikaci budete běžně potřebovat více než jen jeden widget. Nyní přidáme "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html pod oblast pro úpravu textu. Toto tlačítko bude plnit funkci vypínače aplikace (společně se zavřením okna).
 
[[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|Ahoj Notepade]]
 
Nyní se podívejme na zdrojový kód
 
<code>#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()));
QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));


QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
QVBoxLayout layout;
layout.addWidget(&amp;textEdit);
layout.addWidget(&amp;quitButton);


QWidget window;<br /> window.setLayout(&amp;layout);
QWidget window;
window.setLayout(&amp;layout);


window.show();
window.show();


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


Na řádku 1 vkládáme &quot;QtGui&amp;quot;:http://doc.qt.nokia.com/4.7/qtgui.html, které obsahuje všechny Qt GUI třídy.
Na řádku 1 vkládáme "QtGui":http://doc.qt.nokia.com/4.7/qtgui.html, které obsahuje všechny Qt GUI třídy.


Řádek 10 používá Qt systém signálů a slotů a zajišťuje, že stisknutí tlačítka 'Quit' ukončí aplikaci. Slot je funkce, která může být vyvolána za běhu použitím jejího jména (jako doslovný řetězec). Signál je funkce, která když zavolána zavolá všechny sloty s ní propojené; tyto procedury nazýváme propojení slotu se signálem (to connect the slot to the signal) a vyslání signálu (to emit the signal).
Řádek 10 používá Qt systém signálů a slotů a zajišťuje, že stisknutí tlačítka 'Quit' ukončí aplikaci. Slot je funkce, která může být vyvolána za běhu použitím jejího jména (jako doslovný řetězec). Signál je funkce, která když zavolána zavolá všechny sloty s ní propojené; tyto procedury nazýváme propojení slotu se signálem (to connect the slot to the signal) a vyslání signálu (to emit the signal).


&quot;quit()&quot;:http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit je slot třídy &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html , který při zavolání ukončí aplikaci. &quot;clicked()&quot;:http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked je signál třídy, který &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html vyšle poté co je stisknut. Statická funkce &quot;QObject::connect()&quot;:http://doc.qt.nokia.com/4.7/qobject.html#connect se stará o propojení signálu se slotem. SIGNAL () a SLOT() jsou dvě makra, která přebírají prototyp (type-signature) signálu a slotu k propojení.
"quit()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit je slot třídy "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html , který při zavolání ukončí aplikaci. "clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked je signál třídy, který "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html vyšle poté co je stisknut. Statická funkce "QObject::connect()":http://doc.qt.nokia.com/4.7/qobject.html#connect se stará o propojení signálu se slotem. SIGNAL () a SLOT() jsou dvě makra, která přebírají prototyp (type-signature) signálu a slotu k propojení.


Řádek 12 vytváří objekt třídy &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html. Jak již bylo zmíňeno, widgety mohou obsahovat další wigety. Je také možné přímo nastavit meze (umístění a velikost) potomků widgetu (widgetů, které daný widget obsahuje). Layout spravuje meze svých potomků automaticky. Například &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html umístí potomky vertikálně pod sebe.
Řádek 12 vytváří objekt třídy "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html. Jak již bylo zmíňeno, widgety mohou obsahovat další wigety. Je také možné přímo nastavit meze (umístění a velikost) potomků widgetu (widgetů, které daný widget obsahuje). Layout spravuje meze svých potomků automaticky. Například "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html umístí potomky vertikálně pod sebe.


Řádky 13 a 14 přidávájí do layoutu oblast na úpravu textu a tlačítko. Řádek 17 nastavuje nastaví widgetu hlavní layout.
Řádky 13 a 14 přidávájí do layoutu oblast na úpravu textu a tlačítko. Řádek 17 nastavuje nastaví widgetu hlavní layout.
Line 64: Line 98:
|-
|-
|Signály a Sloty
|Signály a Sloty
|&quot;Signals &amp; Slots&amp;quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html
|"Signals &amp; Slots":http://doc.qt.nokia.com/4.7/signalsandslots.html
|-
|-
|Layouty
|Layouty
|&quot;Layout Management&amp;quot;:http://doc.qt.nokia.com/4.7/layout.html, &quot;Widgets and Layouts&amp;quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, &quot;Layout Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html
|"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
|-
|-
|Widgety které Qt nabízí
|Widgety které Qt nabízí
|&quot;Qt Widget Gallery&amp;quot;:http://doc.qt.nokia.com/4.7/gallery.html, &quot;Widget Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html
|"Qt Widget Gallery":http://doc.qt.nokia.com/4.7/gallery.html, "Widget Examples":http://doc.qt.nokia.com/4.7/examples-widgets.html
|}
|}


== Odvozování vlastních widgetů od QWidgetu ==
== Odvozování vlastních widgetů od QWidgetu ==


Možná by bylo hezké dotázat se uživatele před ukončením aplikace, zdali opravdu chce aplikaci opustit. V tomto příkladě vytvoříme podtřídu &quot;QWidgetu&amp;quot;:http://doc.qt.nokia.com/4.7/qwidget.html, které přidáme vlastní slot a následně ho napojíme na naše tlačítko 'Quit'.
Možná by bylo hezké dotázat se uživatele před ukončením aplikace, zdali opravdu chce aplikaci opustit. V tomto příkladě vytvoříme podtřídu "QWidgetu":http://doc.qt.nokia.com/4.7/qwidget.html, které přidáme vlastní slot a následně ho napojíme na naše tlačítko 'Quit'.


[[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Odvozujeme od QWidgetu]]
[[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Odvozujeme od QWidgetu]]
Line 81: Line 115:
Podívejme se nyní na zdrojový kód
Podívejme se nyní na zdrojový kód


<code>class Notepad : public QWidget<br />{<br /> Q_OBJECT
<code>class Notepad : public QWidget
{
Q_OBJECT


public:<br /> Notepad();
public:
Notepad();


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


private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};</code>
private:
QTextEdit *textEdit;
QPushButton *quitButton;
};</code>


Na začátku definice naší třídy (která přirozeně musí být podtřídou třídy &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html. &quot;QObject&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html) musí být makro Q_OBJECT, to z ní učiní plnohotnotný QObject. To že je třída QObjectem jí dává specielní vlastnosti. Například se můžeme dotázat na název třídy či slotu za běhu programu. Je také možné zjistit parametry slotu a zavolat ho.
Na začátku definice naší třídy (která přirozeně musí být podtřídou třídy "QObject":http://doc.qt.nokia.com/4.7/qobject.html. "QObject":http://doc.qt.nokia.com/4.7/qobject.html) musí být makro Q_OBJECT, to z ní učiní plnohotnotný QObject. To že je třída QObjectem jí dává specielní vlastnosti. Například se můžeme dotázat na název třídy či slotu za běhu programu. Je také možné zjistit parametry slotu a zavolat ho.


Řádek 13 deklaruje slot quit(). Nyní můžeme quit() propojit se signály s odpovídajícím prototypem (libovolným bezparametrickým signálem).
Řádek 13 deklaruje slot quit(). Nyní můžeme quit() propojit se signály s odpovídajícím prototypem (libovolným bezparametrickým signálem).
Line 95: Line 136:
Namísto nastavování GUI a propojení slotu ve funkci main() provádíme tuto práci v konstruktoru třídy Notepad.
Namísto nastavování GUI a propojení slotu ve funkci main() provádíme tuto práci v konstruktoru třídy Notepad.


<code>Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<code>Notepad::Notepad()
{
textEdit = new QTextEdit;
quitButton = new QPushButton(tr("Quit"));


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


QVBoxLayout '''layout = new QVBoxLayout;<br /> layout-&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);
QVBoxLayout '''layout = new QVBoxLayout;
<br /> setLayout(layout);
layout->addWidget(textEdit);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}</code>
layout->addWidget(quitButton);
<br />Jak jste mohli vidět v definici třídy, používáme ukazatele na naše &quot;QObjekty&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html (textEdit a quitButton). Zpravidla byste měli &quot;QObjekty&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html vždy alokovat na heapu a nikdy je kopírovat.
 
<br />Viditelné stringy &quot;obalujeme&amp;quot; do funkce &quot;tr()&quot;:http://doc.qt.nokia.com/4.7/qobject.html#tr&amp;gt; a to z toho důvodu, kdybychom se v budoucnu rozhodli poskytovat naší aplikaci ve více jazykových mutacích. Nebudeme zacházet do detailů, ovšem pokud vás téma zajímá, můžete se podívat na odkaz Qt Linguist z následující tabulky.
setLayout(layout);
<br />h3. Rozšiřující informace
 
<br />|Téma|Odkaz|<br />|tr() a internacionalizace|&quot;Qt Linguist Manual&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html, &quot;Writing SOurce Code for Translation&amp;quot;:http://doc.qt.nokia.com/4.7/i18n-source-translation.html, &quot;Hello tr()&quot;:http://doc.qt.nokia.com/4.7/linguist-hellotr.html Example, &quot;Internationalization with Qt&amp;quot;:http://doc.qt.nokia.com/4.7/internationalization.html|<br />|QObjekty a objektový model Qt (Základ pro porozumění Qt)|&quot;Object Model&amp;quot;:http://doc.qt.nokia.com/4.7/object.html|<br />|qmake a systém překladu Qt|&quot;qmake Manual&amp;quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html|
setWindowTitle(tr("Notepad"));
<br />h2. Vytváření .pro souboru
}</code>
<br />Na ukázku si vytvoříme vlastní .pro soubor namísto toho, který za nás vygenerovalo qmake <s>project.
 
<br /><code>HEADERS = notepad.h<br />SOURCES = notepad.cpp  main.cpp</code>
Jak jste mohli vidět v definici třídy, používáme ukazatele na naše "QObjekty":http://doc.qt.nokia.com/4.7/qobject.html (textEdit a quitButton). Zpravidla byste měli "QObjekty":http://doc.qt.nokia.com/4.7/qobject.html vždy alokovat na heapu a nikdy je kopírovat.
<br />Následující příkazy přeloží náš ukázkový projekt.
 
<br /><code>qmake<br />make</code>
Viditelné stringy "obalujeme" do funkce "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr> a to z toho důvodu, kdybychom se v budoucnu rozhodli poskytovat naší aplikaci ve více jazykových mutacích. Nebudeme zacházet do detailů, ovšem pokud vás téma zajímá, můžete se podívat na odkaz Qt Linguist z následující tabulky.
<br />h2. Používání třídy QMainWindow
 
<br />Mnoho aplikací bude mít prospěch z používání &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html, které má svůj vlastní layout kam můžete přidat menu, dokovací widgety, nástrojovou lištu a stavovou lištu. &quot;QMainWindow&amp;quot;:http://doc.qt.nokia.com/4.7/qmainwindow.html má centrální oblast která může obsahovat libovolný widget. V Našem případě tam umístíme naši oblast pro úpravu textu.
h3. Rozšiřující informace
<br />[[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|Používání třídy QMainWindow]]
 
<br />Nyní se podívejme na novou definici třídy Notepad
|Téma|Odkaz|
<br /><code>#include &lt;QtGui&amp;gt;
|tr() a internacionalizace|"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|
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
|QObjekty a objektový model Qt (Základ pro porozumění Qt)|"Object Model":http://doc.qt.nokia.com/4.7/object.html|
<br />public:<br /> Notepad();
|qmake a systém překladu Qt|"qmake Manual":http://doc.qt.nokia.com/4.7/qmake-manual.html|
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
 
<br />private:<br /> QTextEdit *textEdit;
h2. Vytváření .pro souboru
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
 
<br /> QMenu '''fileMenu;<br />};</code>
Na ukázku si vytvoříme vlastní .pro soubor namísto toho, který za nás vygenerovalo qmake -project.
<br />Přidáváme další dva sloty pro otevření a uložení dokumentu. Budou implementovány v následující sekci.
 
<br />Často chceme, aby bylo možné vyvolat jediný slot několika widgety. Typický příklad představují položky menu a tlačítka na nástrojové liště. Pro usnadnění Qt nabízízí &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html, která může být předáná několika widgetům a být propojena se slotem. Například jak &quot;QMenu&amp;quot;:http://doc.qt.nokia.com/4.7/qmenu.html tak i &quot;QToolBar&amp;quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html mohou vytvářet položky menu a nástrojová tlačítka z identických &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html objektů. Za moment se podíváme jak to funguje.
<code>HEADERS = notepad.h
<br />Stejně jako v předchozí definici, nastavujeme GUI v konstruktoru třídy Notepad
SOURCES = notepad.cpp  main.cpp</code>
<br /><code>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()));
Následující příkazy přeloží náš ukázkový projekt.
<br /> fileMenu = menuBar()<s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu</s>&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);
 
<br /> textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);
<code>qmake
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}</code>
make</code>
<br />Naše &quot;QAction&amp;quot;:http://doc.qt.nokia.com/4.7/qaction.html objekty jsou vytvořeny s textem který chceme zobrazit na widgetech kterým je předáme (v našem případě se jedná o položky v menu). Pokud bychom je zároveň chtěli přidat do nástrojové lišty, mohli bychom jim nastavit i &quot;ikony&amp;quot;:http://doc.qt.nokia.com/4.7/qicon.html.
 
<br />Pokud nyní stiskneme položku v menu, spustí to danou akci a ta vyvolá příslušný slot.
h2. Používání třídy QMainWindow
<br />h3. Rozšiřující informace
 
<br />|Téma|Odkaz|<br />|Hlavní okna a jejich třídy|&quot;Application Main Window&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindow.html, &quot;Main Window Examples&amp;quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html|<br />|MDI aplikace|&quot;QMdiArea&amp;quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html, &quot;MDI Example&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html|
Mnoho aplikací bude mít prospěch z používání "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, které má svůj vlastní layout kam můžete přidat menu, dokovací widgety, nástrojovou lištu a stavovou lištu. "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html má centrální oblast která může obsahovat libovolný widget. V Našem případě tam umístíme naši oblast pro úpravu textu.
<br />h2. Ukládání a načítání
 
<br />V tomto příkladě naimplementujeme funkčnost slotů open() a save(), které jsme přidali v předchozí definici.
[[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|Používání třídy QMainWindow]]
<br />[[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|Ukládání a načítání]]
 
<br />Začneme se slotem open():
Nyní se podívejme na novou definici třídy Notepad
<br /><code>QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open 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::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</s>&gt;setPlainText(contents);<br /> file.close();<br />}</code>
<code>#include <QtGui>
<br />Prvním krokem je dotázání se uživatele na název souboru, který chce otevřít. Qt nabízí &quot;QFileDialog&amp;quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html, což je dialog ve kterém uživatel může vybrat soubor. Obrázek výše zobrazuje tento dialog na Linuxové distribuci Kubuntu. Statická funkce &quot;getOpenFileName()&quot;:http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName&amp;gt; zobrazí modální souborový dialog a neskončí dokud uživatel nevybere soubor. Vrací cestu k vybranému souboru, případně prázdný řetězec pokud uživatel dialog zrušil.
 
<br />Pokud máme cestu k souboru, pokusíme se ho otevřít funkcí &quot;open()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#open&amp;gt;. Ta vrací true pokud bylo otevření úspěšné. Nebudeme zacházet do detailů co se zpracování chyb týče, ovšem můžete si přečíst články odkázané v sekci &quot;Rozšiřující informace&amp;quot;. Pokud soubor nemůže být otevřen, zobrazíme &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html a zobrazíme dialog s chybovým hlášením (pro více informací si přečtěte dokumentaci třídy &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html).<br />Čtení dat je díky funcki &quot;readAll()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#readAll&amp;gt; triviální, ta vrátí veškerá data obsažená v souboru v &quot;QByteArray&amp;quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. Funkce &quot;constData()&quot;:http://doc.qt.nokia.com/4.7/qbytearray.html#constData&amp;gt; vrací veškerá data jako const char''' jenž &quot;QString&amp;quot;:http://doc.qt.nokia.com/4.7/qstring.html přebírá v jednom ze svých konstruktorů. Poté již obsah souboru snadno zobrazíme v oblasti pro úpravu textu. Po načtení soubor uzavřeme za použití &quot;close()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#close&amp;gt;, tím předáme souborový deskriptor zpět operačnímu systému.
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;
};</code>
 
Přidáváme další dva sloty pro otevření a uložení dokumentu. Budou implementovány v následující sekci.
 
Často chceme, aby bylo možné vyvolat jediný slot několika widgety. Typický příklad představují položky menu a tlačítka na nástrojové liště. Pro usnadnění Qt nabízízí "QAction":http://doc.qt.nokia.com/4.7/qaction.html, která může být předáná několika widgetům a být propojena se slotem. Například jak "QMenu":http://doc.qt.nokia.com/4.7/qmenu.html tak i "QToolBar":http://doc.qt.nokia.com/4.7/qtoolbar.html mohou vytvářet položky menu a nástrojová tlačítka z identických "QAction":http://doc.qt.nokia.com/4.7/qaction.html objektů. Za moment se podíváme jak to funguje.
 
Stejně jako v předchozí definici, nastavujeme GUI v konstruktoru třídy Notepad
 
<code>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"));
}</code>
 
Naše "QAction":http://doc.qt.nokia.com/4.7/qaction.html objekty jsou vytvořeny s textem který chceme zobrazit na widgetech kterým je předáme (v našem případě se jedná o položky v menu). Pokud bychom je zároveň chtěli přidat do nástrojové lišty, mohli bychom jim nastavit i "ikony":http://doc.qt.nokia.com/4.7/qicon.html.
 
Pokud nyní stiskneme položku v menu, spustí to danou akci a ta vyvolá příslušný slot.
 
h3. Rozšiřující informace
 
|Téma|Odkaz|
|Hlavní okna a jejich třídy|"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 aplikace|"QMdiArea":http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example":http://doc.qt.nokia.com/4.7/mainwindows-mdi.html|
 
h2. Ukládání a načítání
 
V tomto příkladě naimplementujeme funkčnost slotů open() a save(), které jsme přidali v předchozí definici.
 
[[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|Ukládání a načítání]]
 
Začneme se slotem open():
 
<code>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();
}</code>
 
Prvním krokem je dotázání se uživatele na název souboru, který chce otevřít. Qt nabízí "QFileDialog":http://doc.qt.nokia.com/4.7/qfiledialog.html, což je dialog ve kterém uživatel může vybrat soubor. Obrázek výše zobrazuje tento dialog na Linuxové distribuci Kubuntu. Statická funkce "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName> zobrazí modální souborový dialog a neskončí dokud uživatel nevybere soubor. Vrací cestu k vybranému souboru, případně prázdný řetězec pokud uživatel dialog zrušil.
 
Pokud máme cestu k souboru, pokusíme se ho otevřít funkcí "open()":http://doc.qt.nokia.com/4.7/qiodevice.html#open>. Ta vrací true pokud bylo otevření úspěšné. Nebudeme zacházet do detailů co se zpracování chyb týče, ovšem můžete si přečíst články odkázané v sekci "Rozšiřující informace". Pokud soubor nemůže být otevřen, zobrazíme "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html a zobrazíme dialog s chybovým hlášením (pro více informací si přečtěte dokumentaci třídy "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html).
Čtení dat je díky funcki "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll> triviální, ta vrátí veškerá data obsažená v souboru v "QByteArray":http://doc.qt.nokia.com/4.7/qbytearray.html. Funkce "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData> vrací veškerá data jako const char''' jenž "QString":http://doc.qt.nokia.com/4.7/qstring.html přebírá v jednom ze svých konstruktorů. Poté již obsah souboru snadno zobrazíme v oblasti pro úpravu textu. Po načtení soubor uzavřeme za použití "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close>, tím předáme souborový deskriptor zpět operačnímu systému.


Nyní se podívejme na slot save().
Nyní se podívejme na slot save().


<code>QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<code>QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
<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-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}</code>
tr("Text Files ('''.txt);;C++ Files ('''.cpp '''.h)"));
<br />Při ukládání obsahu oblasti pro úpravu textu do textového souboru používáme třídy &quot;QTextStream&amp;quot;:http://doc.qt.nokia.com/4.7/qtextstream.html, která zaobaluje objekt třídy &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html. Tento textový proud je schopen zapisovat &quot;QString&amp;quot;:http://doc.qt.nokia.com/4.7/qstring.html přímo do souboru; &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html přijímá pouze surová data (typu char''') funkcí &quot;write()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#write&amp;gt; třídy &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html
 
if (fileName != "") {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
// error message
} else {
QTextStream stream(&amp;file);
stream << textEdit->toPlainText();
stream.flush();
file.close();
}
}</code>
 
Při ukládání obsahu oblasti pro úpravu textu do textového souboru používáme třídy "QTextStream":http://doc.qt.nokia.com/4.7/qtextstream.html, která zaobaluje objekt třídy "QFile":http://doc.qt.nokia.com/4.7/qfile.html. Tento textový proud je schopen zapisovat "QString":http://doc.qt.nokia.com/4.7/qstring.html přímo do souboru; "QFile":http://doc.qt.nokia.com/4.7/qfile.html přijímá pouze surová data (typu char''') funkcí "write()":http://doc.qt.nokia.com/4.7/qiodevice.html#write> třídy "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html


=== Rozšiřující informace ===
=== Rozšiřující informace ===
Line 156: Line 299:
|-
|-
|Soubory a zařízení vstupu a výstupu
|Soubory a zařízení vstupu a výstupu
|&quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html, &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html
|"QFile":http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html
|}
|}

Revision as of 09:44, 25 February 2015

[toc align_right="yes" depth="3"]

Začínáme programovat s Qt

Vítejte ve světe Qt — ve světe multiplatformního GUI toolkitu. V tomto tutoriálu si krok za krokem ukážeme jak naprogramovat aplikaci jako je Notepad, tímto způsobem vás naučíme základních dovedností. Po přečtení tohoto návodu byste měli být připraveni na čtení našich přehledů a API dokumentace a zároveň být schopni nalézt informace, které můžete uplatnit ve vámi vyvíjených aplikacích.

Ahoj Notepade

V tomto úvodním příkladu vytvoříme a zobrazíme oblast pro úpravu textu. Takto vypadá nejjednodušší možný Qt program.

Ahoj Notepade

A toto je jeho zdrojový kód:

#include <QApplication>
#include <QTextEdit>

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

 QTextEdit textEdit;
 textEdit.show();

 return app.exec();
}

Nyní si tento zdrojový kód řádek po řádku projdeme. V prvních dvou řádcích vkládáme hlavičkové soubory pro "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html a "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html, což jsou přávě ty třídy, které pro tento příklad potřebujeme. Názvy všech Qt hlavičkových souborů se shodují s názvy tříd které jsou v nich deklarovány.

Na řádku 6 vytváříme objekt třídy "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html. Tento objekt spravuje prostředky celé aplikace a je vyžadován pro funkčnost všech Qt programů mající GUI. Jako parametry potřebuje argv a args, potože Qt samo od sebe přijímá několik argumentů příkazové řádky.

Řádek 8 vytváří objekt třídy "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html. Oblast pro úpravu textu je vizuální prvek GUI. V Qt takovéto elementy nazýváme widgety. Příklady dalších widgetů jsou například posuvníky, štítky, přepínače, atp. Widget může být zároveň kontejnerem pro další widgety; příkladem budiž hlavní okno aplikace či dialog.

Řádek 9 zobrazí oblast pro úpravu textu na obrazovce ve vlastním okně. Vzhledem k tomu, že widgety mohou složit i jako kontejnery (například "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, který obsahuje nástrojovou lištu, menu, stavový řádek a několik dalších widgetů), je možné zobrazit widget ve vlastním okně. Widgety jsou implicitně skryty; o zobrazení se stará právě metoda "show()":http://doc.qt.nokia.com/4.7/qwidget.html#show).

Řádek 11 spustí hlavní smyčku eventů aplikace. Dokud aplikace beží, jejím widgetům jsou zasílány eventy. Příkladem eventů jsou stisknutí tlačítek myši a klávesnice. Jakmile napíšete text do dříve zmíněné oblasti pro úpravu textu, ta obdrží eventy informující o stisknutí kláves a reaguje vykreslením příslušného textu.

Pro spuštění aplikace, otevřete příkazovou řádku, přejděte do adresáře kde máte její zdrojový soubor a napište následující příkazy.

qmake -project
qmake
make

Ty vytvoří spustitelný soubor v daném adresáři (na systémech windows bude možná třeba použít nmake namísto make. Také spustitelné soubory se budou nacházet buďto v podadresáři release nebo debug). qmake je Qt nástroj pro sestavování projektů vyžadující konfigurační soubor. Tento konfigurační soubor za nás qmake sám vygeneruje, když ho spustíme s přepínačem -project. Z daného konfiguračního souboru (s příponou .pro) qmake vytvoří makefile, která za vás program sestaví. Na to jak si můžete vytvořit vlastní .pro soubor se podíváme později.

h3. Rozšiřující informace

|Téma|Odkaz| |Widgety a gemoetrie okna|"Window and Dialog Widgets":http://doc.qt.nokia.com/4.7/application-windows.html%7C |Eventy a jejich zpracování|"The Event System":http://doc.qt.nokia.com/4.7/eventsandfilters.html%7C

h2. Přídání tlačítka 'Quit'

V reálné aplikaci budete běžně potřebovat více než jen jeden widget. Nyní přidáme "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html pod oblast pro úpravu textu. Toto tlačítko bude plnit funkci vypínače aplikace (společně se zavřením okna).

Ahoj Notepade

Nyní se podívejme na zdrojový kód

#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();
}

Na řádku 1 vkládáme "QtGui":http://doc.qt.nokia.com/4.7/qtgui.html, které obsahuje všechny Qt GUI třídy.

Řádek 10 používá Qt systém signálů a slotů a zajišťuje, že stisknutí tlačítka 'Quit' ukončí aplikaci. Slot je funkce, která může být vyvolána za běhu použitím jejího jména (jako doslovný řetězec). Signál je funkce, která když zavolána zavolá všechny sloty s ní propojené; tyto procedury nazýváme propojení slotu se signálem (to connect the slot to the signal) a vyslání signálu (to emit the signal).

"quit()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit je slot třídy "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html , který při zavolání ukončí aplikaci. "clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked je signál třídy, který "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html vyšle poté co je stisknut. Statická funkce "QObject::connect()":http://doc.qt.nokia.com/4.7/qobject.html#connect se stará o propojení signálu se slotem. SIGNAL () a SLOT() jsou dvě makra, která přebírají prototyp (type-signature) signálu a slotu k propojení.

Řádek 12 vytváří objekt třídy "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html. Jak již bylo zmíňeno, widgety mohou obsahovat další wigety. Je také možné přímo nastavit meze (umístění a velikost) potomků widgetu (widgetů, které daný widget obsahuje). Layout spravuje meze svých potomků automaticky. Například "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html umístí potomky vertikálně pod sebe.

Řádky 13 a 14 přidávájí do layoutu oblast na úpravu textu a tlačítko. Řádek 17 nastavuje nastaví widgetu hlavní layout.

Rozšiřující informace

Téma Odkaz
Signály a Sloty "Signals & Slots":http://doc.qt.nokia.com/4.7/signalsandslots.html
Layouty "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
Widgety které Qt nabízí "Qt Widget Gallery":http://doc.qt.nokia.com/4.7/gallery.html, "Widget Examples":http://doc.qt.nokia.com/4.7/examples-widgets.html

Odvozování vlastních widgetů od QWidgetu

Možná by bylo hezké dotázat se uživatele před ukončením aplikace, zdali opravdu chce aplikaci opustit. V tomto příkladě vytvoříme podtřídu "QWidgetu":http://doc.qt.nokia.com/4.7/qwidget.html, které přidáme vlastní slot a následně ho napojíme na naše tlačítko 'Quit'.

Odvozujeme od QWidgetu

Podívejme se nyní na zdrojový kód

class Notepad : public QWidget
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void quit();

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

Na začátku definice naší třídy (která přirozeně musí být podtřídou třídy "QObject":http://doc.qt.nokia.com/4.7/qobject.html. "QObject":http://doc.qt.nokia.com/4.7/qobject.html) musí být makro Q_OBJECT, to z ní učiní plnohotnotný QObject. To že je třída QObjectem jí dává specielní vlastnosti. Například se můžeme dotázat na název třídy či slotu za běhu programu. Je také možné zjistit parametry slotu a zavolat ho.

Řádek 13 deklaruje slot quit(). Nyní můžeme quit() propojit se signály s odpovídajícím prototypem (libovolným bezparametrickým signálem).

Namísto nastavování GUI a propojení slotu ve funkci main() provádíme tuto práci v konstruktoru třídy Notepad.

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"));
}

Jak jste mohli vidět v definici třídy, používáme ukazatele na naše "QObjekty":http://doc.qt.nokia.com/4.7/qobject.html (textEdit a quitButton). Zpravidla byste měli "QObjekty":http://doc.qt.nokia.com/4.7/qobject.html vždy alokovat na heapu a nikdy je kopírovat.

Viditelné stringy "obalujeme" do funkce "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr> a to z toho důvodu, kdybychom se v budoucnu rozhodli poskytovat naší aplikaci ve více jazykových mutacích. Nebudeme zacházet do detailů, ovšem pokud vás téma zajímá, můžete se podívat na odkaz Qt Linguist z následující tabulky.

h3. Rozšiřující informace

|Téma|Odkaz| |tr() a internacionalizace|"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%7C |QObjekty a objektový model Qt (Základ pro porozumění Qt)|"Object Model":http://doc.qt.nokia.com/4.7/object.html%7C |qmake a systém překladu Qt|"qmake Manual":http://doc.qt.nokia.com/4.7/qmake-manual.html%7C

h2. Vytváření .pro souboru

Na ukázku si vytvoříme vlastní .pro soubor namísto toho, který za nás vygenerovalo qmake -project.

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

Následující příkazy přeloží náš ukázkový projekt.

qmake
make

h2. Používání třídy QMainWindow

Mnoho aplikací bude mít prospěch z používání "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, které má svůj vlastní layout kam můžete přidat menu, dokovací widgety, nástrojovou lištu a stavovou lištu. "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html má centrální oblast která může obsahovat libovolný widget. V Našem případě tam umístíme naši oblast pro úpravu textu.

Používání třídy QMainWindow

Nyní se podívejme na novou definici třídy Notepad

#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;
};

Přidáváme další dva sloty pro otevření a uložení dokumentu. Budou implementovány v následující sekci.

Často chceme, aby bylo možné vyvolat jediný slot několika widgety. Typický příklad představují položky menu a tlačítka na nástrojové liště. Pro usnadnění Qt nabízízí "QAction":http://doc.qt.nokia.com/4.7/qaction.html, která může být předáná několika widgetům a být propojena se slotem. Například jak "QMenu":http://doc.qt.nokia.com/4.7/qmenu.html tak i "QToolBar":http://doc.qt.nokia.com/4.7/qtoolbar.html mohou vytvářet položky menu a nástrojová tlačítka z identických "QAction":http://doc.qt.nokia.com/4.7/qaction.html objektů. Za moment se podíváme jak to funguje.

Stejně jako v předchozí definici, nastavujeme GUI v konstruktoru třídy Notepad

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"));
}

Naše "QAction":http://doc.qt.nokia.com/4.7/qaction.html objekty jsou vytvořeny s textem který chceme zobrazit na widgetech kterým je předáme (v našem případě se jedná o položky v menu). Pokud bychom je zároveň chtěli přidat do nástrojové lišty, mohli bychom jim nastavit i "ikony":http://doc.qt.nokia.com/4.7/qicon.html.

Pokud nyní stiskneme položku v menu, spustí to danou akci a ta vyvolá příslušný slot.

h3. Rozšiřující informace

|Téma|Odkaz| |Hlavní okna a jejich třídy|"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%7C |MDI aplikace|"QMdiArea":http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example":http://doc.qt.nokia.com/4.7/mainwindows-mdi.html%7C

h2. Ukládání a načítání

V tomto příkladě naimplementujeme funkčnost slotů open() a save(), které jsme přidali v předchozí definici.

Ukládání a načítání

Začneme se slotem open():

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();
}

Prvním krokem je dotázání se uživatele na název souboru, který chce otevřít. Qt nabízí "QFileDialog":http://doc.qt.nokia.com/4.7/qfiledialog.html, což je dialog ve kterém uživatel může vybrat soubor. Obrázek výše zobrazuje tento dialog na Linuxové distribuci Kubuntu. Statická funkce "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName> zobrazí modální souborový dialog a neskončí dokud uživatel nevybere soubor. Vrací cestu k vybranému souboru, případně prázdný řetězec pokud uživatel dialog zrušil.

Pokud máme cestu k souboru, pokusíme se ho otevřít funkcí "open()":http://doc.qt.nokia.com/4.7/qiodevice.html#open>. Ta vrací true pokud bylo otevření úspěšné. Nebudeme zacházet do detailů co se zpracování chyb týče, ovšem můžete si přečíst články odkázané v sekci "Rozšiřující informace". Pokud soubor nemůže být otevřen, zobrazíme "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html a zobrazíme dialog s chybovým hlášením (pro více informací si přečtěte dokumentaci třídy "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html). Čtení dat je díky funcki "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll> triviální, ta vrátí veškerá data obsažená v souboru v "QByteArray":http://doc.qt.nokia.com/4.7/qbytearray.html. Funkce "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData> vrací veškerá data jako const char jenž "QString":http://doc.qt.nokia.com/4.7/qstring.html přebírá v jednom ze svých konstruktorů. Poté již obsah souboru snadno zobrazíme v oblasti pro úpravu textu. Po načtení soubor uzavřeme za použití "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close>, tím předáme souborový deskriptor zpět operačnímu systému.

Nyní se podívejme na slot save().

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();
 }
}

Při ukládání obsahu oblasti pro úpravu textu do textového souboru používáme třídy "QTextStream":http://doc.qt.nokia.com/4.7/qtextstream.html, která zaobaluje objekt třídy "QFile":http://doc.qt.nokia.com/4.7/qfile.html. Tento textový proud je schopen zapisovat "QString":http://doc.qt.nokia.com/4.7/qstring.html přímo do souboru; "QFile":http://doc.qt.nokia.com/4.7/qfile.html přijímá pouze surová data (typu char) funkcí "write()":http://doc.qt.nokia.com/4.7/qiodevice.html#write> třídy "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html

Rozšiřující informace

Téma Odkaz
Soubory a zařízení vstupu a výstupu "QFile":http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html