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:
=Začínáme programovat s Qt=
[toc align_right="yes" depth="3"]


Vítejte ve světe Qt — ve světe multiplatformního <span class="caps">GUI</span> 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 <span class="caps">API</span> dokumentace a zároveň být schopni nalézt informace, které můžete uplatnit ve vámi vyvíjených aplikacích.
= Začínáme programovat s Qt =


==Ahoj Notepade==
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.
V tomto úvodním příkladu vytvoříme a zobrazíme oblast pro úpravu textu. Takto vypadá nejjednodušší možný Qt program.


[[Image:gs1.png|Ahoj Notepade]]
[[Image:http://doc.qt.nokia.com/4.7/images/gs1.png|Ahoj Notepade]]


A toto je jeho zdrojový kód:
A toto je jeho zdrojový kód:


Nyní si tento zdrojový kód řádek po řádku projdeme. V prvních dvou řádcích vkládáme hlavičkové soubory pro [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' a [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit] ''[doc.qt.nokia.com]'', 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.
<code>#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;


Na řádku 6 vytváříme objekt třídy [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]''. Tento objekt spravuje prostředky celé aplikace a je vyžadován pro funkčnost všech Qt programů mající <span class="caps">GUI</span>. Jako parametry potřebuje argv a args, potože Qt samo od sebe přijímá několik argumentů příkazové řádky.
int main(int argv, char *'''args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> textEdit.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}</code>
<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);


Řádek 8 vytváří objekt třídy [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit] ''[doc.qt.nokia.com]''. Oblast pro úpravu textu je vizuální prvek <span class="caps">GUI</span>. 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.
QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Quit&amp;quot;);


Řá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 [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'', 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 [http://doc.qt.nokia.com/4.7/qwidget.html#show show()] ''[doc.qt.nokia.com]'').
QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
 
Řá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.
 
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.
 
===Rozšiřující informace===
 
{| class="infotable line"
| Téma
| Odkaz
|-
| Widgety a gemoetrie okna
|
[http://doc.qt.nokia.com/4.7/application-windows.html Window and Dialog Widgets] ''[doc.qt.nokia.com]''
|-
| Eventy a jejich zpracování
|
[http://doc.qt.nokia.com/4.7/eventsandfilters.html The Event System] ''[doc.qt.nokia.com]''
|}


==Přídání tlačítka ‘Quit’==
QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);


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


[[Image:gs2.png|Ahoj Notepade]]
window.show();


Nyní se podívejme na zdrojový kód
return app.exec&amp;amp;#40;&amp;#41;;<br />}</code>


Na řádku 1 vkládáme [http://doc.qt.nokia.com/4.7/qtgui.html QtGui] ''[doc.qt.nokia.com]'', které obsahuje všechny Qt <span class="caps">GUI</span> třídy.
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.


Řá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).


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


Řádek 12 vytváří objekt třídy [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]''. 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 [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]'' umístí potomky vertikálně pod sebe.
Řá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.


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


===Rozšiřující informace===
=== Rozšiřující informace ===


{| class="infotable line"
{|
| Téma
|Téma
| Odkaz
|Odkaz
|-
|-
| Signály a Sloty
|Signály a Sloty
|
|&quot;Signals &amp; Slots&amp;quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html
[http://doc.qt.nokia.com/4.7/signalsandslots.html Signals &amp; Slots] ''[doc.qt.nokia.com]''
|-
|-
| 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
[http://doc.qt.nokia.com/4.7/layout.html Layout Management] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html Widgets and Layouts] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-layouts.html Layout Examples] ''[doc.qt.nokia.com]''
|-
|-
| 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
[http://doc.qt.nokia.com/4.7/gallery.html Qt Widget Gallery] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-widgets.html Widget Examples] ''[doc.qt.nokia.com]''
|}
|}


==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 [http://doc.qt.nokia.com/4.7/qwidget.html QWidgetu] ''[doc.qt.nokia.com]'', 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 &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'.


[[Image:gs3.png|Odvozujeme od QWidgetu]]
[[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Odvozujeme od QWidgetu]]


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


Na začátku definice naší třídy (která přirozeně musí být podtřídou třídy [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]''. [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'') 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.
<code>class Notepad : public QWidget<br />{<br /> Q_OBJECT


Řá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).
public:<br /> Notepad();


Namísto nastavování <span class="caps">GUI</span> a propojení slotu ve funkci main() provádíme tuto práci v konstruktoru třídy Notepad.
private slots:<br /> void quit();


Jak jste mohli vidět v definici třídy, používáme ukazatele na naše [http://doc.qt.nokia.com/4.7/qobject.html QObjekty] ''[doc.qt.nokia.com]'' (textEdit a quitButton). Zpravidla byste měli [http://doc.qt.nokia.com/4.7/qobject.html QObjekty] ''[doc.qt.nokia.com]'' vždy alokovat na heapu a nikdy je kopírovat.
private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};</code>


Viditelné stringy “obalujeme” do funkce [http://doc.qt.nokia.com/4.7/qobject.html#tr&gt; tr()] ''[doc.qt.nokia.com]'' 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.
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.


===Rozšiřující informace===
Řá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).
 
{| class="infotable line"
| Téma
| Odkaz
|-
| tr() a internacionalizace
|
[http://doc.qt.nokia.com/4.7/linguist-manual.html Qt Linguist Manual] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Writing SOurce Code for Translation] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Hello tr()] ''[doc.qt.nokia.com]'' Example, [http://doc.qt.nokia.com/4.7/internationalization.html Internationalization with Qt] ''[doc.qt.nokia.com]''
|-
| QObjekty a objektový model Qt (Základ pro porozumění Qt)
|
[http://doc.qt.nokia.com/4.7/object.html Object Model] ''[doc.qt.nokia.com]''
|-
| qmake a systém překladu Qt
|
[http://doc.qt.nokia.com/4.7/qmake-manual.html qmake Manual] ''[doc.qt.nokia.com]''
|}
 
==Vytváření .pro souboru==
 
Na ukázku si vytvoříme vlastní .pro soubor namísto toho, který za nás vygenerovalo qmake -project.
 
Následující příkazy přeloží náš ukázkový projekt.
 
==Používání třídy QMainWindow==
 
Mnoho aplikací bude mít prospěch z používání [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'', které má svůj vlastní layout kam můžete přidat menu, dokovací widgety, nástrojovou lištu a stavovou lištu. [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'' 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.
 
[[Image:gs4.png|Používání třídy QMainWindow]]
 
Nyní se podívejme na novou definici třídy Notepad
 
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í [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'', která může být předáná několika widgetům a být propojena se slotem. Například jak [http://doc.qt.nokia.com/4.7/qmenu.html QMenu] ''[doc.qt.nokia.com]'' tak i [http://doc.qt.nokia.com/4.7/qtoolbar.html QToolBar] ''[doc.qt.nokia.com]'' mohou vytvářet položky menu a nástrojová tlačítka z identických [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'' objektů. Za moment se podíváme jak to funguje.
 
Stejně jako v předchozí definici, nastavujeme <span class="caps">GUI</span> v konstruktoru třídy Notepad
 
Naše [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'' 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 [http://doc.qt.nokia.com/4.7/qicon.html ikony] ''[doc.qt.nokia.com]''.
 
Pokud nyní stiskneme položku v menu, spustí to danou akci a ta vyvolá příslušný slot.
 
===Rozšiřující informace===
 
{| class="infotable line"
| Téma
| Odkaz
|-
| Hlavní okna a jejich třídy
|
[http://doc.qt.nokia.com/4.7/mainwindow.html Application Main Window] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Main Window Examples] ''[doc.qt.nokia.com]''
|-
| <span class="caps">MDI</span> aplikace
|
[http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html <span class="caps">MDI</span> Example] ''[doc.qt.nokia.com]''
|}
 
==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:gs5.png|Ukládání a načítání]]
Namísto nastavování GUI a propojení slotu ve funkci main() provádíme tuto práci v konstruktoru třídy Notepad.


Začneme se slotem open():
<code>Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));


Prvním krokem je dotázání se uživatele na název souboru, který chce otevřít. Qt nabízí [http://doc.qt.nokia.com/4.7/qfiledialog.html QFileDialog] ''[doc.qt.nokia.com]'', 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 [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName&gt; getOpenFileName()] ''[doc.qt.nokia.com]'' 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.
connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));


Pokud máme cestu k souboru, pokusíme se ho otevřít funkcí [http://doc.qt.nokia.com/4.7/qiodevice.html#open&gt; open()] ''[doc.qt.nokia.com]''. 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 [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' a zobrazíme dialog s chybovým hlášením (pro více informací si přečtěte dokumentaci třídy [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'').<br /> Čtení dat je díky funcki [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll&gt; readAll()] ''[doc.qt.nokia.com]'' triviální, ta vrátí veškerá data obsažená v souboru v [http://doc.qt.nokia.com/4.7/qbytearray.html QByteArray] ''[doc.qt.nokia.com]''. Funkce [http://doc.qt.nokia.com/4.7/qbytearray.html#constData&gt; constData()] ''[doc.qt.nokia.com]'' vrací veškerá data jako const char* jenž [http://doc.qt.nokia.com/4.7/qstring.html QString] ''[doc.qt.nokia.com]'' 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í [http://doc.qt.nokia.com/4.7/qiodevice.html#close&gt; close()] ''[doc.qt.nokia.com]'', tím předáme souborový deskriptor zpět operačnímu systému.
QVBoxLayout '''layout = new QVBoxLayout;<br /> layout-&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);
<br /> setLayout(layout);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}</code>
<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.
<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|
<br />h2. Vytváření .pro souboru
<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>
<br />Následující příkazy přeloží náš ukázkový projekt.
<br /><code>qmake<br />make</code>
<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.
<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
<br /><code>#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu '''fileMenu;<br />};</code>
<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.
<br />Stejně jako v předchozí definici, nastavujeme GUI v konstruktoru třídy Notepad
<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()));
<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);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}</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.
<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|
<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.
<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():
<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>
<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.


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


Při ukládání obsahu oblasti pro úpravu textu do textového souboru používáme třídy [http://doc.qt.nokia.com/4.7/qtextstream.html QTextStream] ''[doc.qt.nokia.com]'', která zaobaluje objekt třídy [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]''. Tento textový proud je schopen zapisovat [http://doc.qt.nokia.com/4.7/qstring.html QString] ''[doc.qt.nokia.com]'' přímo do souboru; [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'' přijímá pouze surová data (typu char*) funkcí [http://doc.qt.nokia.com/4.7/qiodevice.html#write&gt; write()] ''[doc.qt.nokia.com]'' třídy [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''
<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;));
<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>
<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


===Rozšiřující informace===
=== Rozšiřující informace ===


{| class="infotable line"
{|
| Téma
|Téma
| Odkaz
|Odkaz
|-
|-
| 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
[http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''
|}
|}

Revision as of 09:22, 24 February 2015

[toc align_right="yes&quot; depth="3&quot;]

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

int main(int argv, char *'''args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> textEdit.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}


Nyní si tento zdrojový kód řádek po řádku projdeme. V prvních dvou řádcích vkládáme hlavičkové soubory pro "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html a "QTextEdit&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.
Na řádku 6 vytváříme objekt třídy "QApplication&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.
Řádek 8 vytváří objekt třídy "QTextEdit&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.
Řá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&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 "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<br />qmake<br />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&quot;:http://doc.qt.nokia.com/4.7/application-windows.html%7C
|Eventy a jejich zpracování|"The Event System&quot;: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&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).
Ahoj Notepade
Nyní se podívejme na zdrojový kód


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

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

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

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

window.show();

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

Na řádku 1 vkládáme "QtGui&quot;: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&quot;: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&quot;: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&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 "QVBoxLayout&quot;: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&quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html
Layouty "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
Widgety které Qt nabízí "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

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

Odvozujeme od QWidgetu

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

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

public:<br /> Notepad();

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

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

Na začátku definice naší třídy (která přirozeně musí být podtřídou třídy "QObject&quot;:http://doc.qt.nokia.com/4.7/qobject.html. "QObject&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.

Řá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()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));

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

QVBoxLayout '''layout = new QVBoxLayout;<br /> layout-&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);
<br /> setLayout(layout);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}


Jak jste mohli vidět v definici třídy, používáme ukazatele na naše "QObjekty&quot;:http://doc.qt.nokia.com/4.7/qobject.html (textEdit a quitButton). Zpravidla byste měli "QObjekty&quot;:http://doc.qt.nokia.com/4.7/qobject.html vždy alokovat na heapu a nikdy je kopírovat.
Viditelné stringy "obalujeme&quot; do funkce "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr&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.
h3. Rozšiřující informace
|Téma|Odkaz|
|tr() a internacionalizace|"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%7C
|QObjekty a objektový model Qt (Základ pro porozumění Qt)|"Object Model&quot;:http://doc.qt.nokia.com/4.7/object.html%7C
|qmake a systém překladu Qt|"qmake Manual&quot;: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<br />SOURCES = notepad.cpp  main.cpp


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


qmake<br />make


h2. Používání třídy QMainWindow
Mnoho aplikací bude mít prospěch z používání "QMainWindow&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. "QMainWindow&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.
Používání třídy QMainWindow
Nyní se podívejme na novou definici třídy Notepad


#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu '''fileMenu;<br />};


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&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 "QMenu&quot;:http://doc.qt.nokia.com/4.7/qmenu.html tak i "QToolBar&quot;:http://doc.qt.nokia.com/4.7/qtoolbar.html mohou vytvářet položky menu a nástrojová tlačítka z identických "QAction&quot;: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()<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</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);
<br /> setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}


Naše "QAction&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 "ikony&quot;: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&quot;:http://doc.qt.nokia.com/4.7/mainwindow.html, "Main Window Examples&quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html%7C
|MDI aplikace|"QMdiArea&quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example&quot;: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(&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 />}


Prvním krokem je dotázání se uživatele na název souboru, který chce otevřít. Qt nabízí "QFileDialog&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 "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName&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.
Pokud máme cestu k souboru, pokusíme se ho otevřít funkcí "open()":http://doc.qt.nokia.com/4.7/qiodevice.html#open&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 "Rozšiřující informace&quot;. Pokud soubor nemůže být otevřen, zobrazíme "QMessageBox&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 "QMessageBox&quot;: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&gt; triviální, ta vrátí veškerá data obsažená v souboru v "QByteArray&quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. Funkce "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData&gt; vrací veškerá data jako const char jenž "QString&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í "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close&gt;, 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(&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-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}


Při ukládání obsahu oblasti pro úpravu textu do textového souboru používáme třídy "QTextStream&quot;:http://doc.qt.nokia.com/4.7/qtextstream.html, která zaobaluje objekt třídy "QFile&quot;:http://doc.qt.nokia.com/4.7/qfile.html. Tento textový proud je schopen zapisovat "QString&quot;:http://doc.qt.nokia.com/4.7/qstring.html přímo do souboru; "QFile&quot;: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&gt; třídy "QIODevice&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html